heuristic

package
v1.0.21 Latest Latest
Warning

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

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

Documentation

Overview

Package heuristic provides lightweight response analysis to detect errors before full JSON parsing, enabling faster retry decisions.

The package implements a tiered analysis approach:

  • Tier 1: Structural checks (empty, HTML, non-JSON)
  • Tier 2: Protocol-specific success indicators
  • Tier 3: Common error pattern detection

This allows the gateway to quickly identify likely-error responses and trigger retries without the latency cost of full JSON parsing.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ErrorContainsArchivalPattern

func ErrorContainsArchivalPattern(errStr string) bool

ErrorContainsArchivalPattern checks if an error string contains any archival-related or capability-limitation pattern. This is a fallback for when the structured heuristic AnalysisResult is not available (e.g., protocol-layer errors propagated through the hedge_failed path).

func HasErrorField

func HasErrorField(prefix []byte) bool

HasErrorField checks if the response prefix contains an error field. Works for both JSON-RPC and REST responses.

func IsArchivalRelatedError

func IsArchivalRelatedError(pattern string) bool

IsArchivalRelatedError returns true if the indicator pattern is an archival/pruning error. These errors are expected from non-archival nodes and should NOT trigger domain-level circuit breaking — the domain isn't broken, it just doesn't have historical state. Retrying on a different (archival-capable) supplier is correct, but punishing the domain for a capability mismatch causes death spirals where all domains get locked out.

func IsCapabilityLimitationError

func IsCapabilityLimitationError(pattern string) bool

IsCapabilityLimitationError returns true if the pattern indicates a node capability limitation rather than a broken domain. These include archival errors AND other capability mismatches like Tron lite fullnodes that can't serve certain API calls. The request should retry on a different supplier but should NOT circuit-break the domain.

func IsJSONRPCLikeSuccess

func IsJSONRPCLikeSuccess(prefix []byte) bool

IsJSONRPCLikeSuccess provides a quick check for JSON-RPC success. This is a simplified version for callers who just need a boolean.

func QuickErrorCheck

func QuickErrorCheck(contentLower []byte) bool

QuickErrorCheck performs a fast check for obvious error indicators. This is a simplified version that only checks the most common patterns. Use this when you need maximum speed and can tolerate some false negatives.

Cost: O(n) single pass Time: ~1-2μs for 512 byte content

func ShouldRetry

func ShouldRetry(responseBytes []byte, httpStatusCode int, rpcType sharedtypes.RPCType, jsonrpcMethod string) bool

ShouldRetry returns the retry recommendation using the default analyzer.

Types

type AnalysisResult

type AnalysisResult struct {
	// ShouldRetry indicates whether the response suggests a retry is warranted.
	ShouldRetry bool

	// Confidence represents how confident the analysis is (0.0 to 1.0).
	// Higher values indicate more certainty that the response is an error.
	Confidence float64

	// Reason provides a machine-readable classification of why retry is suggested.
	Reason string

	// Structure contains the structural classification of the response.
	Structure ResponseStructure

	// Details provides additional human-readable context for debugging.
	Details string

	// MatchedPattern is the specific error pattern that matched (from Tier 3 indicator analysis).
	// Empty for non-indicator results.
	MatchedPattern string
}

AnalysisResult contains the outcome of heuristic response analysis.

func Analyze

func Analyze(responseBytes []byte, httpStatusCode int, rpcType sharedtypes.RPCType, jsonrpcMethod string) AnalysisResult

Analyze performs heuristic analysis using the default analyzer.

func AnalyzeQuick

func AnalyzeQuick(responseBytes []byte, httpStatusCode int) AnalysisResult

AnalyzeQuick performs a fast heuristic check using the default analyzer.

func CheckRequestIDMismatch added in v1.0.16

func CheckRequestIDMismatch(responsePrefix []byte, requestID string) *AnalysisResult

