cachemdw

package
v0.0.0-...-a6a90d4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 3, 2024 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package cachemdw is responsible for caching EVM requests and provides corresponding middleware package can work with any underlying storage which implements simple cache.Cache interface

package provides two different middlewares: - IsCachedMiddleware (should be run before proxy middleware) - CachingMiddleware (should be run after proxy middleware)

IsCachedMiddleware is responsible for setting response in the context if it's in the cache CachingMiddleware is responsible for caching response by taking a value from context (should be set by proxy mdw) and setting in the cache

Index

Constants

View Source
const (
	CachedContextKey   = "X-KAVA-PROXY-CACHED"
	ResponseContextKey = "X-KAVA-PROXY-RESPONSE"

	CacheHeaderKey          = "X-Kava-Proxy-Cache-Status"
	CacheHitHeaderValue     = "HIT"
	CacheMissHeaderValue    = "MISS"
	CachePartialHeaderValue = "PARTIAL"
)

Variables

View Source
var (
	ErrRequestIsNotCacheable  = errors.New("request is not cacheable")
	ErrResponseIsNotCacheable = errors.New("response is not cacheable")
	ErrResponseIsNotFinal     = errors.New("response is not final")
)

Functions

func BuildCacheKey

func BuildCacheKey(cachePrefix string, cacheItemType CacheItemType, parts []string) string

func GetQueryKey

func GetQueryKey(
	cachePrefix string,
	req *decode.EVMRPCRequestEnvelope,
) (string, error)

GetQueryKey calculates cache key for request

func IsCacheHitHeaders

func IsCacheHitHeaders(header http.Header) bool

IsCacheHitHeaders returns true when the passed in response headers are for a request that came from the cache.

func IsCacheable

func IsCacheable(
	logger *logging.ServiceLogger,
	req *decode.EVMRPCRequestEnvelope,
) bool

IsCacheable checks if EVM request is cacheable. In current implementation we consider request is cacheable if it has specific block height

func IsRequestCached

func IsRequestCached(ctx context.Context) bool

IsRequestCached returns whether request was cached if returns true it means: - middleware marked that request was cached - value of cached response should be available in context via ResponseContextKey

func LogCannotCastRequestError

func LogCannotCastRequestError(logger *logging.ServiceLogger, r *http.Request)

Types

type CacheItemType

type CacheItemType int
const (
	CacheItemTypeEVMRequest CacheItemType = iota + 1
)

func (CacheItemType) String

func (t CacheItemType) String() string

type Config

type Config struct {
	// TTL for cached evm requests
	// Different evm method groups may have different TTLs
	// TTL should be either greater than zero or equal to -1, -1 means cache indefinitely
	CacheMethodHasBlockNumberParamTTL time.Duration
	CacheMethodHasBlockHashParamTTL   time.Duration
	CacheStaticMethodTTL              time.Duration
	CacheMethodHasTxHashParamTTL      time.Duration
}

type JsonRpcError

type JsonRpcError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

func (*JsonRpcError) String

func (e *JsonRpcError) String() string

String returns the string representation of the error

type JsonRpcResponse

type JsonRpcResponse struct {
	Version      string          `json:"jsonrpc,omitempty"`
	ID           json.RawMessage `json:"id,omitempty"`
	Result       json.RawMessage `json:"result,omitempty"`
	JsonRpcError *JsonRpcError   `json:"error,omitempty"`
}

JsonRpcResponse is a EVM JSON-RPC response

func UnmarshalJsonRpcResponse

func UnmarshalJsonRpcResponse(data []byte) (*JsonRpcResponse, error)

UnmarshalJsonRpcResponse unmarshals a JSON-RPC response

func (*JsonRpcResponse) Error

func (resp *JsonRpcResponse) Error() error

Error returns the json-rpc error if any

func (*JsonRpcResponse) IsCacheable

func (resp *JsonRpcResponse) IsCacheable() bool

