Tags: lavanet/lava
Tags
feat(consumer): per-chain latency cutoff for random provider selection ( #2314) * feat(consumer): per-chain latency cutoff for random provider selection Adds an optional per-endpoint QoS latency cutoff (MaxProviderLatency, in seconds) to RPCEndpoint. During the general random/weighted provider selection, providers whose EWMA latency exceeds the cutoff are put aside via the existing ignored-providers set, so the optimizer never picks them. Includes a safety fallback: the cutoff is applied only if at least one candidate stays under the threshold; otherwise the full pool is kept so relays keep flowing when the whole pairing is slow. Cold-start providers (no QoS data) are treated as under-threshold. Static, header-selected, sticky and stateful selection paths are unaffected. No optimizer/interface changes; the setting rides on csm.rpcEndpoint. 0 (default) disables the cutoff. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(consumer): unit tests + docs for per-chain latency cutoff Adds focused unit tests for filterHighLatencyProviders covering: excluding slow providers, keeping fast ones, the all-slow safety fallback, disabled cutoff (0), cold-start (no QoS) handling, preserving pre-existing ignored entries, strict ">" threshold boundary, multi-provider filtering, and a mixed cold-start/slow/fast case. Documents max-provider-latency in the rpcconsumer README and adds a commented example to config/rpcconsumer.yml. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(consumer): integration tests + live E2E harness for latency cutoff Go tests: - consumer_session_manager_latency_selection_test.go: drives getValidProviderAddresses through a stub optimizer to prove the cutoff applies only to the general random path (sticky/stateful/selected-provider paths are unaffected). - rpcconsumer_endpoints_test.go: verifies max-provider-latency parses from the YAML endpoints config into RPCEndpoint (0/omitted => disabled). Live E2E (full env: dev chain + mock-backed providers + consumer): - scripts/pre_setups/init_eth_latency_cutoff.sh: brings up 3 ETH1 providers, each behind its own mock RPC backend; one mock is slowed so its provider exceeds the cutoff. Modes: cutoff | regression-disabled | regression-fallback. - scripts/test/verify_latency_cutoff.sh: drives relays and asserts on the lava_consumer_provider_selections metric per mode. - scripts/test/e2e_latency_cutoff.sh: one-command runner (setup -> wait -> verify -> teardown). - config/eth_latency_cutoff_consumer{,_disabled}.yml: the two consumer configs (cutoff 1.0 and disabled 0) selected by mode. The mock RPC server is left untouched; providers use --use-static-spec with a verification-stripped ETH1 spec so they accept the mock backend while still proxying real (latency-bearing) relays. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style(consumer): gofmt latency selection test stub methods Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * log change --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
fix(chainlib): tolerate non-scalar JSON-RPC request ids in id validat… …ion (#2302) * fix(chainlib): tolerate non-scalar JSON-RPC request ids in id validation ValidateRequestAndResponseIds parsed the request id before reaching the "null/empty response id" carve-out. A client that sends a non-scalar id (object/array) — invalid per JSON-RPC 2.0, e.g. a .NET CancellationToken serialized into the id — therefore hard-failed with "failed parsing ID", which lavap surfaces as "jsonRPC ID mismatch / insufficient results" plus a cross-provider retry storm, even when the relay itself was fine. Captured against live nodes: Polygon rejects the object id and replies id:null; NEAR accepts it, returns a valid result, and echoes the object id back. Both were being failed. - Check the null/empty/[] response-id carve-out first, before parsing the request id (covers Polygon's id:null rejection). - When either id is non-scalar, compare ids semantically (whitespace/key-order tolerant) instead of erroring (covers NEAR's verbatim echo, preserving the valid response). A genuinely different id is still reported as a mismatch. Scalar id behaviour is unchanged. Root cause is a non-compliant client; this makes lavap surface the node's real response instead of masking it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(chainlib): end-to-end coverage for non-scalar JSON-RPC request id Drives the real ParseMsg -> SendNodeMsg path against a mock node with an object request id, covering both observed node behaviours: a NEAR-like node that echoes the id and returns a valid result (must be returned, not discarded), and a Polygon-like node that rejects with id:null + "invalid request" (must pass through, not become an "ID mismatch" / retry storm). Complements the ValidateRequestAndResponseIds unit test by asserting the full relay outcome. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feat: support multiple --use-static-spec sources with aggregation (#2225 ) Allow --use-static-spec flag to be specified multiple times, aggregating specs from local files, directories, GitHub, and GitLab repositories. When the same chain ID appears in multiple sources, the later source completely replaces the earlier spec (full replacement, not merge). Changes: - Change --use-static-spec from String to StringArray flag type - Add spec aggregation logic with last-wins override semantics - Support comma-separated local file paths (file1.json,file2.json) - Add helper functions for loading all specs from various sources - Add comprehensive tests for aggregation behavior - Remove unused GetSpecsFromPath function Multiple local files can be specified either as separate flags or comma-separated: --use-static-spec file1.json --use-static-spec file2.json --use-static-spec file1.json,file2.json Co-authored-by: Cursor <cursoragent@cursor.com>
fix(chainlib): include response error in ID mismatch logs (#2192) When a node returns an error (e.g., "Apikey is expired") with an empty/invalid JSON-RPC ID, the ID validation fails with a confusing parsing error. This adds the actual response error message to the log output, making the root cause immediately visible.
PreviousNext