CheckRequestIDMismatch detects fabricated responses by comparing the response ID to the original request ID. JSON-RPC 2.0 spec requires the response ID to match the request ID. A response with "id":null when the request had a real ID proves the response was fabricated by the supplier's relay miner, not the actual node.

Returns an AnalysisResult if a mismatch is detected, nil otherwise.

func IndicatorAnalysisToResult

func IndicatorAnalysisToResult(ir IndicatorResult) AnalysisResult

IndicatorAnalysisToResult converts an IndicatorResult to an AnalysisResult.

func ProtocolAnalysis

func ProtocolAnalysis(prefix []byte, fullLength int, rpcType sharedtypes.RPCType, jsonrpcMethod string) AnalysisResult

ProtocolAnalysis performs Tier 2 protocol-specific analysis. It checks whether the response contains expected success indicators for the given RPC type.

Parameters:

  • prefix: First N bytes of the response (typically 512)
  • fullLength: Total length of the response
  • rpcType: The protocol type for specific validation

Cost: O(n) where n is prefix length Time: ~1-3μs for 512 byte prefix

func StructuralAnalysis

func StructuralAnalysis(responseBytes []byte) AnalysisResult

StructuralAnalysis performs Tier 1 analysis and returns a result. This is the entry point for structural-only analysis.

type Analyzer

type Analyzer interface {
	// Analyze performs heuristic analysis on a response to determine if it's likely an error.
	// Parameters:
	//   - responseBytes: The raw response payload
	//   - httpStatusCode: The HTTP status code from the endpoint
	//   - rpcType: The RPC type for protocol-specific analysis
	//   - jsonrpcMethod: The JSON-RPC method name for method-aware checks (e.g., "eth_blockNumber").
	//     Empty string means unknown/non-JSON-RPC — method-aware checks are skipped.
	//
	// Returns an AnalysisResult with retry recommendation and confidence level.
	Analyze(responseBytes []byte, httpStatusCode int, rpcType sharedtypes.RPCType, jsonrpcMethod string) AnalysisResult
}

Analyzer defines the interface for heuristic response analysis.

type AnalyzerConfig

type AnalyzerConfig struct {
	// MaxPrefixBytes is the maximum number of bytes to inspect for heuristics.
	// Default: 512 bytes. Larger values may catch more edge cases but cost more CPU.
	MaxPrefixBytes int

	// ConfidenceThreshold is the minimum confidence level to suggest retry.
	// Default: 0.5. Set higher for fewer false positives, lower for more aggressive retries.
	ConfidenceThreshold float64

	// EnableTier3 controls whether error indicator pattern matching is performed.
	// Default: true. Disable if you want only structural and protocol checks.
	EnableTier3 bool
}

AnalyzerConfig holds configuration options for the response analyzer.

func DefaultConfig

func DefaultConfig() AnalyzerConfig

DefaultConfig returns the default analyzer configuration.

type ErrorCategory

type ErrorCategory int

ErrorCategory represents the type of error detected.

const (
	// CategoryNone indicates no error pattern was detected.
	CategoryNone ErrorCategory = iota
	// CategoryHTTPError indicates an HTTP-level error message.
	CategoryHTTPError
	// CategoryConnectionError indicates a connection/network error.
	CategoryConnectionError
	// CategoryRateLimit indicates rate limiting.
	CategoryRateLimit
	// CategoryAuthError indicates authentication/authorization error.
	CategoryAuthError
	// CategoryServiceError indicates a service-level error.
	CategoryServiceError
	// CategoryBlockchainError indicates a blockchain-specific error.
	CategoryBlockchainError
	// CategoryProtocolError indicates a protocol-level error.
	CategoryProtocolError
)

func (ErrorCategory) String

func (ec ErrorCategory) String() string

String returns a human-readable representation of the ErrorCategory.

type IndicatorResult