IsCacheable returns true in case of: - json-rpc response doesn't contain an error - json-rpc response's result isn't empty

func (*JsonRpcResponse) IsFinal

func (resp *JsonRpcResponse) IsFinal(method string) bool

func (*JsonRpcResponse) IsResultEmpty

func (resp *JsonRpcResponse) IsResultEmpty() bool

IsResultEmpty checks if the response's result is empty

func (*JsonRpcResponse) Marshal

func (resp *JsonRpcResponse) Marshal() ([]byte, error)

Marshal marshals a JSON-RPC response to JSON

type QueryResponse

type QueryResponse struct {
	// JsonRpcResponseResult is an EVM JSON-RPC response's result
	JsonRpcResponseResult []byte `json:"json_rpc_response_result"`
	// HeaderMap is a map of HTTP headers which is cached along with the EVM JSON-RPC response
	HeaderMap map[string]string `json:"header_map"`
}

QueryResponse represents the structure which stored in the cache for every cacheable request

type ServiceCache

type ServiceCache struct {
	*logging.ServiceLogger
	// contains filtered or unexported fields
}

ServiceCache is responsible for caching EVM requests and provides corresponding middleware ServiceCache can work with any underlying storage which implements simple cache.Cache interface

func NewServiceCache

func NewServiceCache(
	cacheClient cache.Cache,
	blockGetter decode.EVMBlockGetter,
	decodedRequestContextKey any,
	cachePrefix string,
	cacheEnabled bool,
	whitelistedHeaders []string,
	defaultAccessControlAllowOriginValue string,
	hostnameToAccessControlAllowOriginValueMap map[string]string,
	config *Config,
	logger *logging.ServiceLogger,
) *ServiceCache

func (*ServiceCache) CacheQueryResponse

func (c *ServiceCache) CacheQueryResponse(
	ctx context.Context,
	req *decode.EVMRPCRequestEnvelope,
	responseInBytes []byte,
	headerMap map[string]string,
) error

CacheQueryResponse calculates cache key for request and then saves response to the cache. NOTE: only JSON-RPC response's result is cached. There is no point to cache JSON-RPC response's ID (because it should correspond to request's ID, which constantly changes). Same with JSON-RPC response's Version.

func (*ServiceCache) CachingMiddleware

func (c *ServiceCache) CachingMiddleware(
	next http.Handler,
) http.HandlerFunc

CachingMiddleware returns kava-proxy-service compatible middleware which works in the following way: - tries to get decoded request from context (previous middleware should set it) - checks few conditions:

  • if request isn't already cached
  • if request is cacheable
  • if response is present in context

- if all above is true - caches the response - calls next middleware

func (*ServiceCache) GetCachedQueryResponse

func (c *ServiceCache) GetCachedQueryResponse(
	ctx context.Context,
	req *decode.EVMRPCRequestEnvelope,
) (*QueryResponse, error)

GetCachedQueryResponse calculates cache key for request and then tries to get it from cache. NOTE: only JSON-RPC response's result will be taken from the cache. JSON-RPC response's ID and Version will be constructed on the fly to match JSON-RPC request.

func (*ServiceCache) GetTTL

func (c *ServiceCache) GetTTL(method string) (time.Duration, error)

GetTTL returns TTL for specified EVM method.

func (*ServiceCache) Healthcheck

func (c *ServiceCache) Healthcheck(ctx context.Context) error

func (*ServiceCache) IsCacheEnabled

func (c *ServiceCache) IsCacheEnabled() bool

func (*ServiceCache) IsCachedMiddleware

func (c *ServiceCache) IsCachedMiddleware(
	next http.Handler,
) http.HandlerFunc

IsCachedMiddleware returns kava-proxy-service compatible middleware which works in the following way: - tries to get decoded request from context (previous middleware should set it) - tries to get response from the cache

  • if present sets cached response in context, marks as cached in context and forwards to next middleware
  • if not present marks as uncached in context and forwards to next middleware

- next middleware should check whether request was cached and act accordingly:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL