types

package
v1.0.25 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package types provides core QoS types that can be imported without cycles.

The DataExtractor interface defines how endpoint quality data is extracted from responses. This enables both hardcoded extractors (EVM, Cosmos, Solana) and future dynamic/generic extractors (YAML-configured rules).

This package is separate from qos to avoid import cycles with gateway.

Package types provides the NoOpDataExtractor for passthrough services.

NoOpDataExtractor is used for services that don't need response parsing. All extraction methods return zero values or indicate "not available". This is the default fallback for unknown services.

Package types provides the ExtractorRegistry for mapping service IDs to DataExtractors.

The registry enables service-agnostic request processing on the hot path, with service-specific parsing deferred to async workers.

Usage

registry := types.NewExtractorRegistry()
registry.Register("eth", evm.NewEVMDataExtractor())
registry.Register("osmosis", cosmos.NewCosmosDataExtractor())
registry.Register("text-to-text", types.NewNoOpDataExtractor()) // passthrough

// In async worker:
extractor := registry.Get(serviceID)
data := types.NewExtractedData(endpoint, statusCode, response, latency)
data.ExtractAll(extractor)

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidBlockHeightResult = errors.New("invalid block height result")

ErrInvalidBlockHeightResult is returned by DataExtractor.ExtractBlockHeight when the response contains a result field but the result cannot be parsed as a block height. For example, a supplier returning {"result":[]} for eth_blockNumber.

This is distinct from "method not relevant" errors (e.g., eth_getBalance has no block height) and from JSON-RPC error responses (which are valid protocol responses).

When this error is returned, the endpoint should be marked with block height 0 so the block height filter catches it, rather than treating it as "unknown/fresh".

View Source
var ErrNoOpExtractor = errors.New("noop extractor: extraction not supported for this service")

ErrNoOpExtractor is returned when extraction is not supported.

Functions

This section is empty.

Types

type DataExtractor

type DataExtractor interface {
	// ExtractBlockHeight extracts the latest block height from a response.
	// This is used to determine sync status - endpoints behind in block height
	// are potentially stale or syncing.
	//
	// Parameters:
	//   - request: Original request bytes (to identify method)
	//   - response: Response bytes to parse
	//
	// Returns:
	//   - Block height as int64
	//   - Error if extraction fails or response doesn't contain block height
	ExtractBlockHeight(request []byte, response []byte) (int64, error)

	// ExtractChainID extracts the chain identifier from a response.
	// This is used to validate endpoints are on the correct chain.
	//
	// Parameters:
	//   - request: Original request bytes (to identify method)
	//   - response: Response bytes to parse
	//
	// Returns:
	//   - Chain ID as string (hex for EVM, chain-name for Cosmos)
	//   - Error if extraction fails or response doesn't contain chain ID
	ExtractChainID(request []byte, response []byte) (string, error)

	// IsSyncing determines if the endpoint is currently syncing.
	// Syncing endpoints may return stale data and should be deprioritized.
	//
	// Parameters:
	//   - request: Original request bytes (to identify method)
	//   - response: Response bytes to parse
	//
	// Returns:
	//   - true if endpoint is syncing
	//   - false if endpoint is synced
	//   - Error if sync status cannot be determined
	IsSyncing(request []byte, response []byte) (bool, error)

	// IsArchival determines if the endpoint supports archival queries.
	// Archival endpoints can serve historical data queries.
	//
	// Parameters:
	//   - request: Original request bytes (to identify method)
	//   - response: Response bytes to parse
	//
	// Returns:
	//   - true if endpoint is archival (query succeeded)
	//   - false if endpoint is not archival (query failed)
	//   - Error if archival status cannot be determined
	IsArchival(request []byte, response []byte) (bool, error)

	// IsValidResponse checks if the response is valid for the protocol.
	// This performs basic validation without extracting specific data.
	//
	// Parameters:
	//   - request: Original request bytes (to identify method)
	//   - response: Response bytes to parse
	//
	// Returns:
	//   - true if response is valid (correct format, no errors)
	//   - false if response is invalid (malformed, contains error)
	//   - Error if validation fails unexpectedly
	IsValidResponse(request []byte, response []byte) (bool, error)
}

DataExtractor defines how endpoint quality data is extracted from responses. All QoS services (EVM, Cosmos, Solana, generic) implement this interface.

This interface enables:

  • Hardcoded extractors: Know exactly how to parse their protocol's responses
  • Dynamic extractors: Use configurable rules for unknown protocols

type ExtractedData

type ExtractedData struct {
	// BlockHeight is the latest block number (0 if not extracted).
	BlockHeight int64

	// InvalidBlockHeight is set when block height extraction was attempted
	// but the supplier returned an unparseable result (e.g. "result":[] or "result":{}).
	// When true, the endpoint should be marked with block height 0 so the
	// block height filter catches it, rather than treating it as "unknown".
	InvalidBlockHeight bool

	// ChainID is the chain identifier (empty if not extracted).
	ChainID string

	// IsSyncing indicates if the endpoint is syncing.
	IsSyncing bool

	// IsArchival indicates if the endpoint supports archival queries.
	// Only meaningful when ArchivalCheckPerformed is true.
	IsArchival bool

	// ArchivalCheckPerformed indicates whether an archival check was actually performed.
	// When true, IsArchival contains a definitive result (true or false).
	// When false, IsArchival should be ignored (request wasn't an archival query).
	ArchivalCheckPerformed bool

	// IsValidResponse indicates if the response was valid.
	IsValidResponse bool

	// ResponseTime is how long the request took.
	ResponseTime time.Duration

	// EndpointAddr identifies the endpoint that responded.
	EndpointAddr protocol.EndpointAddr

	// HTTPStatusCode is the HTTP status code from the response.
	HTTPStatusCode int

	// RawResponse is the original response bytes (for re-parsing if needed).
	RawResponse []byte

	// ExtractionErrors holds any errors that occurred during extraction.
	// Map from field name (e.g., "block_height") to error message.
	ExtractionErrors map[string]string
}