type IndicatorResult struct {
	// Found indicates whether an error pattern was detected.
	Found bool
	// Category is the type of error detected.
	Category ErrorCategory
	// Pattern is the specific pattern that matched.
	Pattern string
	// Confidence is how confident we are this indicates an error.
	Confidence float64
}

IndicatorResult contains the result of error indicator analysis.

func IndicatorAnalysis

func IndicatorAnalysis(content []byte, alreadyLowercased bool) IndicatorResult

IndicatorAnalysis performs Tier 3 error indicator pattern matching. It searches for known error patterns in the response content.

Parameters:

  • content: Response content to analyze (should be lowercased for efficiency)
  • alreadyLowercased: Set to true if content is already lowercase

Cost: O(n*m) where n is content length and m is number of patterns Time: ~3-10μs for 512 byte content

type ResponseAnalyzer

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

ResponseAnalyzer implements the Analyzer interface using a tiered approach. It combines structural, protocol-specific, and indicator-based analysis to determine if a response is likely an error.

func NewAnalyzer

func NewAnalyzer(config AnalyzerConfig) *ResponseAnalyzer

NewAnalyzer creates a new ResponseAnalyzer with the given configuration.

func NewDefaultAnalyzer

func NewDefaultAnalyzer() *ResponseAnalyzer

NewDefaultAnalyzer creates a new ResponseAnalyzer with default configuration.

func (*ResponseAnalyzer) Analyze

func (ra *ResponseAnalyzer) Analyze(responseBytes []byte, httpStatusCode int, rpcType sharedtypes.RPCType, jsonrpcMethod string) AnalysisResult

Analyze performs comprehensive heuristic analysis on a response. It uses a tiered approach, short-circuiting as soon as a definitive result is found:

  1. HTTP Status Check (free) - 4xx/5xx always indicates error
  2. Tier 1: Structural Analysis - Empty, HTML, non-JSON
  3. Tier 2: Protocol Analysis - JSON-RPC result/error fields
  4. Tier 3: Indicator Analysis - Error pattern matching

Returns an AnalysisResult with retry recommendation and confidence.

func (*ResponseAnalyzer) AnalyzeQuick

func (ra *ResponseAnalyzer) AnalyzeQuick(responseBytes []byte, httpStatusCode int) AnalysisResult

AnalyzeQuick performs a fast heuristic check with minimal processing. Use this when you need maximum speed and can accept lower accuracy.

This performs:

  1. HTTP status check
  2. Empty/first-byte check
  3. Quick error pattern scan

Cost: O(n) single pass on prefix Time: ~2-5μs

func (*ResponseAnalyzer) ShouldRetry

func (ra *ResponseAnalyzer) ShouldRetry(responseBytes []byte, httpStatusCode int, rpcType sharedtypes.RPCType, jsonrpcMethod string) bool

ShouldRetry is a convenience method that returns just the retry decision.

type ResponseStructure

type ResponseStructure int

ResponseStructure classifies the structural type of a response.

const (
	// StructureValid indicates the response has valid JSON structure.
	StructureValid ResponseStructure = iota
	// StructureEmpty indicates an empty response (0 bytes).
	StructureEmpty
	// StructureHTML indicates the response is HTML (likely an error page).
	StructureHTML
	// StructureXML indicates the response is XML (unexpected for JSON APIs).
	StructureXML
	// StructureNonJSON indicates the response is plain text (not JSON).
	StructureNonJSON
	// StructureMalformed indicates the response starts like JSON but appears malformed.
	StructureMalformed
)

func ClassifyStructure

func ClassifyStructure(responseBytes []byte) ResponseStructure

ClassifyStructure performs Tier 1 structural analysis on the response. It determines what type of content the response contains based on its structure, without parsing the full content.

Cost: O(1) - only inspects first few bytes Time: < 1μs typically

func (ResponseStructure) String

func (rs ResponseStructure) String() string

String returns a human-readable representation of the ResponseStructure.

Jump to

Keyboard shortcuts

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