func getSignedProposal(prop *pb.Proposal, signer msp.SigningIdentity) (*pb.SignedProposal, error) { propBytes, err := pbutils.GetBytesProposal(prop) if err != nil { return nil, err } signature, err := signer.Sign(propBytes) if err != nil { return nil, err } return &pb.SignedProposal{ProposalBytes: propBytes, Signature: signature}, nil }
func (b *BDDContext) userSendsProposalToEndorsersWithTimeoutOfSeconds(enrollID, proposalAlias, timeoutInSecs string, endorsersTable *gherkin.DataTable) (err error) { var proposal *pb.Proposal var keyedProposalResponsesMap KeyedProposalResponseMap keyedProposalResponsesMap = make(KeyedProposalResponseMap) errRetFunc := func() error { return fmt.Errorf("Error sending proposal '%s' for user '%s': %s", proposalAlias, enrollID, err) } var userRegistration *UserRegistration if userRegistration, err = b.GetUserRegistration(enrollID); err != nil { return errRetFunc() } // Get the proposal from the user if proposal, err = userRegistration.GetProposal(proposalAlias); err != nil { return errRetFunc() } var ctx context.Context var cancel context.CancelFunc if ctx, cancel, err = getContextAndCancelForTimeoutInSecs(context.Background(), timeoutInSecs); err != nil { return errRetFunc() } defer cancel() // Loop through endorsers and send proposals var endorsers []string if endorsers, err = b.GetArgsForUser(endorsersTable.Rows[0].Cells, userRegistration); err != nil { return errRetFunc() } respQueue := make(chan *KeyedProposalResponse) for _, e := range endorsers { go func(endorser string) { var localErr error var proposalResponse *pb.ProposalResponse // Now use the endorser client to send the proposal var grpcClient *grpc.ClientConn if grpcClient, localErr = b.getGrpcClientForComposeService(endorser); localErr != nil { respQueue <- &KeyedProposalResponse{endorser, nil, fmt.Errorf("Error calling endorser '%s': %s", endorser, localErr)} return } defer grpcClient.Close() proposalBytes, err := utils.GetBytesProposal(proposal) if err != nil { respQueue <- &KeyedProposalResponse{endorser, nil, fmt.Errorf("Error serializing proposal bytes")} return } // FIXME: the endorser needs to be given a signed proposal - who should sign? signedProposal := &pb.SignedProposal{ProposalBytes: proposalBytes, Signature: []byte("signature")} endorserClient := pb.NewEndorserClient(grpcClient) if proposalResponse, localErr = endorserClient.ProcessProposal(ctx, signedProposal); localErr != nil { respQueue <- &KeyedProposalResponse{endorser, nil, fmt.Errorf("Error calling endorser '%s': %s", endorser, localErr)} return } respQueue <- &KeyedProposalResponse{endorser, proposalResponse, nil} }(e) } go func() { for i := 0; i < len(endorsers); i++ { result := <-respQueue keyedProposalResponsesMap[result.endorser] = result if result.err != nil { // TODO: think about whether to break on first failure, or allow to collect } } cancel() }() <-ctx.Done() if ctx.Err() != context.Canceled { err = ctx.Err() return errRetFunc() } userRegistration.lastResult = keyedProposalResponsesMap return nil }