ExtractedData holds all data extracted from a response. This is the result of running all extractors on a response.

func NewExtractedData

func NewExtractedData(endpointAddr protocol.EndpointAddr, statusCode int, response []byte, latency time.Duration) *ExtractedData

NewExtractedData creates a new ExtractedData with defaults.

func (*ExtractedData) ExtractAll

func (ed *ExtractedData) ExtractAll(extractor DataExtractor, request []byte)

ExtractAll runs all extractors and populates the ExtractedData. Errors are captured in ExtractionErrors rather than returned directly, allowing partial extraction even when some fields fail.

func (*ExtractedData) ExtractWithConfig

func (ed *ExtractedData) ExtractWithConfig(extractor DataExtractor, request []byte, config ExtractionConfig)

ExtractWithConfig runs extractions based on the provided config.

func (*ExtractedData) HasErrors

func (ed *ExtractedData) HasErrors() bool

HasErrors returns true if any extraction errors occurred.

type ExtractionConfig

type ExtractionConfig struct {
	// ExtractBlockHeight enables block height extraction.
	ExtractBlockHeight bool

	// ExtractChainID enables chain ID extraction.
	ExtractChainID bool

	// CheckSyncStatus enables sync status checking.
	CheckSyncStatus bool

	// CheckArchival enables archival status checking.
	CheckArchival bool

	// ValidateResponse enables response validation.
	ValidateResponse bool
}

ExtractionConfig configures which extractions to run. Used to skip extractions that aren't relevant for a given check.

func DefaultExtractionConfig

func DefaultExtractionConfig() ExtractionConfig

DefaultExtractionConfig returns a config with all extractions enabled.

type ExtractorRegistry

type ExtractorRegistry struct {
	// contains filtered or unexported fields
}

ExtractorRegistry maps service IDs to their DataExtractor implementations. This enables the hot path to be completely service-agnostic, with service-specific parsing deferred to async workers.

Thread-safe for concurrent reads/writes.

func NewExtractorRegistry

func NewExtractorRegistry() *ExtractorRegistry

NewExtractorRegistry creates a new registry with a NoOp fallback.

func (*ExtractorRegistry) Count

func (r *ExtractorRegistry) Count() int

Count returns the number of registered extractors.

func (*ExtractorRegistry) Get

Get returns the DataExtractor for a service ID. Returns the fallback (NoOp) extractor if the service is not registered.

func (*ExtractorRegistry) Has

func (r *ExtractorRegistry) Has(serviceID protocol.ServiceID) bool

Has returns true if a service ID has a registered extractor.

func (*ExtractorRegistry) List

func (r *ExtractorRegistry) List() []protocol.ServiceID

List returns all registered service IDs.

func (*ExtractorRegistry) Register

func (r *ExtractorRegistry) Register(serviceID protocol.ServiceID, extractor DataExtractor)

Register adds a DataExtractor for a service ID. Overwrites any existing extractor for the same service.

func (*ExtractorRegistry) RegisterMultiple

func (r *ExtractorRegistry) RegisterMultiple(extractors map[protocol.ServiceID]DataExtractor)

RegisterMultiple adds multiple DataExtractors at once. Useful for bulk registration during initialization.

func (*ExtractorRegistry) SetFallback

func (r *ExtractorRegistry) SetFallback(extractor DataExtractor)

SetFallback sets the fallback extractor for unknown services. By default, this is a NoOpDataExtractor.

type NoOpDataExtractor

type NoOpDataExtractor struct{}

NoOpDataExtractor is a passthrough extractor that doesn't parse responses. Used for:

  • Services explicitly configured as "passthrough"
  • Unknown services (fallback)
  • Services where response parsing isn't needed or possible

func NewNoOpDataExtractor

func NewNoOpDataExtractor() *NoOpDataExtractor

NewNoOpDataExtractor creates a new NoOp data extractor.

func (*NoOpDataExtractor) ExtractBlockHeight

func (e *NoOpDataExtractor) ExtractBlockHeight(_, _ []byte) (int64, error)

ExtractBlockHeight returns an error indicating extraction is not supported.

func (*NoOpDataExtractor) ExtractChainID

func (e *NoOpDataExtractor) ExtractChainID(_, _ []byte) (string, error)

ExtractChainID returns an error indicating extraction is not supported.

func (*NoOpDataExtractor) IsArchival

func (e *NoOpDataExtractor) IsArchival(_, _ []byte) (bool, error)

IsArchival returns an error indicating extraction is not supported.

func (*NoOpDataExtractor) IsSyncing

func (e *NoOpDataExtractor) IsSyncing(_, _ []byte) (bool, error)

IsSyncing returns an error indicating extraction is not supported.

func (*NoOpDataExtractor) IsValidResponse

func (e *NoOpDataExtractor) IsValidResponse(_, response []byte) (bool, error)

IsValidResponse returns true for any non-empty response. This is the only method that provides a meaningful result for NoOp. A response is considered "valid" if it has content.

Jump to

Keyboard shortcuts

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