예제 #1
0
//call specified chaincode (system or user)
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

	if txsim != nil {
		ctxt = context.WithValue(ctxt, chaincode.TXSimulatorKey, txsim)
	}

	//is this a system chaincode
	syscc := chaincode.IsSysCC(cid.Name)

	cccid := chaincode.NewCCContext(chainID, cid.Name, "", txid, syscc, prop)

	b, ccevent, err = chaincode.ExecuteChaincode(ctxt, cccid, cis.ChaincodeSpec.CtorMsg.Args)

	if err != nil {
		return nil, nil, err
	}

	//----- BEGIN -  SECTION THAT MAY NEED TO BE DONE IN LCCC ------
	//if this a call to deploy a chaincode, We need a mechanism
	//to pass TxSimulator into LCCC. Till that is worked out this
	//special code does the actual deploy, upgrade here so as to collect
	//all state under one TxSimulator
	//
	//NOTE that if there's an error all simulation, including the chaincode
	//table changes in lccc will be thrown away
	if cid.Name == "lccc" && len(cis.ChaincodeSpec.CtorMsg.Args) == 3 && (string(cis.ChaincodeSpec.CtorMsg.Args[0]) == "deploy" || string(cis.ChaincodeSpec.CtorMsg.Args[0]) == "upgrade") {
		var cds *pb.ChaincodeDeploymentSpec
		cds, err = putils.GetChaincodeDeploymentSpec(cis.ChaincodeSpec.CtorMsg.Args[2])
		if err != nil {
			return nil, nil, err
		}

		//this should not be a system chaincode
		if chaincode.IsSysCC(cds.ChaincodeSpec.ChaincodeID.Name) {
			return nil, nil, fmt.Errorf("attempting to deploy a system chaincode %s/%s", cds.ChaincodeSpec.ChaincodeID.Name, chainID)
		}

		cccid = chaincode.NewCCContext(chainID, cds.ChaincodeSpec.ChaincodeID.Name, "", txid, false, prop)

		err = e.deploy(ctxt, cccid, cds)
		if err != nil {
			return nil, nil, err
		}
	}
	//----- END -------

	return b, ccevent, err
}
예제 #2
0
func isTxValidForVscc(payload *common.Payload, envBytes []byte) error {
	// TODO: Extract the VSCC/policy from LCCC as soon as this is ready
	vscc := "vscc"

	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?

	// build arguments for VSCC invocation
	// args[0] - function name (not used now)
	// args[1] - serialized Envelope
	args := [][]byte{[]byte(""), envBytes}

	// 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, chainName, vsccCis, []byte(""))
	if err != nil {
		logger.Errorf("Cannot create a proposal to invoke VSCC, err %s\n", err)
		return err
	}

	// get context for the chaincode execution
	var txsim ledger.TxSimulator
	lgr := peer.GetLedger(chainName)
	txsim, err = lgr.NewTxSimulator()
	if err != nil {
		logger.Errorf("Cannot obtain tx simulator, err %s\n", err)
		return err
	}
	defer txsim.Done()
	ctxt := context.WithValue(context.Background(), chaincode.TXSimulatorKey, txsim)

	cccid := chaincode.NewCCContext(chainName, vscc, "", txid, true, prop)

	// invoke VSCC
	_, _, err = chaincode.ExecuteChaincode(ctxt, cccid, args)
	if err != nil {
		logger.Errorf("VSCC check failed for transaction, error %s", err)
		return err
	}

	return nil
}