func Test2EndorsersDisagree(t *testing.T) { // get a toy proposal prop, err := getProposal() if err != nil { t.Fatalf("getProposal failed, err %s", err) return } simRes1 := []byte("simulation_result1") // endorse it to get a proposal response presp1, err := utils.CreateProposalResponse(prop.Header, prop.Payload, simRes1, nil, nil, signer) if err != nil { t.Fatalf("CreateProposalResponse failed, err %s", err) return } simRes2 := []byte("simulation_result2") // endorse it to get a proposal response presp2, err := utils.CreateProposalResponse(prop.Header, prop.Payload, simRes2, nil, nil, signer) if err != nil { t.Fatalf("CreateProposalResponse failed, err %s", err) return } // assemble a transaction from that proposal and endorsement _, err = utils.CreateSignedTx(prop, signer, presp1, presp2) if err == nil { t.Fatalf("CreateSignedTx should have failed") return } }
func Test2EndorsersAgree(t *testing.T) { // get a toy proposal prop, err := getProposal() if err != nil { t.Fatalf("getProposal failed, err %s", err) return } simRes1 := []byte("simulation_result") // endorse it to get a proposal response presp1, err := utils.CreateProposalResponse(prop.Header, prop.Payload, simRes1, nil, nil, signer) if err != nil { t.Fatalf("CreateProposalResponse failed, err %s", err) return } simRes2 := []byte("simulation_result") // endorse it to get a proposal response presp2, err := utils.CreateProposalResponse(prop.Header, prop.Payload, simRes2, nil, nil, signer) if err != nil { t.Fatalf("CreateProposalResponse failed, err %s", err) return } // assemble a transaction from that proposal and endorsement tx, err := utils.CreateSignedTx(prop, signer, presp1, presp2) if err != nil { t.Fatalf("CreateSignedTx failed, err %s", err) return } // validate the transaction _, _, err = ValidateTransaction(tx) if err != nil { t.Fatalf("ValidateTransaction failed, err %s", err) return } }
func TestBadTx(t *testing.T) { // get a toy proposal prop, err := getProposal() if err != nil { t.Fatalf("getProposal failed, err %s", err) return } simRes := []byte("simulation_result") // endorse it to get a proposal response presp, err := utils.CreateProposalResponse(prop.Header, prop.Payload, simRes, nil, nil, signer) if err != nil { t.Fatalf("CreateProposalResponse failed, err %s", err) return } // assemble a transaction from that proposal and endorsement tx, err := utils.CreateSignedTx(prop, signer, presp) if err != nil { t.Fatalf("CreateSignedTx failed, err %s", err) return } // mess with the transaction payload corrupt(tx.Payload) // validate the transaction it should fail _, _, err = ValidateTransaction(tx) if err == nil { t.Fatalf("ValidateTransaction should have failed") return } // assemble a transaction from that proposal and endorsement tx, err = utils.CreateSignedTx(prop, signer, presp) if err != nil { t.Fatalf("CreateSignedTx failed, err %s", err) return } // mess with the transaction payload corrupt(tx.Signature) // validate the transaction it should fail _, _, err = ValidateTransaction(tx) if err == nil { t.Fatalf("ValidateTransaction should have failed") return } }
func createTx() (*common.Envelope, error) { cis := &peer.ChaincodeInvocationSpec{ChaincodeSpec: &peer.ChaincodeSpec{ChaincodeID: &peer.ChaincodeID{Name: "foo"}}} uuid := util.GenerateUUID() prop, err := utils.CreateProposalFromCIS(uuid, util.GetTestChainID(), cis, sid) if err != nil { return nil, err } presp, err := utils.CreateProposalResponse(prop.Header, prop.Payload, []byte("res"), nil, nil, id) if err != nil { return nil, err } return utils.CreateSignedTx(prop, id, presp) }
func endTxSimulation(chainID string, txsim ledger.TxSimulator, payload []byte, commit bool, prop *pb.Proposal) error { txsim.Done() if lgr := peer.GetLedger(chainID); lgr != nil { if commit { var txSimulationResults []byte var err error //get simulation results if txSimulationResults, err = txsim.GetTxSimulationResults(); err != nil { return err } // assemble a (signed) proposal response message resp, err := putils.CreateProposalResponse(prop.Header, prop.Payload, txSimulationResults, nil, nil, signer) if err != nil { return err } // get the envelope env, err := putils.CreateSignedTx(prop, signer, resp) if err != nil { return err } envBytes, err := putils.GetBytesEnvelope(env) if err != nil { return err } //create the block with 1 transaction block := common.NewBlock(1, []byte{}) block.Data.Data = [][]byte{envBytes} //commit the block if err := lgr.Commit(block); err != nil { return err } } } return nil }
// ConstructSingedTxEnv constructs a transaction envelop for tests func ConstructSingedTxEnv(txid string, chainID string, ccName string, simulationResults []byte, events []byte, visibility []byte, signer msp.SigningIdentity) (*common.Envelope, error) { ss, err := signer.Serialize() if err != nil { return nil, err } prop, err := putils.CreateChaincodeProposal(txid, chainID, &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: &pb.ChaincodeID{Name: ccName}}}, ss) if err != nil { return nil, err } presp, err := putils.CreateProposalResponse(prop.Header, prop.Payload, simulationResults, nil, nil, signer) if err != nil { return nil, err } env, err := putils.CreateSignedTx(prop, signer, presp) if err != nil { return nil, err } return env, nil }
// Invoke is called to endorse the specified Proposal // For now, we sign the input and return the endorsed result. Later we can expand // the chaincode to provide more sophisticate policy processing such as enabling // policy specification to be coded as a transaction of the chaincode and Client // could select which policy to use for endorsement using parameter // @return a marshalled proposal response // Note that Peer calls this function with 4 mandatory arguments (and 2 optional ones): // args[0] - function name (not used now) // args[1] - serialized Header object // args[2] - serialized ChaincodeProposalPayload object // args[3] - binary blob of simulation results // args[4] - serialized events (optional) // args[5] - payloadVisibility (optional) // // NOTE: this chaincode is meant to sign another chaincode's simulation // results. It should not manipulate state as any state change will be // silently discarded: the only state changes that will be persisted if // this endorsement is successful is what we are about to sign, which by // definition can't be a state change of our own. func (e *EndorserOneValidSignature) Invoke(stub shim.ChaincodeStubInterface) ([]byte, error) { args := stub.GetArgs() if len(args) < 4 { return nil, fmt.Errorf("Incorrect number of arguments (expected a minimum of 4, provided %d)", len(args)) } else if len(args) > 6 { return nil, fmt.Errorf("Incorrect number of arguments (expected a maximum of 6, provided %d)", len(args)) } logger.Infof("ESCC starts: %d args", len(args)) // handle the header var hdr []byte if args[1] == nil { return nil, errors.New("serialized Header object is null") } hdr = args[1] // handle the proposal payload var payl []byte if args[2] == nil { return nil, errors.New("serialized ChaincodeProposalPayload object is null") } payl = args[2] // handle simulation results var results []byte if args[3] == nil { return nil, errors.New("simulation results are null") } results = args[3] // Handle serialized events if they have been provided // they might be nil in case there's no events but there // is a visibility field specified as the next arg events := []byte("") if len(args) > 4 && args[4] != nil { events = args[4] } // Handle payload visibility (it's an optional argument) visibility := []byte("") // TODO: when visibility is properly defined, replace with the default if len(args) > 5 { if args[5] == nil { return nil, errors.New("serialized events are null") } visibility = args[5] } // obtain the default signing identity for this peer; it will be used to sign this proposal response localMsp := mspmgmt.GetLocalMSP() if localMsp == nil { return nil, fmt.Errorf("Nil local MSP manager") } signingEndorser, err := localMsp.GetDefaultSigningIdentity() if err != nil { return nil, fmt.Errorf("Could not obtain the default signing identity, err %s", err) } // obtain a proposal response presp, err := utils.CreateProposalResponse(hdr, payl, results, events, visibility, signingEndorser) if err != nil { return nil, err } // marshall the proposal response so that we return its bytes prBytes, err := utils.GetBytesProposalResponse(presp) if err != nil { return nil, fmt.Errorf("Could not marshall ProposalResponse: err %s", err) } logger.Infof("ESCC exits successfully") return prBytes, nil }
func TestGoodPath(t *testing.T) { // get a toy proposal prop, err := getProposal() if err != nil { t.Fatalf("getProposal failed, err %s", err) return } // sign it sProp, err := utils.GetSignedProposal(prop, signer) if err != nil { t.Fatalf("GetSignedProposal failed, err %s", err) return } // validate it _, _, _, err = ValidateProposalMessage(sProp) if err != nil { t.Fatalf("ValidateProposalMessage failed, err %s", err) return } simRes := []byte("simulation_result") // endorse it to get a proposal response presp, err := utils.CreateProposalResponse(prop.Header, prop.Payload, simRes, nil, nil, signer) if err != nil { t.Fatalf("CreateProposalResponse failed, err %s", err) return } // assemble a transaction from that proposal and endorsement tx, err := utils.CreateSignedTx(prop, signer, presp) if err != nil { t.Fatalf("CreateSignedTx failed, err %s", err) return } // validate the transaction _, act, err := ValidateTransaction(tx) if err != nil { t.Fatalf("ValidateTransaction failed, err %s", err) return } // expect one single action if len(act) != 1 { t.Fatalf("Ivalid number of TransactionAction, expected 1, got %d", len(act)) return } // get the payload of the action _, simResBack, err := utils.GetPayloads(act[0]) if err != nil { t.Fatalf("GetPayloads failed, err %s", err) return } // compare it to the original action and expect it to be equal if string(simRes) != string(simResBack.Results) { t.Fatalf("Simulation results are different") return } }