diff --git a/core/chaincode/chaincode_support.go b/core/chaincode/chaincode_support.go index ec9c92e9d5c..834e6dbd0fb 100644 --- a/core/chaincode/chaincode_support.go +++ b/core/chaincode/chaincode_support.go @@ -38,12 +38,7 @@ import ( pb "github.com/hyperledger/fabric/protos/peer" ) -// ChainName is the name of the chain to which this chaincode support belongs to. -type ChainName string - const ( - // DefaultChain is the name of the default chain. - DefaultChain ChainName = "default" // DevModeUserRunsChaincode property allows user to run chaincode in development environment DevModeUserRunsChaincode string = "dev" chaincodeStartupTimeoutDefault int = 5000 @@ -54,13 +49,12 @@ const ( TXSimulatorKey string = "txsimulatorkey" ) -// chains is a map between different blockchains and their ChaincodeSupport. -//this needs to be a first class, top-level object... for now, lets just have a placeholder -var chains map[ChainName]*ChaincodeSupport - -func init() { - chains = make(map[ChainName]*ChaincodeSupport) -} +//this is basically the singleton that supports the +//entire chaincode framework. It does NOT know about +//chains. Chains are per-proposal entities that are +//setup as part of "join" and go through this object +//via calls to Execute and Deploy chaincodes. +var theChaincodeSupport *ChaincodeSupport //use this for ledger access and make sure TXSimulator is being used func getTxSimulator(context context.Context) ledger.TxSimulator { @@ -84,9 +78,8 @@ type runningChaincodes struct { chaincodeMap map[string]*chaincodeRTEnv } -// GetChain returns the chaincode support for a given chain -func GetChain(name ChainName) *ChaincodeSupport { - return chains[name] +func GetChain() *ChaincodeSupport { + return theChaincodeSupport } //call this under lock @@ -106,48 +99,47 @@ func (chaincodeSupport *ChaincodeSupport) chaincodeHasBeenLaunched(chaincode str } // NewChaincodeSupport creates a new ChaincodeSupport instance -func NewChaincodeSupport(chainname ChainName, getPeerEndpoint func() (*pb.PeerEndpoint, error), userrunsCC bool, ccstartuptimeout time.Duration) *ChaincodeSupport { +func NewChaincodeSupport(getPeerEndpoint func() (*pb.PeerEndpoint, error), userrunsCC bool, ccstartuptimeout time.Duration) *ChaincodeSupport { pnid := viper.GetString("peer.networkId") pid := viper.GetString("peer.id") - s := &ChaincodeSupport{name: chainname, runningChaincodes: &runningChaincodes{chaincodeMap: make(map[string]*chaincodeRTEnv)}, peerNetworkID: pnid, peerID: pid} + theChaincodeSupport = &ChaincodeSupport{runningChaincodes: &runningChaincodes{chaincodeMap: make(map[string]*chaincodeRTEnv)}, peerNetworkID: pnid, peerID: pid} //initialize global chain - chains[chainname] = s peerEndpoint, err := getPeerEndpoint() if err != nil { chaincodeLogger.Errorf("Error getting PeerEndpoint, using peer.address: %s", err) - s.peerAddress = viper.GetString("peer.address") + theChaincodeSupport.peerAddress = viper.GetString("peer.address") } else { - s.peerAddress = peerEndpoint.Address + theChaincodeSupport.peerAddress = peerEndpoint.Address } - chaincodeLogger.Infof("Chaincode support using peerAddress: %s\n", s.peerAddress) + chaincodeLogger.Infof("Chaincode support using peerAddress: %s\n", theChaincodeSupport.peerAddress) //peerAddress = viper.GetString("peer.address") - if s.peerAddress == "" { - s.peerAddress = peerAddressDefault + if theChaincodeSupport.peerAddress == "" { + theChaincodeSupport.peerAddress = peerAddressDefault } - s.userRunsCC = userrunsCC + theChaincodeSupport.userRunsCC = userrunsCC - s.ccStartupTimeout = ccstartuptimeout + theChaincodeSupport.ccStartupTimeout = ccstartuptimeout //TODO I'm not sure if this needs to be on a per chain basis... too lowel and just needs to be a global default ? - s.chaincodeInstallPath = viper.GetString("chaincode.installpath") - if s.chaincodeInstallPath == "" { - s.chaincodeInstallPath = chaincodeInstallPathDefault + theChaincodeSupport.chaincodeInstallPath = viper.GetString("chaincode.installpath") + if theChaincodeSupport.chaincodeInstallPath == "" { + theChaincodeSupport.chaincodeInstallPath = chaincodeInstallPathDefault } - s.peerTLS = viper.GetBool("peer.tls.enabled") - if s.peerTLS { - s.peerTLSCertFile = viper.GetString("peer.tls.cert.file") - s.peerTLSKeyFile = viper.GetString("peer.tls.key.file") - s.peerTLSSvrHostOrd = viper.GetString("peer.tls.serverhostoverride") + theChaincodeSupport.peerTLS = viper.GetBool("peer.tls.enabled") + if theChaincodeSupport.peerTLS { + theChaincodeSupport.peerTLSCertFile = viper.GetString("peer.tls.cert.file") + theChaincodeSupport.peerTLSKeyFile = viper.GetString("peer.tls.key.file") + theChaincodeSupport.peerTLSSvrHostOrd = viper.GetString("peer.tls.serverhostoverride") } kadef := 0 if ka := viper.GetString("chaincode.keepalive"); ka == "" { - s.keepalive = time.Duration(kadef) * time.Second + theChaincodeSupport.keepalive = time.Duration(kadef) * time.Second } else { t, terr := strconv.Atoi(ka) if terr != nil { @@ -157,7 +149,7 @@ func NewChaincodeSupport(chainname ChainName, getPeerEndpoint func() (*pb.PeerEn chaincodeLogger.Debugf("Turn off keepalive(value %s)", ka) t = kadef } - s.keepalive = time.Duration(t) * time.Second + theChaincodeSupport.keepalive = time.Duration(t) * time.Second } viper.SetEnvPrefix("CORE") @@ -169,13 +161,13 @@ func NewChaincodeSupport(chainname ChainName, getPeerEndpoint func() (*pb.PeerEn chaincodeLogLevel, err := logging.LogLevel(chaincodeLogLevelString) if err == nil { - s.chaincodeLogLevel = chaincodeLogLevel.String() + theChaincodeSupport.chaincodeLogLevel = chaincodeLogLevel.String() } else { chaincodeLogger.Warningf("Chaincode logging level %s is invalid; defaulting to %s", chaincodeLogLevelString, flogging.DefaultLoggingLevel().String()) - s.chaincodeLogLevel = flogging.DefaultLoggingLevel().String() + theChaincodeSupport.chaincodeLogLevel = flogging.DefaultLoggingLevel().String() } - return s + return theChaincodeSupport } // // ChaincodeStream standard stream for ChaincodeMessage type. @@ -186,7 +178,6 @@ func NewChaincodeSupport(chainname ChainName, getPeerEndpoint func() (*pb.PeerEn // ChaincodeSupport responsible for providing interfacing with chaincodes from the Peer. type ChaincodeSupport struct { - name ChainName runningChaincodes *runningChaincodes peerAddress string ccStartupTimeout time.Duration @@ -270,7 +261,7 @@ func (chaincodeSupport *ChaincodeSupport) deregisterHandler(chaincodehandler *Ha } // Based on state of chaincode send either init or ready to move to ready state -func (chaincodeSupport *ChaincodeSupport) sendInitOrReady(context context.Context, txid string, prop *pb.Proposal, chaincode string, initArgs [][]byte, timeout time.Duration) error { +func (chaincodeSupport *ChaincodeSupport) sendInitOrReady(context context.Context, chainID string, txid string, prop *pb.Proposal, chaincode string, initArgs [][]byte, timeout time.Duration) error { chaincodeSupport.runningChaincodes.Lock() //if its in the map, there must be a connected stream...nothing to do var chrte *chaincodeRTEnv @@ -284,7 +275,7 @@ func (chaincodeSupport *ChaincodeSupport) sendInitOrReady(context context.Contex var notfy chan *pb.ChaincodeMessage var err error - if notfy, err = chrte.handler.initOrReady(context, txid, prop, initArgs); err != nil { + if notfy, err = chrte.handler.initOrReady(context, chainID, txid, prop, initArgs); err != nil { return fmt.Errorf("Error sending %s: %s", pb.ChaincodeMessage_INIT, err) } if notfy != nil { @@ -442,7 +433,7 @@ func (chaincodeSupport *ChaincodeSupport) Stop(context context.Context, cds *pb. } // Launch will launch the chaincode if not running (if running return nil) and will wait for handler of the chaincode to get into FSM ready state. -func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, txid string, prop *pb.Proposal, spec interface{}) (*pb.ChaincodeID, *pb.ChaincodeInput, error) { +func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, chainID string, txid string, prop *pb.Proposal, spec interface{}) (*pb.ChaincodeID, *pb.ChaincodeInput, error) { //build the chaincode var cID *pb.ChaincodeID var cMsg *pb.ChaincodeInput @@ -499,7 +490,7 @@ func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, txid s var depPayload []byte //hopefully we are restarting from existing image and the deployed transaction exists - depPayload, err = GetCDSFromLCCC(context, txid, prop, string(DefaultChain), chaincode) + depPayload, err = GetCDSFromLCCC(context, txid, prop, chainID, chaincode) if err != nil { return cID, cMsg, fmt.Errorf("Could not get deployment transaction from LCCC for %s - %s", chaincode, err) } @@ -530,7 +521,7 @@ func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, txid s if err == nil { //send init (if (args)) and wait for ready state - err = chaincodeSupport.sendInitOrReady(context, txid, prop, chaincode, initargs, chaincodeSupport.ccStartupTimeout) + err = chaincodeSupport.sendInitOrReady(context, chainID, txid, prop, chaincode, initargs, chaincodeSupport.ccStartupTimeout) if err != nil { chaincodeLogger.Errorf("sending init failed(%s)", err) err = fmt.Errorf("Failed to init chaincode(%s)", err) @@ -618,7 +609,7 @@ func createTransactionMessage(txid string, cMsg *pb.ChaincodeInput) (*pb.Chainco } // Execute executes a transaction and waits for it to complete until a timeout value. -func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, chaincode string, msg *pb.ChaincodeMessage, timeout time.Duration, prop *pb.Proposal) (*pb.ChaincodeMessage, error) { +func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, chainID string, chaincode string, msg *pb.ChaincodeMessage, timeout time.Duration, prop *pb.Proposal) (*pb.ChaincodeMessage, error) { chaincodeSupport.runningChaincodes.Lock() //we expect the chaincode to be running... sanity check chrte, ok := chaincodeSupport.chaincodeHasBeenLaunched(chaincode) @@ -631,7 +622,7 @@ func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, chaincod var notfy chan *pb.ChaincodeMessage var err error - if notfy, err = chrte.handler.sendExecuteMessage(ctxt, msg, prop); err != nil { + if notfy, err = chrte.handler.sendExecuteMessage(ctxt, chainID, msg, prop); err != nil { return nil, fmt.Errorf("Error sending %s: %s", msg.Type.String(), err) } var ccresp *pb.ChaincodeMessage diff --git a/core/chaincode/chaincodeexec.go b/core/chaincode/chaincodeexec.go index fa352793a2e..dbc9dd5f521 100644 --- a/core/chaincode/chaincodeexec.go +++ b/core/chaincode/chaincodeexec.go @@ -36,19 +36,19 @@ func createCIS(ccname string, args [][]byte) (*pb.ChaincodeInvocationSpec, error // GetCDSFromLCCC gets chaincode deployment spec from LCCC func GetCDSFromLCCC(ctxt context.Context, txid string, prop *pb.Proposal, chainID string, chaincodeID string) ([]byte, error) { - payload, _, err := ExecuteChaincode(ctxt, txid, prop, string(DefaultChain), "lccc", [][]byte{[]byte("getdepspec"), []byte(chainID), []byte(chaincodeID)}) + payload, _, err := ExecuteChaincode(ctxt, chainID, txid, prop, "lccc", [][]byte{[]byte("getdepspec"), []byte(chainID), []byte(chaincodeID)}) return payload, err } // ExecuteChaincode executes a given chaincode given chaincode name and arguments -func ExecuteChaincode(ctxt context.Context, txid string, prop *pb.Proposal, chainname string, ccname string, args [][]byte) ([]byte, *pb.ChaincodeEvent, error) { +func ExecuteChaincode(ctxt context.Context, chainID string, txid string, prop *pb.Proposal, ccname string, args [][]byte) ([]byte, *pb.ChaincodeEvent, error) { var spec *pb.ChaincodeInvocationSpec var err error var b []byte var ccevent *pb.ChaincodeEvent spec, err = createCIS(ccname, args) - b, ccevent, err = Execute(ctxt, GetChain(ChainName(chainname)), txid, prop, spec) + b, ccevent, err = Execute(ctxt, chainID, txid, prop, spec) if err != nil { return nil, nil, fmt.Errorf("Error deploying chaincode: %s", err) } diff --git a/core/chaincode/exectransaction.go b/core/chaincode/exectransaction.go index ebfb6e6dd47..d88d4c82363 100644 --- a/core/chaincode/exectransaction.go +++ b/core/chaincode/exectransaction.go @@ -28,7 +28,7 @@ import ( ) //Execute - execute proposal -func Execute(ctxt context.Context, chain *ChaincodeSupport, txid string, prop *pb.Proposal, spec interface{}) ([]byte, *pb.ChaincodeEvent, error) { +func Execute(ctxt context.Context, chainID string, txid string, prop *pb.Proposal, spec interface{}) ([]byte, *pb.ChaincodeEvent, error) { var err error var cds *pb.ChaincodeDeploymentSpec var ci *pb.ChaincodeInvocationSpec @@ -39,18 +39,18 @@ func Execute(ctxt context.Context, chain *ChaincodeSupport, txid string, prop *p } if cds != nil { - _, err := chain.Deploy(ctxt, cds) + _, err := theChaincodeSupport.Deploy(ctxt, cds) if err != nil { return nil, nil, fmt.Errorf("Failed to deploy chaincode spec(%s)", err) } - _, _, err = chain.Launch(ctxt, txid, prop, cds) + _, _, err = theChaincodeSupport.Launch(ctxt, chainID, txid, prop, cds) if err != nil { return nil, nil, fmt.Errorf("%s", err) } } else { //will launch if necessary (and wait for ready) - cID, cMsg, err := chain.Launch(ctxt, txid, prop, ci) + cID, cMsg, err := theChaincodeSupport.Launch(ctxt, chainID, txid, prop, ci) if err != nil { return nil, nil, fmt.Errorf("Failed to launch chaincode spec(%s)", err) } @@ -75,7 +75,7 @@ func Execute(ctxt context.Context, chain *ChaincodeSupport, txid string, prop *p return nil, nil, fmt.Errorf("Failed to transaction message(%s)", err) } - resp, err := chain.Execute(ctxt, chaincode, ccMsg, timeout, prop) + resp, err := theChaincodeSupport.Execute(ctxt, chainID, chaincode, ccMsg, timeout, prop) if err != nil { // Rollback transaction return nil, nil, fmt.Errorf("Failed to execute transaction (%s)", err) diff --git a/core/chaincode/exectransaction_test.go b/core/chaincode/exectransaction_test.go index 9b5749d69c8..16f7cbf2f5d 100644 --- a/core/chaincode/exectransaction_test.go +++ b/core/chaincode/exectransaction_test.go @@ -56,9 +56,9 @@ func getNowMillis() int64 { } //initialize peer and start up. If security==enabled, login as vp -func initPeer() (net.Listener, error) { +func initPeer(chainID string) (net.Listener, error) { //start clean - finitPeer(nil) + finitPeer(nil, chainID) var opts []grpc.ServerOption if viper.GetBool("peer.tls.enabled") { creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"), viper.GetString("peer.tls.key.file")) @@ -87,20 +87,19 @@ func initPeer() (net.Listener, error) { } ccStartupTimeout := time.Duration(chaincodeStartupTimeoutDefault) * time.Millisecond - pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(DefaultChain, getPeerEndpoint, false, ccStartupTimeout)) + pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout)) - RegisterSysCCs() + RegisterSysCCs(chainID) go grpcServer.Serve(lis) return lis, nil } -func finitPeer(lis net.Listener) { +func finitPeer(lis net.Listener, chainID string) { if lis != nil { deRegisterSysCCs() - ledgername := string(DefaultChain) - if lgr := kvledger.GetLedger(ledgername); lgr != nil { + if lgr := kvledger.GetLedger(chainID); lgr != nil { lgr.Close() } closeListenerAndSleep(lis) @@ -110,9 +109,8 @@ func finitPeer(lis net.Listener) { os.RemoveAll(filepath.Join(os.TempDir(), "hyperledger")) } -func startTxSimulation(ctxt context.Context) (context.Context, ledger.TxSimulator, error) { - ledgername := string(DefaultChain) - lgr := kvledger.GetLedger(ledgername) +func startTxSimulation(ctxt context.Context, chainID string) (context.Context, ledger.TxSimulator, error) { + lgr := kvledger.GetLedger(chainID) txsim, err := lgr.NewTxSimulator() if err != nil { return nil, nil, err @@ -122,40 +120,39 @@ func startTxSimulation(ctxt context.Context) (context.Context, ledger.TxSimulato return ctxt, txsim, nil } -func endTxSimulationCDS(txid string, txsim ledger.TxSimulator, payload []byte, commit bool, cds *pb.ChaincodeDeploymentSpec) error { +func endTxSimulationCDS(chainID string, txid string, txsim ledger.TxSimulator, payload []byte, commit bool, cds *pb.ChaincodeDeploymentSpec) error { // get serialized version of the signer ss, err := signer.Serialize() if err != nil { return err } // get a proposal - we need it to get a transaction - prop, err := putils.CreateProposalFromCDS(txid, util.GetTestChainID(), cds, ss) + prop, err := putils.CreateProposalFromCDS(txid, chainID, cds, ss) if err != nil { return err } - return endTxSimulation(txsim, payload, commit, prop) + return endTxSimulation(chainID, txsim, payload, commit, prop) } -func endTxSimulationCIS(txid string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec) error { +func endTxSimulationCIS(chainID string, txid string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec) error { // get serialized version of the signer ss, err := signer.Serialize() if err != nil { return err } // get a proposal - we need it to get a transaction - prop, err := putils.CreateProposalFromCIS(txid, util.GetTestChainID(), cis, ss) + prop, err := putils.CreateProposalFromCIS(txid, chainID, cis, ss) if err != nil { return err } - return endTxSimulation(txsim, payload, commit, prop) + return endTxSimulation(chainID, txsim, payload, commit, prop) } -func endTxSimulation(txsim ledger.TxSimulator, payload []byte, commit bool, prop *pb.Proposal) error { +func endTxSimulation(chainID string, txsim ledger.TxSimulator, payload []byte, commit bool, prop *pb.Proposal) error { txsim.Done() - ledgername := string(DefaultChain) - if lgr := kvledger.GetLedger(ledgername); lgr != nil { + if lgr := kvledger.GetLedger(chainID); lgr != nil { if commit { var txSimulationResults []byte var err error @@ -210,38 +207,38 @@ func getDeploymentSpec(context context.Context, spec *pb.ChaincodeSpec) (*pb.Cha } //getDeployLCCCSpec gets the spec for the chaincode deployment to be sent to LCCC -func getDeployLCCCSpec(cds *pb.ChaincodeDeploymentSpec) (*pb.ChaincodeInvocationSpec, error) { +func getDeployLCCCSpec(chainID string, cds *pb.ChaincodeDeploymentSpec) (*pb.ChaincodeInvocationSpec, error) { b, err := proto.Marshal(cds) if err != nil { return nil, err } //wrap the deployment in an invocation spec to lccc... - lcccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeID: &pb.ChaincodeID{Name: "lccc"}, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte("default"), b}}}} + lcccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeID: &pb.ChaincodeID{Name: "lccc"}, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte(chainID), b}}}} return lcccSpec, nil } // Deploy a chaincode - i.e., build and initialize. -func deploy(ctx context.Context, spec *pb.ChaincodeSpec) (b []byte, err error) { +func deploy(ctx context.Context, chainID string, spec *pb.ChaincodeSpec) (b []byte, err error) { // First build and get the deployment spec chaincodeDeploymentSpec, err := getDeploymentSpec(ctx, spec) if err != nil { return nil, err } - return deploy2(ctx, chaincodeDeploymentSpec) + return deploy2(ctx, chainID, chaincodeDeploymentSpec) } -func deploy2(ctx context.Context, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec) (b []byte, err error) { - cis, err := getDeployLCCCSpec(chaincodeDeploymentSpec) +func deploy2(ctx context.Context, chainID string, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec) (b []byte, err error) { + cis, err := getDeployLCCCSpec(chainID, chaincodeDeploymentSpec) if err != nil { return nil, fmt.Errorf("Error creating lccc spec : %s\n", err) } tid := chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name - ctx, txsim, err := startTxSimulation(ctx) + ctx, txsim, err := startTxSimulation(ctx, chainID) if err != nil { return nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) } @@ -252,19 +249,19 @@ func deploy2(ctx context.Context, chaincodeDeploymentSpec *pb.ChaincodeDeploymen //no error, lets try commit if err == nil { //capture returned error from commit - err = endTxSimulationCDS(uuid, txsim, []byte("deployed"), true, chaincodeDeploymentSpec) + err = endTxSimulationCDS(chainID, uuid, txsim, []byte("deployed"), true, chaincodeDeploymentSpec) } else { //there was an error, just close simulation and return that - endTxSimulationCDS(uuid, txsim, []byte("deployed"), false, chaincodeDeploymentSpec) + endTxSimulationCDS(chainID, uuid, txsim, []byte("deployed"), false, chaincodeDeploymentSpec) } }() //write to lccc - if _, _, err = Execute(ctx, GetChain(DefaultChain), uuid, nil, cis); err != nil { + if _, _, err = Execute(ctx, chainID, uuid, nil, cis); err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s", err) } - if b, _, err = Execute(ctx, GetChain(DefaultChain), tid, nil, chaincodeDeploymentSpec); err != nil { + if b, _, err = Execute(ctx, chainID, tid, nil, chaincodeDeploymentSpec); err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s", err) } @@ -272,14 +269,14 @@ func deploy2(ctx context.Context, chaincodeDeploymentSpec *pb.ChaincodeDeploymen } // Invoke a chaincode. -func invoke(ctx context.Context, spec *pb.ChaincodeSpec) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) { +func invoke(ctx context.Context, chainID string, spec *pb.ChaincodeSpec) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) { chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} // Now create the Transactions message and send to Peer. uuid = util.GenerateUUID() var txsim ledger.TxSimulator - ctx, txsim, err = startTxSimulation(ctx) + ctx, txsim, err = startTxSimulation(ctx, chainID) if err != nil { return nil, uuid, nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) } @@ -288,14 +285,14 @@ func invoke(ctx context.Context, spec *pb.ChaincodeSpec) (ccevt *pb.ChaincodeEve //no error, lets try commit if err == nil { //capture returned error from commit - err = endTxSimulationCIS(uuid, txsim, []byte("invoke"), true, chaincodeInvocationSpec) + err = endTxSimulationCIS(chainID, uuid, txsim, []byte("invoke"), true, chaincodeInvocationSpec) } else { //there was an error, just close simulation and return that - endTxSimulationCIS(uuid, txsim, []byte("invoke"), false, chaincodeInvocationSpec) + endTxSimulationCIS(chainID, uuid, txsim, []byte("invoke"), false, chaincodeInvocationSpec) } }() - retval, ccevt, err = Execute(ctx, GetChain(DefaultChain), uuid, nil, chaincodeInvocationSpec) + retval, ccevt, err = Execute(ctx, chainID, uuid, nil, chaincodeInvocationSpec) if err != nil { return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s ", err) } @@ -310,33 +307,33 @@ func closeListenerAndSleep(l net.Listener) { } } -func executeDeployTransaction(t *testing.T, name string, url string) { - lis, err := initPeer() +func executeDeployTransaction(t *testing.T, chainID string, name string, url string) { + lis, err := initPeer(chainID) if err != nil { t.Fail() t.Logf("Error creating peer: %s", err) } - defer finitPeer(lis) + defer finitPeer(lis, chainID) var ctxt = context.Background() f := "init" args := util.ToChaincodeArgs(f, "a", "100", "b", "200") spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: name, Path: url}, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, err = deploy(ctxt, spec) + _, err = deploy(ctxt, chainID, spec) chaincodeID := spec.ChaincodeID.Name if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) t.Fail() t.Logf("Error deploying <%s>: %s", chaincodeID, err) return } - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) } -func chaincodeQueryChaincode(user string) error { +func chaincodeQueryChaincode(chainID string, user string) error { var ctxt = context.Background() // Deploy first chaincode @@ -348,10 +345,10 @@ func chaincodeQueryChaincode(user string) error { spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID1, CtorMsg: &pb.ChaincodeInput{Args: args}, SecureContext: user} - _, err := deploy(ctxt, spec1) + _, err := deploy(ctxt, chainID, spec1) chaincodeID1 := spec1.ChaincodeID.Name if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) return fmt.Errorf("Error initializing chaincode %s(%s)", chaincodeID1, err) } @@ -366,11 +363,11 @@ func chaincodeQueryChaincode(user string) error { spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}, SecureContext: user} - _, err = deploy(ctxt, spec2) + _, err = deploy(ctxt, chainID, spec2) chaincodeID2 := spec2.ChaincodeID.Name if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return fmt.Errorf("Error initializing chaincode %s(%s)", chaincodeID2, err) } @@ -383,19 +380,19 @@ func chaincodeQueryChaincode(user string) error { spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}, SecureContext: user} // Invoke chaincode var retVal []byte - _, _, retVal, err = invoke(ctxt, spec2) + _, _, retVal, err = invoke(ctxt, chainID, spec2) if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return fmt.Errorf("Error invoking <%s>: %s", chaincodeID2, err) } // Check the return value result, err := strconv.Atoi(string(retVal)) if err != nil || result != 300 { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", chaincodeID1, err) } @@ -405,52 +402,58 @@ func chaincodeQueryChaincode(user string) error { spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}, SecureContext: user} // Invoke chaincode - _, _, retVal, err = invoke(ctxt, spec2) + _, _, retVal, err = invoke(ctxt, chainID, spec2) if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return fmt.Errorf("Error querying <%s>: %s", chaincodeID2, err) } // Check the return value result, err = strconv.Atoi(string(retVal)) if err != nil || result != 300 { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return fmt.Errorf("Incorrect final value after query for <%s>: %s", chaincodeID1, err) } - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return nil } // Test deploy of a transaction func TestExecuteDeployTransaction(t *testing.T) { - executeDeployTransaction(t, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") + chainID := util.GetTestChainID() + + executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") } // Test deploy of a transaction with a GOPATH with multiple elements func TestGopathExecuteDeployTransaction(t *testing.T) { + chainID := util.GetTestChainID() + // add a trailing slash to GOPATH // and a couple of elements - it doesn't matter what they are os.Setenv("GOPATH", os.Getenv("GOPATH")+string(os.PathSeparator)+string(os.PathListSeparator)+"/tmp/foo"+string(os.PathListSeparator)+"/tmp/bar") - executeDeployTransaction(t, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") + executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") } // Test deploy of a transaction with a chaincode over HTTP. func TestHTTPExecuteDeployTransaction(t *testing.T) { + chainID := util.GetTestChainID() + // The chaincode used here cannot be from the fabric repo // itself or it won't be downloaded because it will be found // in GOPATH, which would defeat the test - executeDeployTransaction(t, "example01", "http://gopkg.in/mastersingh24/fabric-test-resources.v1") + executeDeployTransaction(t, chainID, "example01", "http://gopkg.in/mastersingh24/fabric-test-resources.v1") } // Check the correctness of the final state after transaction execution. -func checkFinalState(uuid string, chaincodeID string) error { - _, txsim, err := startTxSimulation(context.Background()) +func checkFinalState(uuid string, chainID string, chaincodeID string) error { + _, txsim, err := startTxSimulation(context.Background(), chainID) if err != nil { return fmt.Errorf("Failed to get handle to simulator: %s ", err) } @@ -490,12 +493,12 @@ func checkFinalState(uuid string, chaincodeID string) error { } // Invoke chaincode_example02 -func invokeExample02Transaction(ctxt context.Context, cID *pb.ChaincodeID, args []string, destroyImage bool) error { +func invokeExample02Transaction(ctxt context.Context, chainID string, cID *pb.ChaincodeID, args []string, destroyImage bool) error { f := "init" argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: argsDeploy}} - _, err := deploy(ctxt, spec) + _, err := deploy(ctxt, chainID, spec) chaincodeID := spec.ChaincodeID.Name if err != nil { return fmt.Errorf("Error deploying <%s>: %s", chaincodeID, err) @@ -504,8 +507,8 @@ func invokeExample02Transaction(ctxt context.Context, cID *pb.ChaincodeID, args time.Sleep(time.Second) if destroyImage { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) - dir := container.DestroyImageReq{CCID: ccintf.CCID{ChaincodeSpec: spec, NetworkID: GetChain(DefaultChain).peerNetworkID, PeerID: GetChain(DefaultChain).peerID}, Force: true, NoPrune: true} + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + dir := container.DestroyImageReq{CCID: ccintf.CCID{ChaincodeSpec: spec, NetworkID: theChaincodeSupport.peerNetworkID, PeerID: theChaincodeSupport.peerID}, Force: true, NoPrune: true} _, err = container.VMCProcess(ctxt, container.DOCKER, dir) if err != nil { @@ -517,12 +520,12 @@ func invokeExample02Transaction(ctxt context.Context, cID *pb.ChaincodeID, args f = "invoke" invokeArgs := append([]string{f}, args...) spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} - _, uuid, _, err := invoke(ctxt, spec) + _, uuid, _, err := invoke(ctxt, chainID, spec) if err != nil { return fmt.Errorf("Error invoking <%s>: %s", chaincodeID, err) } - err = checkFinalState(uuid, chaincodeID) + err = checkFinalState(uuid, chainID, chaincodeID) if err != nil { return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", chaincodeID, err) } @@ -531,7 +534,7 @@ func invokeExample02Transaction(ctxt context.Context, cID *pb.ChaincodeID, args f = "delete" delArgs := util.ToChaincodeArgs(f, "a") spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: delArgs}} - _, uuid, _, err = invoke(ctxt, spec) + _, uuid, _, err = invoke(ctxt, chainID, spec) if err != nil { return fmt.Errorf("Error deleting state in <%s>: %s", chaincodeID, err) } @@ -540,13 +543,15 @@ func invokeExample02Transaction(ctxt context.Context, cID *pb.ChaincodeID, args } func TestExecuteInvokeTransaction(t *testing.T) { - lis, err := initPeer() + chainID := util.GetTestChainID() + + lis, err := initPeer(chainID) if err != nil { t.Fail() t.Logf("Error creating peer: %s", err) } - defer finitPeer(lis) + defer finitPeer(lis, chainID) var ctxt = context.Background() @@ -554,7 +559,7 @@ func TestExecuteInvokeTransaction(t *testing.T) { chaincodeID := &pb.ChaincodeID{Name: "example02", Path: url} args := []string{"a", "b", "10"} - err = invokeExample02Transaction(ctxt, chaincodeID, args, true) + err = invokeExample02Transaction(ctxt, chainID, chaincodeID, args, true) if err != nil { t.Fail() t.Logf("Error invoking transaction: %s", err) @@ -563,11 +568,11 @@ func TestExecuteInvokeTransaction(t *testing.T) { t.Logf("Invoke test passed") } - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}}) } // Execute multiple transactions and queries. -func exec(ctxt context.Context, chaincodeID string, numTrans int, numQueries int) []error { +func exec(ctxt context.Context, chainID string, chaincodeID string, numTrans int, numQueries int) []error { var wg sync.WaitGroup errs := make([]error, numTrans+numQueries) @@ -578,7 +583,7 @@ func exec(ctxt context.Context, chaincodeID string, numTrans int, numQueries int spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: chaincodeID}, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, _, _, err := invoke(ctxt, spec) + _, _, _, err := invoke(ctxt, chainID, spec) if err != nil { errs[qnum] = fmt.Errorf("Error executing <%s>: %s", chaincodeID, err) @@ -600,13 +605,15 @@ func exec(ctxt context.Context, chaincodeID string, numTrans int, numQueries int // Test the execution of an invalid transaction. func TestExecuteInvokeInvalidTransaction(t *testing.T) { - lis, err := initPeer() + chainID := util.GetTestChainID() + + lis, err := initPeer(chainID) if err != nil { t.Fail() t.Logf("Error creating peer: %s", err) } - defer finitPeer(lis) + defer finitPeer(lis, chainID) var ctxt = context.Background() @@ -615,14 +622,14 @@ func TestExecuteInvokeInvalidTransaction(t *testing.T) { //FAIL, FAIL! args := []string{"x", "-1"} - err = invokeExample02Transaction(ctxt, chaincodeID, args, false) + err = invokeExample02Transaction(ctxt, chainID, chaincodeID, args, false) //this HAS to fail with expectedDeltaStringPrefix if err != nil { errStr := err.Error() t.Logf("Got error %s\n", errStr) t.Logf("InvalidInvoke test passed") - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}}) return } @@ -630,20 +637,22 @@ func TestExecuteInvokeInvalidTransaction(t *testing.T) { t.Fail() t.Logf("Error invoking transaction %s", err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}}) } // Test the execution of a chaincode that invokes another chaincode. func TestChaincodeInvokeChaincode(t *testing.T) { - lis, err := initPeer() + chainID := util.GetTestChainID() + + lis, err := initPeer(chainID) if err != nil { t.Fail() t.Logf("Error creating peer: %s", err) } - defer finitPeer(lis) + defer finitPeer(lis, chainID) - err = chaincodeInvokeChaincode(t, "") + err = chaincodeInvokeChaincode(t, chainID, "") if err != nil { t.Fail() t.Logf("Failed chaincode invoke chaincode : %s", err) @@ -654,7 +663,7 @@ func TestChaincodeInvokeChaincode(t *testing.T) { closeListenerAndSleep(lis) } -func chaincodeInvokeChaincode(t *testing.T, user string) (err error) { +func chaincodeInvokeChaincode(t *testing.T, chainID string, user string) (err error) { var ctxt = context.Background() // Deploy first chaincode @@ -666,12 +675,12 @@ func chaincodeInvokeChaincode(t *testing.T, user string) (err error) { spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID1, CtorMsg: &pb.ChaincodeInput{Args: args}, SecureContext: user} - _, err = deploy(ctxt, spec1) + _, err = deploy(ctxt, chainID, spec1) chaincodeID1 := spec1.ChaincodeID.Name if err != nil { t.Fail() t.Logf("Error initializing chaincode %s(%s)", chaincodeID1, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) return } @@ -688,13 +697,13 @@ func chaincodeInvokeChaincode(t *testing.T, user string) (err error) { spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}, SecureContext: user} - _, err = deploy(ctxt, spec2) + _, err = deploy(ctxt, chainID, spec2) chaincodeID2 := spec2.ChaincodeID.Name if err != nil { t.Fail() t.Logf("Error initializing chaincode %s(%s)", chaincodeID2, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return } @@ -709,28 +718,28 @@ func chaincodeInvokeChaincode(t *testing.T, user string) (err error) { spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}, SecureContext: user} // Invoke chaincode var uuid string - _, uuid, _, err = invoke(ctxt, spec2) + _, uuid, _, err = invoke(ctxt, chainID, spec2) if err != nil { t.Fail() t.Logf("Error invoking <%s>: %s", chaincodeID2, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return } // Check the state in the ledger - err = checkFinalState(uuid, chaincodeID1) + err = checkFinalState(uuid, chainID, chaincodeID1) if err != nil { t.Fail() t.Logf("Incorrect final state after transaction for <%s>: %s", chaincodeID1, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return } - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return } @@ -738,13 +747,15 @@ func chaincodeInvokeChaincode(t *testing.T, user string) (err error) { // Test the execution of a chaincode that invokes another chaincode with wrong parameters. Should receive error from // from the called chaincode func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) { - lis, err := initPeer() + chainID := util.GetTestChainID() + + lis, err := initPeer(chainID) if err != nil { t.Fail() t.Logf("Error creating peer: %s", err) } - defer finitPeer(lis) + defer finitPeer(lis, chainID) var ctxt = context.Background() @@ -757,12 +768,12 @@ func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) { spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID1, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, err = deploy(ctxt, spec1) + _, err = deploy(ctxt, chainID, spec1) chaincodeID1 := spec1.ChaincodeID.Name if err != nil { t.Fail() t.Logf("Error initializing chaincode %s(%s)", chaincodeID1, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) return } @@ -777,13 +788,13 @@ func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) { spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, err = deploy(ctxt, spec2) + _, err = deploy(ctxt, chainID, spec2) chaincodeID2 := spec2.ChaincodeID.Name if err != nil { t.Fail() t.Logf("Error initializing chaincode %s(%s)", chaincodeID2, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return } @@ -795,26 +806,26 @@ func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) { spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}} // Invoke chaincode - _, _, _, err = invoke(ctxt, spec2) + _, _, _, err = invoke(ctxt, chainID, spec2) if err == nil { t.Fail() t.Logf("Error invoking <%s>: %s", chaincodeID2, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return } if strings.Index(err.Error(), "Incorrect number of arguments. Expecting 3") < 0 { t.Fail() t.Logf("Unexpected error %s", err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) return } - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) } // Test the invocation of a transaction. @@ -822,13 +833,15 @@ func TestRangeQuery(t *testing.T) { //TODO enable after ledger enables RangeQuery t.Skip() - lis, err := initPeer() + chainID := util.GetTestChainID() + + lis, err := initPeer(chainID) if err != nil { t.Fail() t.Logf("Error creating peer: %s", err) } - defer finitPeer(lis) + defer finitPeer(lis, chainID) var ctxt = context.Background() @@ -840,12 +853,12 @@ func TestRangeQuery(t *testing.T) { spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, err = deploy(ctxt, spec) + _, err = deploy(ctxt, chainID, spec) chaincodeID := spec.ChaincodeID.Name if err != nil { t.Fail() t.Logf("Error initializing chaincode %s(%s)", chaincodeID, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) return } @@ -854,25 +867,27 @@ func TestRangeQuery(t *testing.T) { args = util.ToChaincodeArgs(f) spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, _, _, err = invoke(ctxt, spec) + _, _, _, err = invoke(ctxt, chainID, spec) if err != nil { t.Fail() t.Logf("Error invoking <%s>: %s", chaincodeID, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) return } - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) } func TestGetEvent(t *testing.T) { - lis, err := initPeer() + chainID := util.GetTestChainID() + + lis, err := initPeer(chainID) if err != nil { t.Fail() t.Logf("Error creating peer: %s", err) } - defer finitPeer(lis) + defer finitPeer(lis, chainID) var ctxt = context.Background() @@ -882,12 +897,12 @@ func TestGetEvent(t *testing.T) { f := "init" spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(f)}} - _, err = deploy(ctxt, spec) + _, err = deploy(ctxt, chainID, spec) chaincodeID := spec.ChaincodeID.Name if err != nil { t.Fail() t.Logf("Error initializing chaincode %s(%s)", chaincodeID, err) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) return } @@ -898,7 +913,7 @@ func TestGetEvent(t *testing.T) { spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: args}} var ccevt *pb.ChaincodeEvent - ccevt, _, _, err = invoke(ctxt, spec) + ccevt, _, _, err = invoke(ctxt, chainID, spec) if err != nil { t.Logf("Error invoking chaincode %s(%s)", chaincodeID, err) @@ -920,21 +935,23 @@ func TestGetEvent(t *testing.T) { t.Fail() } - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) } // Test the execution of a chaincode that queries another chaincode // example02 implements "query" as a function in Invoke. example05 calls example02 func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { + chainID := util.GetTestChainID() + var peerLis net.Listener var err error - if peerLis, err = initPeer(); err != nil { + if peerLis, err = initPeer(chainID); err != nil { t.Fail() t.Logf("Error registering user %s", err) return } - defer finitPeer(peerLis) + defer finitPeer(peerLis, chainID) var ctxt = context.Background() @@ -947,10 +964,10 @@ func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID1, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, err = deploy(ctxt, spec1) + _, err = deploy(ctxt, chainID, spec1) chaincodeID1 := spec1.ChaincodeID.Name if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) t.Fail() t.Logf("Error initializing chaincode %s(%s)", chaincodeID1, err) return @@ -967,11 +984,11 @@ func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, err = deploy(ctxt, spec2) + _, err = deploy(ctxt, chainID, spec2) chaincodeID2 := spec2.ChaincodeID.Name if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) t.Fail() t.Logf("Error initializing chaincode %s(%s)", chaincodeID2, err) return @@ -986,11 +1003,11 @@ func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}} // Invoke chaincode var retVal []byte - _, _, retVal, err = invoke(ctxt, spec2) + _, _, retVal, err = invoke(ctxt, chainID, spec2) if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) t.Fail() t.Logf("Error invoking <%s>: %s", chaincodeID2, err) return @@ -999,8 +1016,8 @@ func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { // Check the return value result, err := strconv.Atoi(string(retVal)) if err != nil || result != 300 { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) t.Fail() t.Logf("Incorrect final state after transaction for <%s>: %s", chaincodeID1, err) return @@ -1012,11 +1029,11 @@ func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID2, CtorMsg: &pb.ChaincodeInput{Args: args}} // Invoke chaincode - _, _, retVal, err = invoke(ctxt, spec2) + _, _, retVal, err = invoke(ctxt, chainID, spec2) if err != nil { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) t.Fail() t.Logf("Error querying <%s>: %s", chaincodeID2, err) return @@ -1025,15 +1042,15 @@ func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { // Check the return value result, err = strconv.Atoi(string(retVal)) if err != nil || result != 300 { - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) t.Fail() t.Logf("Incorrect final value after query for <%s>: %s", chaincodeID1, err) return } - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) - GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) + theChaincodeSupport.Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) } var signer msp.SigningIdentity diff --git a/core/chaincode/handler.go b/core/chaincode/handler.go index 6e4000a0b91..16584b18a0c 100644 --- a/core/chaincode/handler.go +++ b/core/chaincode/handler.go @@ -53,6 +53,7 @@ type MessageHandler interface { } type transactionContext struct { + chainID string proposal *pb.Proposal responseNotifier chan *pb.ChaincodeMessage @@ -106,7 +107,7 @@ func (handler *Handler) serialSend(msg *pb.ChaincodeMessage) error { return nil } -func (handler *Handler) createTxContext(ctxt context.Context, txid string, prop *pb.Proposal) (*transactionContext, error) { +func (handler *Handler) createTxContext(ctxt context.Context, chainID string, txid string, prop *pb.Proposal) (*transactionContext, error) { if handler.txCtxs == nil { return nil, fmt.Errorf("cannot create notifier for txid:%s", txid) } @@ -115,7 +116,7 @@ func (handler *Handler) createTxContext(ctxt context.Context, txid string, prop if handler.txCtxs[txid] != nil { return nil, fmt.Errorf("txid:%s exists", txid) } - txctx := &transactionContext{proposal: prop, responseNotifier: make(chan *pb.ChaincodeMessage, 1), + txctx := &transactionContext{chainID: chainID, proposal: prop, responseNotifier: make(chan *pb.ChaincodeMessage, 1), rangeQueryIteratorMap: make(map[string]ledger.ResultsIterator)} handler.txCtxs[txid] = txctx txctx.txsimulator = getTxSimulator(ctxt) @@ -909,7 +910,7 @@ func (handler *Handler) enterBusyState(e *fsm.Event, state string) { chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: chaincodeSpec} // Launch the new chaincode if not already running - _, chaincodeInput, launchErr := handler.chaincodeSupport.Launch(ctxt, msg.Txid, txContext.proposal, chaincodeInvocationSpec) + _, chaincodeInput, launchErr := handler.chaincodeSupport.Launch(ctxt, txContext.chainID, msg.Txid, txContext.proposal, chaincodeInvocationSpec) if launchErr != nil { payload := []byte(launchErr.Error()) chaincodeLogger.Debugf("[%s]Failed to launch invoked chaincode. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) @@ -923,7 +924,7 @@ func (handler *Handler) enterBusyState(e *fsm.Event, state string) { ccMsg, _ := createTransactionMessage(msg.Txid, chaincodeInput) // Execute the chaincode - response, execErr := handler.chaincodeSupport.Execute(ctxt, newChaincodeID, ccMsg, timeout, txContext.proposal) + response, execErr := handler.chaincodeSupport.Execute(ctxt, txContext.chainID, newChaincodeID, ccMsg, timeout, txContext.proposal) //payload is marshalled and send to the calling chaincode's shim which unmarshals and //sends it to chaincode @@ -1003,11 +1004,11 @@ func (handler *Handler) setChaincodeProposal(prop *pb.Proposal, msg *pb.Chaincod //if initArgs is set (should be for "deploy" only) move to Init //else move to ready -func (handler *Handler) initOrReady(ctxt context.Context, txid string, prop *pb.Proposal, initArgs [][]byte) (chan *pb.ChaincodeMessage, error) { +func (handler *Handler) initOrReady(ctxt context.Context, chainID string, txid string, prop *pb.Proposal, initArgs [][]byte) (chan *pb.ChaincodeMessage, error) { var ccMsg *pb.ChaincodeMessage var send bool - txctx, funcErr := handler.createTxContext(ctxt, txid, prop) + txctx, funcErr := handler.createTxContext(ctxt, chainID, txid, prop) if funcErr != nil { return nil, funcErr } @@ -1078,8 +1079,8 @@ func filterError(errFromFSMEvent error) error { return nil } -func (handler *Handler) sendExecuteMessage(ctxt context.Context, msg *pb.ChaincodeMessage, prop *pb.Proposal) (chan *pb.ChaincodeMessage, error) { - txctx, err := handler.createTxContext(ctxt, msg.Txid, prop) +func (handler *Handler) sendExecuteMessage(ctxt context.Context, chainID string, msg *pb.ChaincodeMessage, prop *pb.Proposal) (chan *pb.ChaincodeMessage, error) { + txctx, err := handler.createTxContext(ctxt, chainID, msg.Txid, prop) if err != nil { return nil, err } diff --git a/core/chaincode/importsysccs.go b/core/chaincode/importsysccs.go index 3a33b9e4264..2041e69a2ab 100644 --- a/core/chaincode/importsysccs.go +++ b/core/chaincode/importsysccs.go @@ -48,9 +48,9 @@ var systemChaincodes = []*SystemChaincode{ //RegisterSysCCs is the hook for system chaincodes where system chaincodes are registered with the fabric //note the chaincode must still be deployed and launched like a user chaincode will be -func RegisterSysCCs() { +func RegisterSysCCs(chainID string) { for _, sysCC := range systemChaincodes { - RegisterSysCC(sysCC) + RegisterSysCC(chainID, sysCC) } } diff --git a/core/chaincode/lccc.go b/core/chaincode/lccc.go index fa370b0c5d4..12681cc055c 100644 --- a/core/chaincode/lccc.go +++ b/core/chaincode/lccc.go @@ -224,7 +224,7 @@ func (lccc *LifeCycleSysCC) getChaincodeDeploymentSpec(code []byte) (*pb.Chainco } //do access control -func (lccc *LifeCycleSysCC) acl(stub shim.ChaincodeStubInterface, chainname ChainName, cds *pb.ChaincodeDeploymentSpec) error { +func (lccc *LifeCycleSysCC) acl(stub shim.ChaincodeStubInterface, chainname string, cds *pb.ChaincodeDeploymentSpec) error { return nil } @@ -280,10 +280,7 @@ func (lccc *LifeCycleSysCC) deploy(stub shim.ChaincodeStubInterface, chainname s ctxt = context.WithValue(ctxt, TXSimulatorKey, dummytxsim) - //TODO - create chaincode support for chainname, for now use DefaultChain - chaincodeSupport := GetChain(ChainName(chainname)) - - _, err = chaincodeSupport.Deploy(ctxt, cds) + _, err = theChaincodeSupport.Deploy(ctxt, cds) if err != nil { return fmt.Errorf("Failed to deploy chaincode spec(%s)", err) } @@ -292,13 +289,13 @@ func (lccc *LifeCycleSysCC) deploy(stub shim.ChaincodeStubInterface, chainname s txid := util.GenerateUUID() //launch and wait for ready - _, _, err = chaincodeSupport.Launch(ctxt, txid, nil, cds) + _, _, err = theChaincodeSupport.Launch(ctxt, chainname, txid, nil, cds) if err != nil { return fmt.Errorf("%s", err) } //stop now that we are done - chaincodeSupport.Stop(ctxt, cds) + theChaincodeSupport.Stop(ctxt, cds) return nil } @@ -324,7 +321,7 @@ func (lccc *LifeCycleSysCC) executeDeploy(stub shim.ChaincodeStubInterface, chai return InvalidChaincodeNameErr(cds.ChaincodeSpec.ChaincodeID.Name) } - if err = lccc.acl(stub, DefaultChain, cds); err != nil { + if err = lccc.acl(stub, chainname, cds); err != nil { return err } diff --git a/core/chaincode/lccc_test.go b/core/chaincode/lccc_test.go index c80c2f3cc1c..3d62fbc5708 100644 --- a/core/chaincode/lccc_test.go +++ b/core/chaincode/lccc_test.go @@ -58,7 +58,7 @@ func initialize() { } ccStartupTimeout := time.Duration(30000) * time.Millisecond - pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(DefaultChain, getPeerEndpoint, false, ccStartupTimeout)) + pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout)) } //TestDeploy tests the deploy function (stops short of actually running the chaincode) diff --git a/core/chaincode/sysccapi.go b/core/chaincode/sysccapi.go index 27e41f151d7..da2c969c45f 100644 --- a/core/chaincode/sysccapi.go +++ b/core/chaincode/sysccapi.go @@ -55,7 +55,7 @@ type SystemChaincode struct { } // RegisterSysCC registers the given system chaincode with the peer -func RegisterSysCC(syscc *SystemChaincode) error { +func RegisterSysCC(chainID string, syscc *SystemChaincode) error { if !syscc.Enabled || !isWhitelisted(syscc) { sysccLogger.Info(fmt.Sprintf("system chaincode (%s,%s) disabled", syscc.Name, syscc.Path)) return nil @@ -74,13 +74,7 @@ func RegisterSysCC(syscc *SystemChaincode) error { chaincodeID := &pb.ChaincodeID{Path: syscc.Path, Name: syscc.Name} spec := pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeID: chaincodeID, CtorMsg: &pb.ChaincodeInput{Args: syscc.InitArgs}} - //PDMP - use default chain to get the simulator - //Note that we are just colleting simulation though - //we will not submit transactions. We *COULD* commit - //transactions ourselves - chainName := string(DefaultChain) - - lgr := kvledger.GetLedger(chainName) + lgr := kvledger.GetLedger(chainID) var txsim ledger.TxSimulator if txsim, err = lgr.NewTxSimulator(); err != nil { return err @@ -89,7 +83,7 @@ func RegisterSysCC(syscc *SystemChaincode) error { defer txsim.Done() ctxt := context.WithValue(context.Background(), TXSimulatorKey, txsim) - if deployErr := DeploySysCC(ctxt, &spec); deployErr != nil { + if deployErr := DeploySysCC(ctxt, chainID, &spec); deployErr != nil { errStr := fmt.Sprintf("deploy chaincode failed: %s", deployErr) sysccLogger.Error(errStr) return fmt.Errorf(errStr) @@ -113,7 +107,7 @@ func deregisterSysCC(syscc *SystemChaincode) error { return err } - chaincodeSupport := GetChain(DefaultChain) + chaincodeSupport := GetChain() if chaincodeSupport != nil { err = chaincodeSupport.Stop(ctx, chaincodeDeploymentSpec) } @@ -129,7 +123,7 @@ func buildSysCC(context context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeD } // DeploySysCC deploys the supplied system chaincode to the local peer -func DeploySysCC(ctx context.Context, spec *pb.ChaincodeSpec) error { +func DeploySysCC(ctx context.Context, chainID string, spec *pb.ChaincodeSpec) error { // First build and get the deployment spec chaincodeDeploymentSpec, err := buildSysCC(ctx, spec) @@ -139,7 +133,7 @@ func DeploySysCC(ctx context.Context, spec *pb.ChaincodeSpec) error { } txid := chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name - _, _, err = Execute(ctx, GetChain(DefaultChain), txid, nil, chaincodeDeploymentSpec) + _, _, err = Execute(ctx, chainID, txid, nil, chaincodeDeploymentSpec) return err } diff --git a/core/chaincode/systemchaincode_test.go b/core/chaincode/systemchaincode_test.go index 168f911b277..7209d4f6023 100644 --- a/core/chaincode/systemchaincode_test.go +++ b/core/chaincode/systemchaincode_test.go @@ -53,7 +53,7 @@ func TestExecuteDeploySysChaincode(t *testing.T) { } ccStartupTimeout := time.Duration(5000) * time.Millisecond - pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(DefaultChain, getPeerEndpoint, false, ccStartupTimeout)) + pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout)) go grpcServer.Serve(lis) @@ -72,14 +72,17 @@ func TestExecuteDeploySysChaincode(t *testing.T) { // System chaincode has to be enabled viper.Set("chaincode.system", map[string]string{"sample_syscc": "true"}) - RegisterSysCCs() + + chainID := util.GetTestChainID() + + RegisterSysCCs(chainID) url := "github.com/hyperledger/fabric/core/system_chaincode/sample_syscc" f := "putval" args := util.ToChaincodeArgs(f, "greeting", "hey there") spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "sample_syscc", Path: url}, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, _, _, err = invoke(ctxt, spec) + _, _, _, err = invoke(ctxt, chainID, spec) if err != nil { closeListenerAndSleep(lis) t.Fail() @@ -90,7 +93,7 @@ func TestExecuteDeploySysChaincode(t *testing.T) { f = "getval" args = util.ToChaincodeArgs(f, "greeting") spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "sample_syscc", Path: url}, CtorMsg: &pb.ChaincodeInput{Args: args}} - _, _, _, err = invoke(ctxt, spec) + _, _, _, err = invoke(ctxt, chainID, spec) if err != nil { closeListenerAndSleep(lis) t.Fail() @@ -100,7 +103,7 @@ func TestExecuteDeploySysChaincode(t *testing.T) { cds := &pb.ChaincodeDeploymentSpec{ExecEnv: 1, ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "sample_syscc", Path: url}, CtorMsg: &pb.ChaincodeInput{Args: args}}} - GetChain(DefaultChain).Stop(ctxt, cds) + theChaincodeSupport.Stop(ctxt, cds) closeListenerAndSleep(lis) } diff --git a/core/committer/noopssinglechain/client.go b/core/committer/noopssinglechain/client.go index bbc5a89af63..7d650352233 100644 --- a/core/committer/noopssinglechain/client.go +++ b/core/committer/noopssinglechain/client.go @@ -76,13 +76,13 @@ func StopDeliveryService(service *DeliverService) { // NewDeliverService construction function to create and initilize // delivery service instance -func NewDeliverService(address string, grpcServer *grpc.Server) *DeliverService { +func NewDeliverService(chainID string, address string, grpcServer *grpc.Server) *DeliverService { if viper.GetBool("peer.committer.enabled") { logger.Infof("Creating committer for single noops endorser") deliverService := &DeliverService{ // Instance of RawLedger - committer: committer.NewLedgerCommitter(kvledger.GetLedger(string(chaincode.DefaultChain))), + committer: committer.NewLedgerCommitter(kvledger.GetLedger(chainID)), windowSize: 10, stopChan: make(chan bool), } @@ -226,12 +226,16 @@ func (d *DeliverService) isDone() bool { return atomic.LoadInt32(&d.stopFlag) == 1 } -func isTxValidForVscc(envBytes []byte) error { +func isTxValidForVscc(payload *common.Payload, envBytes []byte) error { // TODO: Extract the VSCC/policy from LCCC as soon as this is ready vscc := "vscc" - // TODO - get chainname from the envelope - chainName := string(chaincode.DefaultChain) + chainName := payload.Header.ChainHeader.ChainID + if chainName == "" { + err := fmt.Errorf("transaction header does not contain an chain ID") + logger.Errorf("%s", err) + return err + } txid := "N/A" // FIXME: is that appropriate? @@ -242,7 +246,7 @@ func isTxValidForVscc(envBytes []byte) error { // create VSCC invocation proposal vsccCis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeID: &pb.ChaincodeID{Name: vscc}, CtorMsg: &pb.ChaincodeInput{Args: args}}} - prop, err := putils.CreateProposalFromCIS(txid, util.GetTestChainID(), vsccCis, []byte("")) + prop, err := putils.CreateProposalFromCIS(txid, chainName, vsccCis, []byte("")) if err != nil { logger.Errorf("Cannot create a proposal to invoke VSCC, err %s\n", err) return err @@ -260,7 +264,7 @@ func isTxValidForVscc(envBytes []byte) error { ctxt := context.WithValue(context.Background(), chaincode.TXSimulatorKey, txsim) // invoke VSCC - _, _, err = chaincode.ExecuteChaincode(ctxt, txid, prop, chainName, vscc, args) + _, _, err = chaincode.ExecuteChaincode(ctxt, chainName, txid, prop, vscc, args) if err != nil { logger.Errorf("VSCC check failed for transaction, error %s", err) return err @@ -302,14 +306,15 @@ func (d *DeliverService) readUntilClose() { // chain binding proposal to endorsements to tx holds. We do // NOT check the validity of endorsements, though. That's a // job for VSCC below - _, err := peer.ValidateTransaction(env) + payload, _, err := peer.ValidateTransaction(env) if err != nil { // TODO: this code needs to receive a bit more attention and discussion: // it's not clear what it means if a transaction which causes a failure // in validation is just dropped on the floor logger.Errorf("Invalid transaction, error %s", err) } else { - err = isTxValidForVscc(d) + //the payload is used to get headers + err = isTxValidForVscc(payload, d) if err != nil { // TODO: this code needs to receive a bit more attention and discussion: // it's not clear what it means if a transaction which causes a failure diff --git a/core/endorser/endorser.go b/core/endorser/endorser.go index 0b631993503..71f884a177f 100644 --- a/core/endorser/endorser.go +++ b/core/endorser/endorser.go @@ -65,8 +65,7 @@ func (*Endorser) getTxSimulator(ledgername string) (ledger.TxSimulator, error) { //deploy the chaincode after call to the system chaincode is successful func (e *Endorser) deploy(ctxt context.Context, txid string, proposal *pb.Proposal, chainname string, cds *pb.ChaincodeDeploymentSpec, cid *pb.ChaincodeID) error { - //TODO - create chaincode support for chainname, for now use DefaultChain - chaincodeSupport := chaincode.GetChain(chaincode.ChainName(chainname)) + chaincodeSupport := chaincode.GetChain() _, err := chaincodeSupport.Deploy(ctxt, cds) if err != nil { @@ -74,7 +73,7 @@ func (e *Endorser) deploy(ctxt context.Context, txid string, proposal *pb.Propos } //launch and wait for ready - _, _, err = chaincodeSupport.Launch(ctxt, txid, proposal, cds) + _, _, err = chaincodeSupport.Launch(ctxt, chainname, txid, proposal, cds) if err != nil { return fmt.Errorf("%s", err) } @@ -86,16 +85,13 @@ func (e *Endorser) deploy(ctxt context.Context, txid string, proposal *pb.Propos } //call specified chaincode (system or user) -func (e *Endorser) callChaincode(ctxt context.Context, txid string, prop *pb.Proposal, cis *pb.ChaincodeInvocationSpec, cid *pb.ChaincodeID, txsim ledger.TxSimulator) ([]byte, *pb.ChaincodeEvent, error) { +func (e *Endorser) callChaincode(ctxt context.Context, chainID string, txid string, prop *pb.Proposal, cis *pb.ChaincodeInvocationSpec, cid *pb.ChaincodeID, txsim ledger.TxSimulator) ([]byte, *pb.ChaincodeEvent, error) { var err error var b []byte var ccevent *pb.ChaincodeEvent - //TODO - get chainname from cis when defined - chainName := string(chaincode.DefaultChain) - ctxt = context.WithValue(ctxt, chaincode.TXSimulatorKey, txsim) - b, ccevent, err = chaincode.ExecuteChaincode(ctxt, txid, prop, chainName, cid.Name, cis.ChaincodeSpec.CtorMsg.Args) + b, ccevent, err = chaincode.ExecuteChaincode(ctxt, chainID, txid, prop, cid.Name, cis.ChaincodeSpec.CtorMsg.Args) if err != nil { return nil, nil, err @@ -115,7 +111,7 @@ func (e *Endorser) callChaincode(ctxt context.Context, txid string, prop *pb.Pro if err != nil { return nil, nil, err } - err = e.deploy(ctxt, txid, prop, chainName, cds, cid) + err = e.deploy(ctxt, txid, prop, chainID, cds, cid) if err != nil { return nil, nil, err } @@ -126,7 +122,7 @@ func (e *Endorser) callChaincode(ctxt context.Context, txid string, prop *pb.Pro } //simulate the proposal by calling the chaincode -func (e *Endorser) simulateProposal(ctx context.Context, txid string, prop *pb.Proposal, cid *pb.ChaincodeID, txsim ledger.TxSimulator) ([]byte, []byte, *pb.ChaincodeEvent, error) { +func (e *Endorser) simulateProposal(ctx context.Context, chainID string, txid string, prop *pb.Proposal, cid *pb.ChaincodeID, txsim ledger.TxSimulator) ([]byte, []byte, *pb.ChaincodeEvent, error) { //we do expect the payload to be a ChaincodeInvocationSpec //if we are supporting other payloads in future, this be glaringly point //as something that should change @@ -148,7 +144,7 @@ func (e *Endorser) simulateProposal(ctx context.Context, txid string, prop *pb.P var simResult []byte var resp []byte var ccevent *pb.ChaincodeEvent - resp, ccevent, err = e.callChaincode(ctx, txid, prop, cis, cid, txsim) + resp, ccevent, err = e.callChaincode(ctx, chainID, txid, prop, cis, cid, txsim) if err != nil { return nil, nil, nil, err } @@ -160,19 +156,19 @@ func (e *Endorser) simulateProposal(ctx context.Context, txid string, prop *pb.P return resp, simResult, ccevent, nil } -func (e *Endorser) getCDSFromLCCC(ctx context.Context, txid string, prop *pb.Proposal, chaincodeID string, txsim ledger.TxSimulator) ([]byte, error) { +func (e *Endorser) getCDSFromLCCC(ctx context.Context, chainID string, txid string, prop *pb.Proposal, chaincodeID string, txsim ledger.TxSimulator) ([]byte, error) { ctxt := context.WithValue(ctx, chaincode.TXSimulatorKey, txsim) - return chaincode.GetCDSFromLCCC(ctxt, txid, prop, string(chaincode.DefaultChain), chaincodeID) + return chaincode.GetCDSFromLCCC(ctxt, txid, prop, chainID, chaincodeID) } //endorse the proposal by calling the ESCC -func (e *Endorser) endorseProposal(ctx context.Context, txid string, proposal *pb.Proposal, simRes []byte, event *pb.ChaincodeEvent, visibility []byte, ccid *pb.ChaincodeID, txsim ledger.TxSimulator) ([]byte, error) { - endorserLogger.Infof("endorseProposal starts for proposal %p, simRes %p event %p, visibility %p, ccid %s", proposal, simRes, event, visibility, ccid) +func (e *Endorser) endorseProposal(ctx context.Context, chainID string, txid string, proposal *pb.Proposal, simRes []byte, event *pb.ChaincodeEvent, visibility []byte, ccid *pb.ChaincodeID, txsim ledger.TxSimulator) ([]byte, error) { + endorserLogger.Infof("endorseProposal starts for proposal %p, chainID %s, simRes %p event %p, visibility %p, ccid %s", chainID, proposal, simRes, event, visibility, ccid) // 1) extract the chaincodeDeploymentSpec for the chaincode we are invoking; we need it to get the escc var escc string if ccid.Name != "lccc" { - depPayload, err := e.getCDSFromLCCC(ctx, txid, proposal, ccid.Name, txsim) + depPayload, err := e.getCDSFromLCCC(ctx, chainID, txid, proposal, ccid.Name, txsim) if err != nil { return nil, fmt.Errorf("failed to obtain cds for %s - %s", ccid, err) } @@ -211,7 +207,7 @@ func (e *Endorser) endorseProposal(ctx context.Context, txid string, proposal *p // args[5] - payloadVisibility args := [][]byte{[]byte(""), proposal.Header, proposal.Payload, simRes, eventBytes, visibility} ecccis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeID: &pb.ChaincodeID{Name: escc}, CtorMsg: &pb.ChaincodeInput{Args: args}}} - prBytes, _, err := e.callChaincode(ctx, txid, proposal, ecccis, &pb.ChaincodeID{Name: escc}, txsim) + prBytes, _, err := e.callChaincode(ctx, chainID, txid, proposal, ecccis, &pb.ChaincodeID{Name: escc}, txsim) if err != nil { return nil, err } @@ -241,6 +237,17 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err } + chainID := hdr.ChainHeader.ChainID + if chainID == "" { + err = fmt.Errorf("chainID not provided") + return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err + } + + //TODO check join call checks go here + + //OK... this is not a join proposal, just a regular one...the chain is there and the peer has joined + //lets proceed with the proposal processing + //TODO check for uniqueness of prop.TxID with ledger txid := hdr.ChainHeader.TxID @@ -252,7 +259,7 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro // obtaining once the tx simulator for this proposal var txsim ledger.TxSimulator //TODO - get chainname from the proposal when defined - chainName := string(chaincode.DefaultChain) + chainName := hdr.ChainHeader.ChainID if txsim, err = e.getTxSimulator(chainName); err != nil { return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err } @@ -266,14 +273,14 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro //1 -- simulate //TODO what do we do with response ? We need it for Invoke responses for sure //Which field in PayloadResponse will carry return value ? - result, simulationResult, ccevent, err := e.simulateProposal(ctx, txid, prop, hdrExt.ChaincodeID, txsim) + result, simulationResult, ccevent, err := e.simulateProposal(ctx, chainID, txid, prop, hdrExt.ChaincodeID, txsim) if err != nil { return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err } //2 -- endorse and get a marshalled ProposalResponse message //TODO what do we do with response ? We need it for Invoke responses for sure - prBytes, err := e.endorseProposal(ctx, txid, prop, simulationResult, ccevent, hdrExt.PayloadVisibility, hdrExt.ChaincodeID, txsim) + prBytes, err := e.endorseProposal(ctx, chainID, txid, prop, simulationResult, ccevent, hdrExt.PayloadVisibility, hdrExt.ChaincodeID, txsim) if err != nil { return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, err } @@ -295,14 +302,13 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro // Only exposed for testing purposes - commit the tx simulation so that // a deploy transaction is persisted and that chaincode can be invoked. // This makes the endorser test self-sufficient -func (e *Endorser) commitTxSimulation(proposal *pb.Proposal, signer msp.SigningIdentity, pResp *pb.ProposalResponse) error { +func (e *Endorser) commitTxSimulation(proposal *pb.Proposal, chainID string, signer msp.SigningIdentity, pResp *pb.ProposalResponse) error { tx, err := putils.CreateSignedTx(proposal, signer, pResp) if err != nil { return err } - ledgername := string(chaincode.DefaultChain) - lgr := kvledger.GetLedger(ledgername) + lgr := kvledger.GetLedger(chainID) if lgr == nil { return fmt.Errorf("failure while looking up the ledger") } diff --git a/core/endorser/endorser_test.go b/core/endorser/endorser_test.go index 8e5b1b2a83c..c60f0b59d66 100644 --- a/core/endorser/endorser_test.go +++ b/core/endorser/endorser_test.go @@ -46,7 +46,7 @@ var mspInstance msp.PeerMSP var signer msp.SigningIdentity //initialize peer and start up. If security==enabled, login as vp -func initPeer() (net.Listener, error) { +func initPeer(chainID string) (net.Listener, error) { //start clean finitPeer(nil) var opts []grpc.ServerOption @@ -91,14 +91,14 @@ func initPeer() (net.Listener, error) { } ccStartupTimeout := time.Duration(30000) * time.Millisecond - pb.RegisterChaincodeSupportServer(grpcServer, chaincode.NewChaincodeSupport(chaincode.DefaultChain, getPeerEndpoint, false, ccStartupTimeout)) + pb.RegisterChaincodeSupportServer(grpcServer, chaincode.NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout)) - chaincode.RegisterSysCCs() + chaincode.RegisterSysCCs(chainID) chaincodeID := &pb.ChaincodeID{Path: "github.com/hyperledger/fabric/core/chaincode/lccc", Name: "lccc"} spec := pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeID: chaincodeID, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}} - chaincode.DeploySysCC(context.Background(), &spec) + chaincode.DeploySysCC(context.Background(), chainID, &spec) go grpcServer.Serve(lis) @@ -119,24 +119,24 @@ func closeListenerAndSleep(l net.Listener) { //getProposal gets the proposal for the chaincode invocation //Currently supported only for Invokes (Queries still go through devops client) -func getProposal(cis *pb.ChaincodeInvocationSpec, creator []byte) (*pb.Proposal, error) { +func getProposal(cis *pb.ChaincodeInvocationSpec, chainID string, creator []byte) (*pb.Proposal, error) { uuid := util.GenerateUUID() - return pbutils.CreateChaincodeProposal(uuid, util.GetTestChainID(), cis, creator) + return pbutils.CreateChaincodeProposal(uuid, chainID, cis, creator) } //getDeployProposal gets the proposal for the chaincode deployment //the payload is a ChaincodeDeploymentSpec -func getDeployProposal(cds *pb.ChaincodeDeploymentSpec, creator []byte) (*pb.Proposal, error) { +func getDeployProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) { b, err := proto.Marshal(cds) if err != nil { return nil, err } //wrap the deployment in an invocation spec to lccc... - lcccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeID: &pb.ChaincodeID{Name: "lccc"}, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte("default"), b}}}} + lcccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeID: &pb.ChaincodeID{Name: "lccc"}, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte(chainID), b}}}} //...and get the proposal for it - return getProposal(lcccSpec, creator) + return getProposal(lcccSpec, chainID, creator) } func getSignedProposal(prop *pb.Proposal, signer msp.SigningIdentity) (*pb.SignedProposal, error) { @@ -162,7 +162,7 @@ func getDeploymentSpec(context context.Context, spec *pb.ChaincodeSpec) (*pb.Cha return chaincodeDeploymentSpec, nil } -func deploy(endorserServer pb.EndorserServer, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) { +func deploy(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) { var err error var depSpec *pb.ChaincodeDeploymentSpec @@ -182,7 +182,7 @@ func deploy(endorserServer pb.EndorserServer, spec *pb.ChaincodeSpec, f func(*pb } var prop *pb.Proposal - prop, err = getDeployProposal(depSpec, creator) + prop, err = getDeployProposal(depSpec, chainID, creator) if err != nil { return nil, nil, err } @@ -199,7 +199,7 @@ func deploy(endorserServer pb.EndorserServer, spec *pb.ChaincodeSpec, f func(*pb return resp, prop, err } -func invoke(spec *pb.ChaincodeSpec) (*pb.ProposalResponse, error) { +func invoke(chainID string, spec *pb.ChaincodeSpec) (*pb.ProposalResponse, error) { invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} creator, err := signer.Serialize() @@ -208,7 +208,7 @@ func invoke(spec *pb.ChaincodeSpec) (*pb.ProposalResponse, error) { } var prop *pb.Proposal - prop, err = getProposal(invocation, creator) + prop, err = getProposal(invocation, chainID, creator) if err != nil { return nil, fmt.Errorf("Error creating proposal %s: %s\n", spec.ChaincodeID, err) } @@ -234,78 +234,83 @@ func invoke(spec *pb.ChaincodeSpec) (*pb.ProposalResponse, error) { //TestDeploy deploy chaincode example01 func TestDeploy(t *testing.T) { + chainID := util.GetTestChainID() spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "ex01", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"}, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} - _, _, err := deploy(endorserServer, spec, nil) + _, _, err := deploy(endorserServer, chainID, spec, nil) if err != nil { t.Fail() t.Logf("Deploy-error in deploy %s", err) - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) return } - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) } //TestDeployBadArgs sets bad args on deploy. It should fail, and example02 should not be deployed func TestDeployBadArgs(t *testing.T) { + chainID := util.GetTestChainID() //invalid arguments spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "ex02", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"}, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b")}}} - _, _, err := deploy(endorserServer, spec, nil) + _, _, err := deploy(endorserServer, chainID, spec, nil) if err == nil { t.Fail() t.Log("DeployBadArgs-expected error in deploy but succeeded") - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) return } - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) } //TestDeployBadPayload set payload to nil and do a deploy. It should fail and example02 should not be deployed func TestDeployBadPayload(t *testing.T) { + chainID := util.GetTestChainID() //invalid arguments spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "ex02", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"}, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} f := func(cds *pb.ChaincodeDeploymentSpec) { cds.CodePackage = nil } - _, _, err := deploy(endorserServer, spec, f) + _, _, err := deploy(endorserServer, chainID, spec, f) if err == nil { t.Fail() t.Log("DeployBadPayload-expected error in deploy but succeeded") - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) return } - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) } //TestRedeploy - deploy two times, second time should fail but example02 should remain deployed func TestRedeploy(t *testing.T) { + chainID := util.GetTestChainID() //invalid arguments spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "ex02", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"}, CtorMsg: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} - _, _, err := deploy(endorserServer, spec, nil) + _, _, err := deploy(endorserServer, chainID, spec, nil) if err != nil { t.Fail() t.Logf("error in endorserServer.ProcessProposal %s", err) - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) return } //second time should not fail as we are just simulating - _, _, err = deploy(endorserServer, spec, nil) + _, _, err = deploy(endorserServer, chainID, spec, nil) if err != nil { t.Fail() t.Logf("error in endorserServer.ProcessProposal %s", err) - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) return } - chaincode.GetChain(chaincode.DefaultChain).Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) + chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) } // TestDeployAndInvoke deploys and invokes chaincode_example01 func TestDeployAndInvoke(t *testing.T) { + chainID := util.GetTestChainID() var ctxt = context.Background() url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" @@ -316,7 +321,7 @@ func TestDeployAndInvoke(t *testing.T) { f := "init" argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: chaincodeID, CtorMsg: &pb.ChaincodeInput{Args: argsDeploy}} - resp, prop, err := deploy(endorserServer, spec, nil) + resp, prop, err := deploy(endorserServer, chainID, spec, nil) chaincodeID1 := spec.ChaincodeID.Name if err != nil { t.Fail() @@ -324,7 +329,7 @@ func TestDeployAndInvoke(t *testing.T) { return } - err = endorserServer.(*Endorser).commitTxSimulation(prop, signer, resp) + err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp) if err != nil { t.Fail() t.Logf("Error committing <%s>: %s", chaincodeID1, err) @@ -334,7 +339,7 @@ func TestDeployAndInvoke(t *testing.T) { f = "invoke" invokeArgs := append([]string{f}, args...) spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: chaincodeID, CtorMsg: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} - resp, err = invoke(spec) + resp, err = invoke(chainID, spec) if err != nil { t.Fail() t.Logf("Error invoking transaction: %s", err) @@ -344,13 +349,15 @@ func TestDeployAndInvoke(t *testing.T) { fmt.Printf("Invoke test passed\n") t.Logf("Invoke test passed") - chaincode.GetChain(chaincode.DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}}) + chaincode.GetChain().Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}}) } func TestMain(m *testing.M) { SetupTestConfig() viper.Set("peer.fileSystemPath", filepath.Join(os.TempDir(), "hyperledger", "production")) - lis, err := initPeer() + + chainID := util.GetTestChainID() + lis, err := initPeer(chainID) if err != nil { os.Exit(-1) fmt.Printf("Could not initialize tests") diff --git a/core/ledger/kvledger/kv_ledgers.go b/core/ledger/kvledger/kv_ledgers.go index 52e43e6bcbc..679aba06fc1 100644 --- a/core/ledger/kvledger/kv_ledgers.go +++ b/core/ledger/kvledger/kv_ledgers.go @@ -110,6 +110,11 @@ func (lMgr *ledgerManager) create(name string) (*KVLedger, error) { //GetLedger returns a kvledger, creating one if necessary //the call will panic if it cannot create a ledger func GetLedger(name string) *KVLedger { + //We should never have an empty ledgername when we do multichannel + if name == "" { + panic("empty naame") + } + lgr, err := lManager.create(name) if lgr == nil { diff --git a/core/peer/fullflow_test.go b/core/peer/fullflow_test.go index b09a557b195..ae3e13281da 100644 --- a/core/peer/fullflow_test.go +++ b/core/peer/fullflow_test.go @@ -81,7 +81,7 @@ func TestGoodPath(t *testing.T) { } // validate the transaction - act, err := ValidateTransaction(tx) + _, act, err := ValidateTransaction(tx) if err != nil { t.Fatalf("ValidateTransaction failed, err %s", err) return @@ -209,7 +209,7 @@ func TestBadTx(t *testing.T) { corrupt(tx.Payload) // validate the transaction it should fail - _, err = ValidateTransaction(tx) + _, _, err = ValidateTransaction(tx) if err == nil { t.Fatalf("ValidateTransaction should have failed") return @@ -226,7 +226,7 @@ func TestBadTx(t *testing.T) { corrupt(tx.Signature) // validate the transaction it should fail - _, err = ValidateTransaction(tx) + _, _, err = ValidateTransaction(tx) if err == nil { t.Fatalf("ValidateTransaction should have failed") return @@ -267,7 +267,7 @@ func Test2EndorsersAgree(t *testing.T) { } // validate the transaction - _, err = ValidateTransaction(tx) + _, _, err = ValidateTransaction(tx) if err != nil { t.Fatalf("ValidateTransaction failed, err %s", err) return diff --git a/core/peer/msgvalidation.go b/core/peer/msgvalidation.go index c2a20e4a878..06c9f078ac7 100644 --- a/core/peer/msgvalidation.go +++ b/core/peer/msgvalidation.go @@ -298,18 +298,18 @@ func validateEndorserTransaction(data []byte, hdr *common.Header) ([]*pb.Transac } // ValidateTransaction checks that the transaction envelope is properly formed -func ValidateTransaction(e *common.Envelope) ([]*pb.TransactionAction, error) { +func ValidateTransaction(e *common.Envelope) (*common.Payload, []*pb.TransactionAction, error) { putilsLogger.Infof("ValidateTransactionEnvelope starts for envelope %p", e) // check for nil argument if e == nil { - return nil, fmt.Errorf("Nil Envelope") + return nil, nil, fmt.Errorf("Nil Envelope") } // get the payload from the envelope payload, err := utils.GetPayload(e) if err != nil { - return nil, fmt.Errorf("Could not extract payload from envelope, err %s", err) + return nil, nil, fmt.Errorf("Could not extract payload from envelope, err %s", err) } putilsLogger.Infof("Header is %s", payload.Header) @@ -317,13 +317,13 @@ func ValidateTransaction(e *common.Envelope) ([]*pb.TransactionAction, error) { // validate the header err = validateCommonHeader(payload.Header) if err != nil { - return nil, err + return nil, nil, err } // validate the signature in the envelope err = checkSignatureFromCreator(payload.Header.SignatureHeader.Creator, e.Signature, e.Payload) if err != nil { - return nil, err + return nil, nil, err } // TODO: ensure that creator can transact with us (some ACLs?) which set of APIs is supposed to give us this info? @@ -335,8 +335,8 @@ func ValidateTransaction(e *common.Envelope) ([]*pb.TransactionAction, error) { case common.HeaderType_ENDORSER_TRANSACTION: rv, err := validateEndorserTransaction(payload.Data, payload.Header) putilsLogger.Infof("ValidateTransactionEnvelope returns %p, err %s", rv, err) - return rv, err + return payload, rv, err default: - return nil, fmt.Errorf("Unsupported transaction payload type %d", common.HeaderType(payload.Header.ChainHeader.Type)) + return nil, nil, fmt.Errorf("Unsupported transaction payload type %d", common.HeaderType(payload.Header.ChainHeader.Type)) } } diff --git a/core/system_chaincode/escc/endorser_onevalidsignature_test.go b/core/system_chaincode/escc/endorser_onevalidsignature_test.go index bc3e0c8a834..5aba4710cc0 100644 --- a/core/system_chaincode/escc/endorser_onevalidsignature_test.go +++ b/core/system_chaincode/escc/endorser_onevalidsignature_test.go @@ -270,7 +270,7 @@ func validateProposalResponse(prBytes []byte, proposal *pb.Proposal, visibility } // validate the transaction - _, err = peer.ValidateTransaction(tx) + _, _, err = peer.ValidateTransaction(tx) if err != nil { return err } diff --git a/peer/node/start.go b/peer/node/start.go index cae0cd68a26..9425d01a5d4 100755 --- a/peer/node/start.go +++ b/peer/node/start.go @@ -37,6 +37,7 @@ import ( "github.com/hyperledger/fabric/core/crypto/primitives" "github.com/hyperledger/fabric/core/endorser" "github.com/hyperledger/fabric/core/peer" + "github.com/hyperledger/fabric/core/util" "github.com/hyperledger/fabric/events/producer" pb "github.com/hyperledger/fabric/protos/peer" "github.com/spf13/cobra" @@ -131,7 +132,10 @@ func serve(args []string) error { grpcServer := grpc.NewServer(opts...) - registerChaincodeSupport(chaincode.DefaultChain, grpcServer) + /******this will go away when we implement join command*****/ + chainID := util.GetTestChainID() + + registerChaincodeSupport(chainID, grpcServer) logger.Debugf("Running peer") @@ -142,7 +146,10 @@ func serve(args []string) error { serverEndorser := endorser.NewEndorserServer() pb.RegisterEndorserServer(grpcServer, serverEndorser) - deliverService := noopssinglechain.NewDeliverService(peerEndpoint.Address, grpcServer) + //this shoul not need the chainID. Delivery should be + //split up into network part and chain part. This should + //only init the network part...TBD, part of Join work + deliverService := noopssinglechain.NewDeliverService(chainID, peerEndpoint.Address, grpcServer) if deliverService != nil { deliverService.Start() @@ -200,7 +207,10 @@ func serve(args []string) error { return <-serve } -func registerChaincodeSupport(chainname chaincode.ChainName, grpcServer *grpc.Server) { +//NOTE - when we implment JOIN we will no longer pass the chainID as param +//The chaincode support will come up without registering system chaincodes +//which will be registered only during join phase. +func registerChaincodeSupport(chainID string, grpcServer *grpc.Server) { //get user mode userRunsCC := false if viper.GetString("chaincode.mode") == chaincode.DevModeUserRunsChaincode { @@ -215,10 +225,10 @@ func registerChaincodeSupport(chainname chaincode.ChainName, grpcServer *grpc.Se } ccStartupTimeout := time.Duration(tOut) * time.Millisecond - ccSrv := chaincode.NewChaincodeSupport(chainname, peer.GetPeerEndpoint, userRunsCC, ccStartupTimeout) + ccSrv := chaincode.NewChaincodeSupport(peer.GetPeerEndpoint, userRunsCC, ccStartupTimeout) //Now that chaincode is initialized, register all system chaincodes. - chaincode.RegisterSysCCs() + chaincode.RegisterSysCCs(chainID) pb.RegisterChaincodeSupportServer(grpcServer, ccSrv) } diff --git a/protos/utils/proputils.go b/protos/utils/proputils.go index 8ad49582074..afc95f1fdac 100644 --- a/protos/utils/proputils.go +++ b/protos/utils/proputils.go @@ -389,7 +389,7 @@ func CreateProposalFromCDS(txid string, chainID string, cds *peer.ChaincodeDeplo ChaincodeSpec: &peer.ChaincodeSpec{ Type: peer.ChaincodeSpec_GOLANG, ChaincodeID: &peer.ChaincodeID{Name: "lccc"}, - CtorMsg: &peer.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte("default"), b}}}} + CtorMsg: &peer.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte(chainID), b}}}} //...and get the proposal for it return CreateProposalFromCIS(txid, chainID, lcccSpec, creator)