func (h ServiceHandler) PollService(ctx context.Context, v interface{}) (interface{}, error) {
	session := ctx.Value(auth.Session{}).(string)
	req := v.(*PollServiceRequest)
	if req.Count == 0 {
		req.Count = 10
	}
	res, err := h.client.PollService(ctx, backend.PollServiceRequest{
		Offset:          req.Offset,
		Count:           req.Count,
		DiscardPrevious: req.DiscardPrevious,
		SessionKey:      session,
	})
	if err != nil {
		return nil, err
	}
	events := make([]Event, 0, len(res.Events))
	for _, r := range res.Events {
		events = append(events, h.mapEvent(r))
	}
	return PollServiceResponse{Offset: res.Offset, Events: events}, nil
}
PollService polls the service response queue to retrieve available responses
package service
import (
	"context"
	"encoding/binary"
	"encoding/hex"
	stderr "errors"
	auth "github.com/oasislabs/oasis-gateway/auth/core"
	backend "github.com/oasislabs/oasis-gateway/backend/core"
	"github.com/oasislabs/oasis-gateway/errors"
	"github.com/oasislabs/oasis-gateway/log"
	"github.com/oasislabs/oasis-gateway/rpc"
)
type Client interface {
	DeployServiceAsync(context.Context, backend.DeployServiceRequest) (uint64, errors.Err)
	ExecuteServiceAsync(context.Context, backend.ExecuteServiceRequest) (uint64, errors.Err)
	PollService(context.Context, backend.PollServiceRequest) (backend.Events, errors.Err)
	GetCode(context.Context, backend.GetCodeRequest) (backend.GetCodeResponse, errors.Err)
	GetExpiry(context.Context, backend.GetExpiryRequest) (backend.GetExpiryResponse, errors.Err)
	GetPublicKey(context.Context, backend.GetPublicKeyRequest) (backend.GetPublicKeyResponse, errors.Err)
}
type Services struct {
	Logger   log.Logger
	Client   Client
	Verifier auth.Auth
}
type ServiceHandler struct {
	logger   log.Logger
	client   Client
	verifier auth.Auth
}
func (h ServiceHandler) DeployService(ctx context.Context, v interface{}) (interface{}, error) {
	aad := ctx.Value(auth.AAD{}).(string)
	session := ctx.Value(auth.Session{}).(string)
	req := v.(*DeployServiceRequest)
	authReq := auth.AuthRequest{
		API:  "Deploy",
		Data: req.Data,
	}
	if err := h.verifier.Verify(ctx, authReq); err != nil {
		e := errors.New(errors.ErrFailedAADVerification, err)
		h.logger.Debug(ctx, "failed to verify AAD", log.MapFields{
			"call_type": "DeployServiceFailure",
			"session":   session,
			"err":       e,
		})
		return nil, e
	}
	id, err := h.client.DeployServiceAsync(context.Background(), backend.DeployServiceRequest{
		AAD:        aad,
		Data:       req.Data,
		SessionKey: session,
	})
	if err != nil {
		h.logger.Debug(ctx, "failed to start request", log.MapFields{
			"call_type": "DeployServiceFailure",
			"session":   session,
		}, err)
		return nil, err
	}
	return AsyncResponse{ID: id}, nil
}
func (h ServiceHandler) parseExecuteMessage(v *ExecuteServiceRequest) (authReq auth.AuthRequest) {
	authReq.API = "Execute"
	authReq.Address = v.Address
	authReq.Data = v.Data
	dst := make([]byte, hex.DecodedLen(len(v.Data)))
	_, err := hex.Decode(dst, []byte(v.Data))
	if err != nil || len(dst) < 32 {
		return
	}
	authReq.PK = dst[0:16]
	cipherLength := binary.BigEndian.Uint64([]byte(dst[16:24]))
	aadLength := binary.BigEndian.Uint64([]byte(dst[24:32]))
	if len(dst) < int(cipherLength+aadLength+32) {
		return
	}
	aadOffset := 32 + cipherLength
	authReq.AAD = dst[aadOffset : aadOffset+aadLength]
	return
}
func (h ServiceHandler) ExecuteService(ctx context.Context, v interface{}) (interface{}, error) {
	aad := ctx.Value(auth.AAD{}).(string)
	session := ctx.Value(auth.Session{}).(string)
	req := v.(*ExecuteServiceRequest)
	if len(req.Address) == 0 {
		e := errors.New(errors.ErrInvalidAddress, nil)
		h.logger.Debug(ctx, "received empty address", log.MapFields{
			"call_type": "ExecuteServiceFailure",
			"session":   session,
		}, e)
		return nil, e
	}
	authReq := h.parseExecuteMessage(req)
	if err := h.verifier.Verify(ctx, authReq); err != nil {
		e := errors.New(errors.ErrFailedAADVerification, err)
		h.logger.Debug(ctx, "failed to verify AAD", log.MapFields{
			"call_type": "ExecuteServiceFailure",
			"session":   session,
			"err":       e,
		})
		return nil, e
	}
	id, err := h.client.ExecuteServiceAsync(context.Background(), backend.ExecuteServiceRequest{
		AAD:        aad,
		Address:    req.Address,
		Data:       req.Data,
		SessionKey: session,
	})
	if err != nil {
		h.logger.Debug(ctx, "failed to start request", log.MapFields{
			"call_type": "ExecuteServiceFailure",
			"address":   req.Address,
			"session":   session,
		}, err)
		return nil, err
	}
	return AsyncResponse{ID: id}, nil
}
func (h ServiceHandler) mapEvent(event backend.Event) Event {
	switch r := event.(type) {
	case backend.ErrorEvent:
		return ErrorEvent{
			ID:    r.ID,
			Cause: r.Cause,
		}
	case backend.ExecuteServiceResponse:
		return ExecuteServiceEvent{
			ID:      r.ID,
			Address: r.Address,
			Output:  r.Output,
		}
	case backend.DeployServiceResponse:
		return DeployServiceEvent{
			ID:      r.ID,
			Address: r.Address,
		}
	default:
		panic("received unexpected event type from polling service")
	}
}