func (k Keeper) SkipCurrentRequestBatch(ctx sdk.Context, requestContextID tmbytes.HexBytes, requestContext types.RequestContext) {
	requestContext.BatchCounter++
	requestContext.BatchState = types.BATCHRUNNING
	requestContext.BatchRequestCount = 0
	requestContext.BatchResponseCount = 0
	requestContext.BatchResponseThreshold = requestContext.ResponseThreshold
	k.SetRequestContext(ctx, requestContextID, requestContext)
	k.AddRequestBatchExpiration(ctx, requestContextID, ctx.BlockHeight()+requestContext.Timeout)
}
SkipCurrentRequestBatch skips the current request batch
package keeper
import (
	"encoding/hex"
	"encoding/json"
	"fmt"
	gogotypes "github.com/gogo/protobuf/types"
	"github.com/tendermint/tendermint/crypto/tmhash"
	tmbytes "github.com/tendermint/tendermint/libs/bytes"
	sdk "github.com/cosmos/cosmos-sdk/types"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
	"github.com/irisnet/irismod/modules/service/types"
)
func (k Keeper) RegisterResponseCallback(moduleName string, respCallback types.ResponseCallback) error {
	if _, ok := k.respCallbacks[moduleName]; ok {
		return sdkerrors.Wrapf(types.ErrCallbackRegistered, "%s already registered for module %s", "response callback", moduleName)
	}
	k.respCallbacks[moduleName] = respCallback
	return nil
}
func (k Keeper) RegisterStateCallback(moduleName string, stateCallback types.StateCallback) error {
	if _, ok := k.stateCallbacks[moduleName]; ok {
		return sdkerrors.Wrapf(types.ErrCallbackRegistered, "%s already registered for module %s", "state callback", moduleName)
	}
	k.stateCallbacks[moduleName] = stateCallback
	return nil
}
func (k Keeper) CreateRequestContext(
	ctx sdk.Context,
	serviceName string,
	providers []sdk.AccAddress,
	consumer sdk.AccAddress,
	input string,
	serviceFeeCap sdk.Coins,
	timeout int64,
	repeated bool,
	repeatedFrequency uint64,
	repeatedTotal int64,
	state types.RequestContextState,
	responseThreshold uint32,
	moduleName string,
) (
	tmbytes.HexBytes, error,
) {
	if len(moduleName) != 0 {
		if _, err := k.GetResponseCallback(moduleName); err != nil {
			return nil, err
		}
		if _, err := k.GetStateCallback(moduleName); err != nil {
			return nil, err
		}
		if err := types.ValidateRequest(
			serviceName, serviceFeeCap, providers, input,
			timeout, repeated, repeatedFrequency, repeatedTotal,
		); err != nil {
			return nil, err
		}
		if responseThreshold < 1 || int(responseThreshold) > len(providers) {
			return nil, sdkerrors.Wrapf(types.ErrInvalidResponseThreshold, "response threshold [%d] must be between [1,%d]", responseThreshold, len(providers))
		}
	}
	_, found := k.GetServiceDefinition(ctx, serviceName)
	if !found {
		return nil, sdkerrors.Wrap(types.ErrUnknownServiceDefinition, serviceName)
	}
	if err := types.ValidateRequestInput(input); err != nil {
		return nil, err
	}
	if err := k.validateServiceFeeCap(ctx, serviceFeeCap); err != nil {
		return nil, err
	}
	maxRequestTimeout := k.MaxRequestTimeout(ctx)
	if timeout > maxRequestTimeout {
		return nil, sdkerrors.Wrapf(types.ErrInvalidTimeout, "timeout [%d] must not be greater than the max request timeout [%d]", timeout, maxRequestTimeout)
	}
	if repeated {
		if repeatedFrequency == 0 {
			repeatedFrequency = uint64(timeout)
		}
	} else {
		repeatedFrequency = 0
		repeatedTotal = 0
	}
	batchCounter := uint64(0)
	batchRequestCount := uint32(0)
	batchResponseCount := uint32(0)
	batchResponseThreshold := responseThreshold
	batchState := types.BATCHCOMPLETED
	requestContext := types.NewRequestContext(
		serviceName, providers, consumer, input, serviceFeeCap, timeout,
		repeated, repeatedFrequency, repeatedTotal, batchCounter,
		batchRequestCount, batchResponseCount, batchResponseThreshold,
		batchState, state, responseThreshold, moduleName,
	)
	requestContextID := types.GenerateRequestContextID(TxHash(ctx), k.GetInternalIndex(ctx))
	k.SetRequestContext(ctx, requestContextID, requestContext)
	if requestContext.State == types.RUNNING {
		k.AddNewRequestBatch(ctx, requestContextID, ctx.BlockHeight())
	}
	return requestContextID, nil
}
func (k Keeper) UpdateRequestContext(
	ctx sdk.Context,
	requestContextID tmbytes.HexBytes,
	providers []sdk.AccAddress,
	respThreshold uint32,
	serviceFeeCap sdk.Coins,
	timeout int64,
	repeatedFreq uint64,
	repeatedTotal int64,
	consumer sdk.AccAddress,
) error {
	pds := make([]string, len(providers))
	for i, provider := range providers {
		pds[i] = provider.String()
	}
	requestContext, found := k.GetRequestContext(ctx, requestContextID)
	if !found {
		return sdkerrors.Wrap(types.ErrUnknownRequestContext, requestContextID.String())
	}
	if len(requestContext.ModuleName) > 0 {
		if err := k.CheckAuthority(ctx, consumer, requestContextID, false); err != nil {
			return err
		}
	}
	if requestContext.State == types.COMPLETED {
		return types.ErrRequestContextCompleted
	}
	if len(requestContext.ModuleName) > 0 {
		if err := types.ValidateRequestContextUpdating(providers, serviceFeeCap, timeout, repeatedFreq, repeatedTotal); err != nil {
			return err
		}
		if respThreshold == 0 {
			respThreshold = requestContext.ResponseThreshold
		}
		if len(pds) == 0 {
			pds = requestContext.Providers
		}
		if respThreshold > uint32(len(pds)) {
			return sdkerrors.Wrapf(types.ErrInvalidResponseThreshold, "response threshold [%d] must be between [1,%d]", respThreshold, len(pds))
		}
		if respThreshold > 0 {
			requestContext.ResponseThreshold = respThreshold
		}
	}
	if !serviceFeeCap.Empty() {
		if err := k.validateServiceFeeCap(ctx, serviceFeeCap); err != nil {
			return err
		}
		requestContext.ServiceFeeCap = serviceFeeCap
	}
	maxRequestTimeout := k.MaxRequestTimeout(ctx)
	if timeout > maxRequestTimeout {
		return sdkerrors.Wrapf(types.ErrInvalidTimeout, "timeout [%d] must not be greater than the max request timeout [%d]", timeout, maxRequestTimeout)
	}
	if timeout == 0 {
		timeout = requestContext.Timeout
	}
	if repeatedFreq == 0 {
		repeatedFreq = requestContext.RepeatedFrequency
	}
	if repeatedFreq < uint64(timeout) {
		return sdkerrors.Wrapf(types.ErrInvalidRepeatedFreq, "repeated frequency [%d] must not be less than the timeout [%d]", repeatedFreq, requestContext.Timeout)
	}
	if repeatedTotal >= 1 && repeatedTotal < int64(requestContext.BatchCounter) {
		return sdkerrors.Wrapf(types.ErrInvalidRepeatedTotal, "updated repeated total [%d] must not be less than the current batch counter [%d]", repeatedTotal, requestContext.BatchCounter)
	}
	if len(pds) > 0 {
		requestContext.Providers = pds
	}
	if timeout > 0 {
		requestContext.Timeout = timeout
	}
	if repeatedFreq > 0 {
		requestContext.RepeatedFrequency = repeatedFreq
	}
	if repeatedTotal != 0 {
		requestContext.RepeatedTotal = repeatedTotal
	}
	k.SetRequestContext(ctx, requestContextID, requestContext)
	return nil
}
func (k Keeper) PauseRequestContext(
	ctx sdk.Context,
	requestContextID tmbytes.HexBytes,
	consumer sdk.AccAddress,
) error {
	requestContext, found := k.GetRequestContext(ctx, requestContextID)
	if !found {
		return sdkerrors.Wrap(types.ErrUnknownRequestContext, requestContextID.String())
	}
	if len(requestContext.ModuleName) > 0 {
		if err := k.CheckAuthority(ctx, consumer, requestContextID, false); err != nil {
			return err
		}
	}
	if !requestContext.Repeated {
		return types.ErrRequestContextNonRepeated
	}
	if requestContext.State != types.RUNNING {
		return types.ErrRequestContextNotRunning
	}
	requestContext.State = types.PAUSED
	k.SetRequestContext(ctx, requestContextID, requestContext)
	return nil
}
func (k Keeper) StartRequestContext(
	ctx sdk.Context,
	requestContextID tmbytes.HexBytes,
	consumer sdk.AccAddress,
) error {
	requestContext, found := k.GetRequestContext(ctx, requestContextID)
	if !found {
		return sdkerrors.Wrap(types.ErrUnknownRequestContext, requestContextID.String())
	}
	if len(requestContext.ModuleName) > 0 {
		if err := k.CheckAuthority(ctx, consumer, requestContextID, false); err != nil {
			return err
		}
	}
	if requestContext.State != types.PAUSED {
		return types.ErrRequestContextNotPaused
	}
	requestContext.State = types.RUNNING
	k.SetRequestContext(ctx, requestContextID, requestContext)
	if !k.HasRequestBatchExpiration(ctx, requestContextID) && !k.HasNewRequestBatch(ctx, requestContextID) {
		k.AddNewRequestBatch(ctx, requestContextID, ctx.BlockHeight())
	}
	return nil
}
func (k Keeper) KillRequestContext(
	ctx sdk.Context,
	requestContextID tmbytes.HexBytes,
	consumer sdk.AccAddress,
) error {
	requestContext, found := k.GetRequestContext(ctx, requestContextID)
	if !found {
		return sdkerrors.Wrap(types.ErrUnknownRequestContext, requestContextID.String())
	}
	if len(requestContext.ModuleName) > 0 {
		if err := k.CheckAuthority(ctx, consumer, requestContextID, false); err != nil {
			return err
		}
	}
	if !requestContext.Repeated {
		return types.ErrRequestContextNonRepeated
	}
	requestContext.State = types.COMPLETED
	k.SetRequestContext(ctx, requestContextID, requestContext)
	return nil
}
func (k Keeper) SetRequestContext(ctx sdk.Context, requestContextID tmbytes.HexBytes, requestContext types.RequestContext) {
	store := ctx.KVStore(k.storeKey)
	bz := k.cdc.MustMarshal(&requestContext)
	store.Set(types.GetRequestContextKey(requestContextID), bz)
}
func (k Keeper) DeleteRequestContext(ctx sdk.Context, requestContextID tmbytes.HexBytes) {
	store := ctx.KVStore(k.storeKey)
	store.Delete(types.GetRequestContextKey(requestContextID))
}
func (k Keeper) GetRequestContext(ctx sdk.Context, requestContextID tmbytes.HexBytes) (requestContext types.RequestContext, found bool) {
	store := ctx.KVStore(k.storeKey)
	bz := store.Get(types.GetRequestContextKey(requestContextID))
	if bz == nil {
		return requestContext, false
	}
	k.cdc.MustUnmarshal(bz, &requestContext)
	return requestContext, true
}
func (k Keeper) IterateRequestContexts(
	ctx sdk.Context,
	op func(requestContextID tmbytes.HexBytes, requestContext types.RequestContext) (stop bool),
) {
	store := ctx.KVStore(k.storeKey)
	iterator := sdk.KVStorePrefixIterator(store, types.RequestContextKey)
	defer iterator.Close()
	for ; iterator.Valid(); iterator.Next() {
		requestContextID := iterator.Key()[1:]
		var requestContext types.RequestContext
		k.cdc.MustUnmarshal(iterator.Value(), &requestContext)
		if stop := op(requestContextID, requestContext); stop {
			break
		}
	}
}
func (k Keeper) InitiateRequests(
	ctx sdk.Context,
	requestContextID tmbytes.HexBytes,
	providers []sdk.AccAddress,
	providerRequests map[string][]string,
) []tmbytes.HexBytes {
	requestContext, _ := k.GetRequestContext(ctx, requestContextID)
	requestContext.BatchCounter++
	var requests []types.CompactRequest
	var requestIDs []tmbytes.HexBytes
	consumer, _ := sdk.AccAddressFromBech32(requestContext.Consumer)
	for providerIndex, provider := range providers {
		request := k.buildRequest(
			ctx, requestContextID, requestContext.BatchCounter,
			requestContext.ServiceName, provider,
			consumer, requestContext.Timeout,
		)
		requestID := types.GenerateRequestID(requestContextID, requestContext.BatchCounter, ctx.BlockHeight(), int16(providerIndex))
		k.SetCompactRequest(ctx, requestID, request)
		k.AddActiveRequest(ctx, requestContext.ServiceName, provider, ctx.BlockHeight()+requestContext.Timeout, requestID)
		requests = append(requests, request)
		providerRequests[types.ActionTag(requestContext.ServiceName, provider.String())] = append(
			providerRequests[types.ActionTag(requestContext.ServiceName, provider.String())],
			requestID.String(),
		)
		requestIDs = append(requestIDs, requestID)
	}
	requestContext.BatchState = types.BATCHRUNNING
	requestContext.BatchResponseCount = 0
	requestContext.BatchRequestCount = uint32(len(providers))
	requestContext.BatchResponseThreshold = requestContext.ResponseThreshold
	k.SetRequestContext(ctx, requestContextID, requestContext)
	if len(requests) > 0 {
		requestsJSON, _ := json.Marshal(requests)
		ctx.EventManager().EmitEvents(sdk.Events{
			sdk.NewEvent(
				types.EventTypeNewBatchRequest,
				sdk.NewAttribute(types.AttributeKeyServiceName, requestContext.ServiceName),
				sdk.NewAttribute(types.AttributeKeyRequestContextID, requestContextID.String()),
				sdk.NewAttribute(types.AttributeKeyRequests, string(requestsJSON)),
			),
		})
	}
	return requestIDs
}