Skip to content

feat: introducing new WRS algorithm#2224

Merged
nimrod-teich merged 1 commit into
mainfrom
wrs_algo_feature
Feb 22, 2026
Merged

feat: introducing new WRS algorithm#2224
nimrod-teich merged 1 commit into
mainfrom
wrs_algo_feature

Conversation

@AnnaR-prog

Copy link
Copy Markdown
Contributor

Description

Closes: #XXXX


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • read the contribution guide
  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the main branch
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

@AnnaR-prog AnnaR-prog changed the title Wrs algo feature feat: Wrs algo feature Feb 17, 2026
@AnnaR-prog AnnaR-prog changed the title feat: Wrs algo feature feat: introducing new WRS algorithm Feb 17, 2026
@AnnaR-prog AnnaR-prog force-pushed the wrs_algo_feature branch 2 times, most recently from 45b6f32 to ada3215 Compare February 17, 2026 13:31
@codecov

codecov Bot commented Feb 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 41.31702% with 1007 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
protocol/provideroptimizer/provider_optimizer.go 42.27% 131 Missing and 11 partials ⚠️
protocol/metrics/consumer_metrics_manager.go 27.52% 128 Missing and 1 partial ⚠️
protocol/provideroptimizer/weighted_selector.go 72.24% 115 Missing and 11 partials ⚠️
utils/score/adaptive_max_calculator.go 52.53% 89 Missing and 14 partials ⚠️
protocol/rpcprovider/rpcprovider.go 0.00% 96 Missing ⚠️
protocol/lavasession/consumer_session_manager.go 31.35% 77 Missing and 4 partials ⚠️
protocol/metrics/consumer_optimizer_qos_client.go 0.00% 61 Missing ⚠️
utils/score/score_store.go 11.76% 58 Missing and 2 partials ⚠️
protocol/rpcconsumer/rpcconsumer.go 0.00% 46 Missing ⚠️
protocol/rpcsmartrouter/rpcsmartrouter.go 4.16% 46 Missing ⚠️
... and 10 more
Flag Coverage Δ
consensus 8.71% <38.43%> (+0.09%) ⬆️
protocol 34.51% <42.01%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
protocol/common/cobra_common.go 0.00% <ø> (ø)
protocol/common/endpoints.go 0.00% <ø> (ø)
protocol/lavasession/provider_types.go 65.09% <ø> (ø)
protocol/metrics/provider_metrics.go 0.00% <ø> (ø)
protocol/provideroptimizer/selection_weight.go 100.00% <100.00%> (+14.75%) ⬆️
utils/lavalog.go 15.00% <100.00%> (-0.29%) ⬇️
protocol/lavasession/consumer_types.go 76.08% <80.00%> (+4.15%) ⬆️
protocol/parser/parser.go 69.54% <50.00%> (-0.21%) ⬇️
protocol/rpcprovider/rpcprovider_server.go 9.71% <0.00%> (-0.03%) ⬇️
protocol/statetracker/updaters/pairing_updater.go 67.34% <50.00%> (-0.53%) ⬇️
... and 16 more

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Feb 17, 2026

Copy link
Copy Markdown

Test Results

7 files  ±    0  0 suites   - 86   0s ⏱️ - 31m 50s
0 tests  - 3 459  0 ✅  - 3 458  0 💤  - 1  0 ❌ ±0 
0 runs   - 3 685  0 ✅  - 3 684  0 💤  - 1  0 ❌ ±0 

Results for commit d3d9d64. ± Comparison against base commit 1ed0795.

♻️ This comment has been updated with latest results.

@NadavLevi NadavLevi force-pushed the wrs_algo_feature branch 3 times, most recently from b35cc46 to 8d10d7d Compare February 18, 2026 12:36
…e normalization, metrics, and test tooling

This squashes the full `wrs_algo_feature` history into a single change-set on top of `origin/main`.

- Replace legacy tier-based provider selection with a weighted-random selection (WRS) path, including:
  - stake-based weighting, normalization tweaks, and guardrails against invalid/NaN weights
  - block-availability / requested-block gating and related tuning
  - deterministic RNG hooks and stronger concurrency/edge-case test coverage
- Add Phase-2 adaptive normalization for latency/sync parameters (P10–P90 + global T-Digest), plus config/tuning changes.
- Expand consumer/provider selection observability:
  - richer selection stats and logging (incl. NaN/Inf sanitization)
  - missing Prometheus metric registrations + latest-provider-block metric fixes
  - selection-via-header support and related endpoint/header plumbing
- Improve rpcprovider test-mode behavior for deterministic latest_block/head-gap and availability failure simulation; preserve test LatestBlock behavior.
- Add/extend scripts and local tooling for WRS analysis and reproducible test scenarios:
  - WRS analysis helpers + e2e scripts/test data
  - `wrs_tests/` local framework (stake/latency/availability/sync) and analyzers
- Misc hardening/cleanup:
  - avoid nil ParsedInput panic in parser flow
  - log timestamp precision tweaks, gofmt, and assorted test/config updates

- remove comments
- refactor: remove provider optimizer exploration feature
- wrs_tests: add local WRS test framework and static stake support
- feat(analyze): add log analysis script for provider selection metrics
- feat(setup): add init script for static and backup provider configuration
- refactor(provideroptimizer): add context parameter to provider selection methods
- consumer: add probe-update-weight CLI flag
- refactor(weighted_selector): enhance total stake calculation for consistent normalization
- Enable nanosecond precision in log timestamps
- feat(wrs): Fix Test 3 sync testing with deterministic baseline approach
- provideroptimizer: remove block-availability penalty
- feat: Add support for provider selection via header in session management
- fix: simplify consumer startup message in init script
- fix: lava_consumer_latest_provider_block metric showing 0
- fix: Register missing metrics (latestBlockMetric, qosMetric, providerReputationMetric) with Prometheus
- feat: Enable QoS optimizer improvements in init script
- feat(provider_setup): enhance ETH RPC configuration and validation
- refactor(provider_optimizer): update provider selection metrics logging
- feat(metrics): improve validation and handling of adaptive bounds
- test: Optimize Test 3 startup by using tendermintrpc-only provider config
- feat: add Test 3 init script and metrics analysis tool
- feat: enhance WRS logging and metrics with parameter contributions
- feat(metrics): enhance provider selection logging and validation
- feat(metrics): add sanitizeFloat function to handle NaN/Inf values
- feat(metrics): enhance provider selection metrics and tracking
- chore: upgrade T-Digest library to caio/go-tdigest v5.0.0
- chore: add tdigest dependency for Phase 2 adaptive normalization
- feat: enable Phase 2 adaptive normalization (P10-P90 with global T-Digest)
- chore: lower availability threshold from 90% to 80%
- feat: implement square root scaling for stake normalization
- feat: implement Phase 2 P10-P90 adaptive normalization for sync parameter
- refactor: improve adaptive normalization - constants, bounds, and logging
- feat: implement Phase 2 P10-P90 hybrid adaptive normalization for latency
- e2e optimizer: per-provider test inputs + preserve test LatestBlock under DR
- feat(metrics): enhance provider selection metrics tracking
- rpcprovider test_mode: availability probability with grpc failure
- rpcprovider test_mode: deterministic head/gap latest_block + delay controls
- chore: gofmt
- feat(provideroptimizer): add selection statistics for provider selection
- test(provideroptimizer): add weighted selector edge-case + concurrency tests
- fixes after rebase
- test(provideroptimizer): stabilize availability selection test
- test(provideroptimizer): cover NaN/Inf weight configs
- fix(provideroptimizer): harden weighted selector weight validation
- fix: prevent divide-by-zero panic in WeightedSelector initialization
- tune(provideroptimizer): lower default MinSelectionChance
- fix(provideroptimizer): align selector normalization with clamp
- fix(provideroptimizer): correct requestedBlock Poisson gating
- feat: Implement block availability calculation for provider selection
- Updated tests
- Updated default weights
- Removed dead code
- Enhance tests with deterministic behavior and error handling improvements
- Refactor provider optimizer to support deterministic seed for testing
- Enhance WeightedSelector with customizable random number generation
- Refactor provider optimizer initialization to remove unused parameter
- Refactor provider selection mechanism to remove tier-based logic and enhance weighted selection
- test: Enhance provider optimizer tests for statistical validation
- test: Refine provider optimizer tests for deterministic behavior
- test: Enhance provider optimizer tests for extreme latency scenarios
- test: Update provider optimizer tests for weighted selection logic
- refactor: Remove legacy tier-based selection and streamline provider optimization
- feat: Implement weighted provider selection system
- protocol/parser: avoid nil ParsedInput panic in generic parser flow
- chore: Update lava_consumer_static_with_backup.yml for provider configuration

Co-authored-by: Cursor <cursoragent@cursor.com>
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Implement Weighted Random Selection (WRS) algorithm for provider optimization

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Replaced tier-based provider selection mechanism with a new Weighted Random Selection (WRS)
  algorithm for improved QoS-aware provider selection
• Implemented WeightedSelector component that calculates composite scores based on availability,
  latency, sync, and stake metrics with configurable weights
• Added AdaptiveMaxCalculator using T-Digest with exponential decay for adaptive P10-P90
  normalization of latency and sync metrics
• Introduced ProviderStakeCache to maintain provider stake amounts for selection algorithms
• Integrated selection statistics tracking throughout the consumer session flow with metrics
  reporting via SetProviderSelected() and StartSelectionStatsUpdater()
• Updated RPC consumer and smart router to use weighted selector configuration with new flags for
  availability, latency, sync, and stake weights
• Added test mode support to RPC provider with artificial delay, availability probability, and
  latest block configuration
• Refactored all provider optimizer tests to validate weighted selection probabilities instead of
  tier membership
• Updated consumer session manager and end-to-end tests to use new method signatures supporting
  forced provider selection via headers
• Removed legacy tier-based selection logic, tier configuration variables, and exploration mechanism
• Added comprehensive test coverage for weighted selector, adaptive calculator, and selection
  statistics
Diagram
flowchart LR
  A["Provider QoS Metrics<br/>availability, latency,<br/>sync, stake"] -->|"normalize with<br/>AdaptiveMaxCalculator"| B["Normalized Scores"]
  B -->|"calculate composite<br/>score"| C["WeightedSelector"]
  C -->|"weighted random<br/>selection"| D["Selected Provider"]
  D -->|"track stats"| E["Selection Statistics"]
  E -->|"update metrics"| F["Consumer Metrics"]
  G["ProviderStakeCache"] -->|"provide stake<br/>amounts"| C
Loading

Grey Divider

File Changes

1. protocol/provideroptimizer/provider_optimizer_test.go 🧪 Tests +625/-683

Migrate provider optimizer tests to weighted random selection algorithm

• Refactored tests to use weighted random selection algorithm instead of tier-based selection
• Replaced ChooseProvider calls to accept context.Background() as first parameter and removed
 tier return values
• Updated test assertions to validate weighted selection probabilities rather than tier membership
• Added SetDeterministicSeed() calls for deterministic test behavior and removed global
 rand.InitRandomSeed() calls
• Removed tier-based test logic (CalculateSelectionTiers, GetTier, ShiftTierChance) and
 replaced with direct selection count validation
• Added new tests for block availability calculation (TestCalculateBlockAvailability,
 TestHistoricalQuerySelectionDistribution, TestLatestBlockRequestIgnoresSync,
 TestProviderOptimizerBlockAvailabilityIntegration)
• Simplified test helper runChooseManyTimesAndReturnResults to return only selection counts
 instead of tier results
• Updated latency and sync test scenarios to use more extreme differences for deterministic weighted
 selection outcomes

protocol/provideroptimizer/provider_optimizer_test.go


2. protocol/lavasession/consumer_session_manager_test.go 🧪 Tests +36/-34

Update consumer session manager test method signatures

• Updated GetSessions method calls to include two additional empty string parameters
• Modified CreateConsumerSessionManager helper to use SetDeterministicSeed() instead of global
 rand.InitRandomSeed()
• Updated getValidProviderAddresses method calls with additional empty string parameters
• Consistent parameter signature changes across all test functions that call session management
 methods

protocol/lavasession/consumer_session_manager_test.go


3. protocol/lavasession/end_to_end_lavasession_test.go 🧪 Tests +3/-3

Update end-to-end session test method signatures

• Updated all GetSessions method calls to include two additional empty string parameters at the
 end
• Changes applied consistently across TestHappyFlowE2EEmergency,
 TestHappyFlowEmergencyInConsumer, and prepareSessionsWithFirstRelay functions

protocol/lavasession/end_to_end_lavasession_test.go


View more (105)
4. protocol/provideroptimizer/provider_optimizer.go ✨ Enhancement +402/-269

Replace tier-based selection with weighted random selection algorithm

• Replaced tier-based provider selection with weighted random selection (WRS) algorithm
• Removed tier-related configuration variables and exploration mechanism
• Added global adaptive calculators for P10-P90 latency and sync normalization
• Introduced ProviderStakeCache and WeightedSelector for improved provider scoring
• Refactored ChooseProvider methods to use context and return selection statistics
• Implemented calculateBlockAvailability using Poisson distribution for block sync probability
• Updated NewProviderOptimizer constructor to initialize weighted selector and adaptive
 calculators

protocol/provideroptimizer/provider_optimizer.go


5. protocol/provideroptimizer/weighted_selector.go ✨ Enhancement +895/-0

New weighted random selection algorithm implementation

• New file implementing WeightedSelector for continuous weighted random selection based on QoS
 scores
• Implements normalization functions for availability, latency, sync, and stake metrics
• Supports Phase 2 adaptive P10-P90 normalization via T-Digest for better score distribution
• Provides strategy-specific score adjustments (latency, sync, accuracy, distributed)
• Includes deterministic RNG support for testing via SetDeterministicSeed
• Calculates composite scores combining all QoS metrics with configurable weights

protocol/provideroptimizer/weighted_selector.go


6. protocol/provideroptimizer/weighted_selector_test.go 🧪 Tests +781/-0

Complete test coverage for weighted selector implementation

• Comprehensive test suite for WeightedSelector with 30+ test cases
• Tests weight normalization, score calculation, and selection distribution
• Validates strategy-specific adjustments and edge cases (zero scores, equal scores, concurrent
 access)
• Includes benchmarks for score calculation, provider selection, and full pipeline
• Tests adaptive bounds handling and QoS report generation

protocol/provideroptimizer/weighted_selector_test.go


7. protocol/rpcconsumer/rpcconsumer.go ✨ Enhancement +58/-19

Integrate weighted selector configuration into RPC consumer

• Added weightedSelectorConfig to rpcConsumerStartOptions struct
• Integrated weighted selector configuration flags for availability, latency, sync, and stake
 weights
• Added probe update weight configuration and selection stats header flag
• Removed legacy tier-based optimizer flags (tier count, tier chances, auto-adjust tiers)
• Updated optimizer initialization to use new ConfigureWeightedSelector method
• Added periodic selection stats metrics updates via StartSelectionStatsUpdater

protocol/rpcconsumer/rpcconsumer.go


8. protocol/lavasession/consumer_session_manager.go ✨ Enhancement +166/-48

WRS algorithm integration with selection stats tracking

• Added thread-safe storage for latest selection stats with selectionStatsLock and
 latestSelectionStats fields
• Implemented IsStaticProvider() method to check if a provider is static (used by WS
 subscriptions)
• Changed UpdateWeights() call from async to synchronous to ensure early relays see correct stake
 values
• Added selectedProvider parameter throughout the provider selection flow to support forced
 provider selection via headers
• Integrated selection stats tracking with metrics, converting stats to metrics format and updating
 provider selection counters
• Added helper methods setSelectionStats() and GetSelectionStats() for thread-safe access to
 selection statistics
• Removed static provider connection closing logic from closePurgedUnusedPairingsConnections() to
 preserve shared endpoints
• Updated provider selection to use new ChooseBestProviderWithStats() and
 ChooseProviderWithStats() methods that return selection statistics

protocol/lavasession/consumer_session_manager.go


9. protocol/rpcsmartrouter/rpcsmartrouter.go ✨ Enhancement +68/-21

Weighted selector configuration and static provider stake handling

• Added weightedSelectorConfig to rpcSmartRouterStartOptions for configurable provider selection
 weights
• Changed StaticProviderDummyCoin from 1 ulava to 0 ulava to enable legacy static provider boost
 behavior
• Added support for explicit stake configuration in static providers with fallback to legacy boost
• Integrated weighted selector configuration with new flags for availability, latency, sync, and
 stake weights
• Added EnableSelectionStats flag and started periodic selection stats metrics updates
• Removed old optimizer tier-based flags (ATierChance, LastTierChance, OptimizerNumTiers, etc.)
• Added new probe update weight flag and configuration for weighted selector
• Updated static provider session creation to use configured stake or dummy coin based on
 configuration

protocol/rpcsmartrouter/rpcsmartrouter.go


10. protocol/metrics/consumer_metrics_manager.go ✨ Enhancement +276/-1

Provider selection metrics and score tracking implementation

• Added new metrics for provider selection scores (availability, latency, sync, stake, composite)
• Implemented SetProviderSelected() method to record provider selections and update all provider
 score gauges
• Added StartSelectionStatsUpdater() background goroutine for periodic selection stats metrics
 updates
• Created ProviderSelectionScores struct to hold all scores for a provider at selection time
• Added SetSelectionStatsMetrics() method to set individual selection stat metrics
• Implemented UpdateSelectionStatsFromOptimizerReports() to sync optimizer reports with metrics
• Added provider selection counter metric to track total selections per provider
• Added RNG value gauge to track randomness used in provider selection

protocol/metrics/consumer_metrics_manager.go


11. utils/score/adaptive_max_calculator_test.go 🧪 Tests +459/-0

Adaptive max calculator test suite with decay validation

• Comprehensive test suite for AdaptiveMaxCalculator with 13 test cases covering basic
 functionality, decay, clamping, and edge cases
• Tests verify exponential decay formula matches ScoreStore implementation
• Tests validate P10-P90 bounds calculation for adaptive normalization (Phase 2 hybrid approach)
• Tests include large dataset handling (900 samples), nil handling, and distribution statistics
• Tests verify stats output includes all required fields and percentiles

utils/score/adaptive_max_calculator_test.go


12. protocol/rpcprovider/rpcprovider.go ✨ Enhancement +120/-103

Test mode chain setup and health check handling

• Added test mode support to skip chain proxy and chain fetcher setup when rpcp.testMode is
 enabled
• Refactored chain setup logic into conditional branches for test mode vs. production mode
• Test mode uses NewTestModeChainRouter() and DummyChainTracker instead of real node connections
• Disabled relays health checks in test mode since they require real node connections
• Preserved all production mode logic while adding clean separation for test mode initialization

protocol/rpcprovider/rpcprovider.go


13. utils/score/adaptive_max_calculator.go ✨ Enhancement +421/-0

Adaptive max calculator with T-Digest and exponential decay

• Implemented AdaptiveMaxCalculator using T-Digest with exponential decay for adaptive
 normalization
• Supports both P95-only (deprecated) and P10-P90 bounds approaches for latency normalization
• Implements exponential decay formula matching ScoreStore for consistent weighting across
 components
• Provides GetAdaptiveMax() for 95th percentile and GetAdaptiveBounds() for P10-P90 range
• Includes comprehensive statistics via GetStats() and distribution logging via
 LogDistributionStats()
• Thread-safe implementation with mutex protection for concurrent access
• Handles edge cases: nil calculator, negative samples, old samples, and clamping to configured
 bounds

utils/score/adaptive_max_calculator.go


14. protocol/rpcprovider/provider_state_machine.go ✨ Enhancement +117/-3

Test mode response generation with availability and delay

• Added generateTestResponseWithAvailability() wrapper to gate test responses on availability
 probability
• Returns gRPC Unavailable error when request falls into unavailable bucket for proper failure
 tracking
• Added artificial delay support with DelayMs and DelayJitterMs per-method configuration
• Implemented sleepWithContext() to respect context deadlines when applying delays
• Added LatestBlock and LatestBlockJitter configuration with provider-level fallback
 (HeadBlock/GapBlocks)
• Added helper functions clampProb01() and clampNonNegativeInt64() for input validation
• Preserved gRPC status errors without wrapping to maintain stable failure codes for consumers

protocol/rpcprovider/provider_state_machine.go


15. protocol/provideroptimizer/selection_weight.go Refactoring +25/-108

Provider stake cache refactoring and selection logic separation

• Refactored SelectionWeighter interface to ProviderStakeCache for clearer responsibility
 separation
• Removed QoS-based selection logic (inverse score weighting) from this file
• Removed stake-weighted selection logic from this file
• Simplified to focus solely on maintaining provider stake amounts for selection algorithms
• Renamed implementation from selectionWeighterInst to providerStakeCacheInst
• Reduced interface to three methods: GetStake(), UpdateStakes(), and internal getStakeInner()

protocol/provideroptimizer/selection_weight.go


16. .github/workflows/lava.yml Additional files +40/-7

...

.github/workflows/lava.yml


17. WRS_ENHANCED_LOGGING_AND_METRICS.md Additional files +439/-0

...

WRS_ENHANCED_LOGGING_AND_METRICS.md


18. config/consumer_examples/lava_consumer_static_with_backup.yml Additional files +6/-0

...

config/consumer_examples/lava_consumer_static_with_backup.yml


19. config/provider_examples/provider1_test3_tendermintrpc_only.yml Additional files +13/-0

...

config/provider_examples/provider1_test3_tendermintrpc_only.yml


20. go.mod Additional files +1/-0

...

go.mod


21. go.sum Additional files +4/-0

...

go.sum


22. protocol/chainlib/chainlib.go Additional files +17/-0

...

protocol/chainlib/chainlib.go


23. protocol/chainlib/consumer_ws_subscription_manager_test.go Additional files +3/-1

...

protocol/chainlib/consumer_ws_subscription_manager_test.go


24. protocol/common/cobra_common.go Additional files +14/-12

...

protocol/common/cobra_common.go


25. protocol/common/endpoints.go Additional files +3/-0

...

protocol/common/endpoints.go


26. protocol/integration/protocol_test.go Additional files +2/-1

...

protocol/integration/protocol_test.go


27. protocol/lavasession/consumer_types.go Additional files +26/-8

...

protocol/lavasession/consumer_types.go


28. protocol/lavasession/consumer_types_stake_weights_test.go Additional files +87/-0

...

protocol/lavasession/consumer_types_stake_weights_test.go


29. protocol/lavasession/provider_types.go Additional files +4/-0

...

protocol/lavasession/provider_types.go


30. protocol/metrics/consumer_optimizer_qos_client.go Additional files +153/-32

...

protocol/metrics/consumer_optimizer_qos_client.go


31. protocol/metrics/provider_metrics.go Additional files +6/-0

...

protocol/metrics/provider_metrics.go


32. protocol/parser/parser.go Additional files +5/-1

...

protocol/parser/parser.go


33. protocol/provideroptimizer/provider_selection_mechanism_test.go Additional files +0/-361

...

protocol/provideroptimizer/provider_selection_mechanism_test.go


34. protocol/provideroptimizer/selection_tier.go Additional files +0/-245

...

protocol/provideroptimizer/selection_tier.go


35. protocol/provideroptimizer/selection_tier_test.go Additional files +0/-384

...

protocol/provideroptimizer/selection_tier_test.go


36. protocol/provideroptimizer/selection_weight_test.go Additional files +18/-77

...

protocol/provideroptimizer/selection_weight_test.go


37. protocol/rpcconsumer/rpcconsumer_server.go Additional files +16/-2

...

protocol/rpcconsumer/rpcconsumer_server.go


38. protocol/rpcconsumer/rpcconsumer_server_test.go Additional files +2/-1

...

protocol/rpcconsumer/rpcconsumer_server_test.go


39. protocol/rpcprovider/rpcprovider_server.go Additional files +34/-0

...

protocol/rpcprovider/rpcprovider_server.go


40. protocol/rpcprovider/test_mode_consistency_test.go Additional files +106/-0

...

protocol/rpcprovider/test_mode_consistency_test.go


41. protocol/rpcsmartrouter/rpcsmartrouter_server.go Additional files +24/-2

...

protocol/rpcsmartrouter/rpcsmartrouter_server.go


42. protocol/rpcsmartrouter/rpcsmartrouter_server_test.go Additional files +2/-1

...

protocol/rpcsmartrouter/rpcsmartrouter_server_test.go


43. protocol/rpcsmartrouter/rpcsmartrouter_test.go Additional files +2/-1

...

protocol/rpcsmartrouter/rpcsmartrouter_test.go


44. protocol/statetracker/updaters/pairing_updater.go Additional files +10/-2

...

protocol/statetracker/updaters/pairing_updater.go


45. scripts/analyze_wrs.py Additional files +861/-0

...

scripts/analyze_wrs.py


46. scripts/analyze_wrs_metrics.py Additional files +269/-0

...

scripts/analyze_wrs_metrics.py


47. scripts/e2e/run_optimizer_wrs_health_load.sh Additional files +35/-0

...

scripts/e2e/run_optimizer_wrs_health_load.sh


48. scripts/pre_setups/init_lava_static_and_backup_provider.sh Additional files +2/-2

...

scripts/pre_setups/init_lava_static_and_backup_provider.sh


49. scripts/pre_setups/init_lava_static_and_backup_provider_base.sh Additional files +472/-0

...

scripts/pre_setups/init_lava_static_and_backup_provider_base.sh


50. scripts/pre_setups/init_lava_static_and_backup_provider_eth.sh Additional files +41/-59

...

scripts/pre_setups/init_lava_static_and_backup_provider_eth.sh


51. scripts/pre_setups/init_lava_static_provider_with_kafka.sh Additional files +1/-1

...

scripts/pre_setups/init_lava_static_provider_with_kafka.sh


52. scripts/pre_setups/init_lava_static_provider_with_node.sh Additional files +3/-3

...

scripts/pre_setups/init_lava_static_provider_with_node.sh


53. scripts/pre_setups/init_lava_static_test_three_provider_with_archive.sh Additional files +67/-38

...

scripts/pre_setups/init_lava_static_test_three_provider_with_archive.sh


54. scripts/pre_setups/init_lava_static_three_provider_with_archive.sh Additional files +20/-1

...

scripts/pre_setups/init_lava_static_three_provider_with_archive.sh


55. scripts/pre_setups/init_test3_simple.sh Additional files +115/-0

...

scripts/pre_setups/init_test3_simple.sh


56. scripts/pre_setups/init_test3_sync_impact.sh Additional files +204/-0

...

scripts/pre_setups/init_test3_sync_impact.sh


57. scripts/test_data/optimizer_wrs_provider1.json Additional files +46/-0

...

scripts/test_data/optimizer_wrs_provider1.json


58. scripts/test_data/optimizer_wrs_provider2.json Additional files +46/-0

...

scripts/test_data/optimizer_wrs_provider2.json


59. scripts/test_data/optimizer_wrs_provider3_archive.json Additional files +46/-0

...

scripts/test_data/optimizer_wrs_provider3_archive.json


60. testutil/e2e/allowedErrorList.go Additional files +1/-0

...

testutil/e2e/allowedErrorList.go


61. testutil/e2e/protocolE2E.go Additional files +33/-10

...

testutil/e2e/protocolE2E.go


62. testutil/e2e/proxy/proxy.go Additional files +6/-4

...

testutil/e2e/proxy/proxy.go


63. testutil/e2e/proxy/proxy_test.go Additional files +13/-0

...

testutil/e2e/proxy/proxy_test.go


64. utils/lavalog.go Additional files +6/-4

...

utils/lavalog.go


65. utils/rand/rand.go Additional files +68/-31

...

utils/rand/rand.go


66. utils/score/score_config.go Additional files +48/-1

...

utils/score/score_config.go


67. utils/score/score_store.go Additional files +130/-2

...

utils/score/score_store.go


68. wrs_tests/_framework/analyze.py Additional files +139/-0

...

wrs_tests/_framework/analyze.py


69. wrs_tests/_framework/analyze_test.py Additional files +307/-0

...

wrs_tests/_framework/analyze_test.py


70. wrs_tests/_framework/run.sh Additional files +124/-0

...

wrs_tests/_framework/run.sh


71. wrs_tests/_framework/wrs_analyze.py Additional files +1537/-0

...

wrs_tests/_framework/wrs_analyze.py


72. wrs_tests/run_all_10s_10k.sh Additional files +21/-0

...

wrs_tests/run_all_10s_10k.sh


73. wrs_tests/test_availability/analyze.py Additional files +23/-0

...

wrs_tests/test_availability/analyze.py


74. wrs_tests/test_availability/configs/consumer.yml Additional files +26/-0

...

wrs_tests/test_availability/configs/consumer.yml


75. wrs_tests/test_availability/configs/provider1.json Additional files +15/-0

...

wrs_tests/test_availability/configs/provider1.json


76. wrs_tests/test_availability/configs/provider1.yml Additional files +12/-0

...

wrs_tests/test_availability/configs/provider1.yml


77. wrs_tests/test_availability/configs/provider2.json Additional files +15/-0

...

wrs_tests/test_availability/configs/provider2.json


78. wrs_tests/test_availability/configs/provider2.yml Additional files +12/-0

...

wrs_tests/test_availability/configs/provider2.yml


79. wrs_tests/test_availability/configs/provider3.json Additional files +15/-0

...

wrs_tests/test_availability/configs/provider3.json


80. wrs_tests/test_availability/configs/provider3.yml Additional files +12/-0

...

wrs_tests/test_availability/configs/provider3.yml


81. wrs_tests/test_availability/run.sh Additional files +6/-0

...

wrs_tests/test_availability/run.sh


82. wrs_tests/test_latency/analyze.py Additional files +23/-0

...

wrs_tests/test_latency/analyze.py


83. wrs_tests/test_latency/configs/consumer.yml Additional files +26/-0

...

wrs_tests/test_latency/configs/consumer.yml


84. wrs_tests/test_latency/configs/provider1.json Additional files +15/-0

...

wrs_tests/test_latency/configs/provider1.json


85. wrs_tests/test_latency/configs/provider1.yml Additional files +12/-0

...

wrs_tests/test_latency/configs/provider1.yml


86. wrs_tests/test_latency/configs/provider2.json Additional files +15/-0

...

wrs_tests/test_latency/configs/provider2.json


87. wrs_tests/test_latency/configs/provider2.yml Additional files +12/-0

...

wrs_tests/test_latency/configs/provider2.yml


88. wrs_tests/test_latency/configs/provider3.json Additional files +15/-0

...

wrs_tests/test_latency/configs/provider3.json


89. wrs_tests/test_latency/configs/provider3.yml Additional files +12/-0

...

wrs_tests/test_latency/configs/provider3.yml


90. wrs_tests/test_latency/run.sh Additional files +6/-0

...

wrs_tests/test_latency/run.sh


91. wrs_tests/test_stake/analyze.py Additional files +23/-0

...

wrs_tests/test_stake/analyze.py


92. wrs_tests/test_stake/configs/consumer.yml Additional files +29/-0

...

wrs_tests/test_stake/configs/consumer.yml


93. wrs_tests/test_stake/configs/provider1.json Additional files +15/-0

...

wrs_tests/test_stake/configs/provider1.json


94. wrs_tests/test_stake/configs/provider1.yml Additional files +12/-0

...

wrs_tests/test_stake/configs/provider1.yml


95. wrs_tests/test_stake/configs/provider2.json Additional files +15/-0

...

wrs_tests/test_stake/configs/provider2.json


96. wrs_tests/test_stake/configs/provider2.yml Additional files +12/-0

...

wrs_tests/test_stake/configs/provider2.yml


97. wrs_tests/test_stake/configs/provider3.json Additional files +15/-0

...

wrs_tests/test_stake/configs/provider3.json


98. wrs_tests/test_stake/configs/provider3.yml Additional files +12/-0

...

wrs_tests/test_stake/configs/provider3.yml


99. wrs_tests/test_stake/run.sh Additional files +6/-0

...

wrs_tests/test_stake/run.sh


100. wrs_tests/test_sync/analyze.py Additional files +23/-0

...

wrs_tests/test_sync/analyze.py


101. wrs_tests/test_sync/configs/consumer.yml Additional files +26/-0

...

wrs_tests/test_sync/configs/consumer.yml


102. wrs_tests/test_sync/configs/provider1.json Additional files +15/-0

...

wrs_tests/test_sync/configs/provider1.json


103. wrs_tests/test_sync/configs/provider1.yml Additional files +12/-0

...

wrs_tests/test_sync/configs/provider1.yml


104. wrs_tests/test_sync/configs/provider2.json Additional files +15/-0

...

wrs_tests/test_sync/configs/provider2.json


105. wrs_tests/test_sync/configs/provider2.yml Additional files +12/-0

...

wrs_tests/test_sync/configs/provider2.yml


106. wrs_tests/test_sync/configs/provider3.json Additional files +15/-0

...

wrs_tests/test_sync/configs/provider3.json


107. wrs_tests/test_sync/configs/provider3.yml Additional files +12/-0

...

wrs_tests/test_sync/configs/provider3.yml


108. wrs_tests/test_sync/run.sh Additional files +6/-0

...

wrs_tests/test_sync/run.sh


Grey Divider

Qodo Logo

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. threadSafeRand panics on errors 📘 Rule violation ⛯ Reliability
Description
The new crypto/rand implementation calls panic() on invalid bounds and on crypto/rand
failures, which can crash the process instead of handling errors gracefully. The panic message
concatenates err.Error(), which may expose internal error details if it reaches user-visible
output.
Code

utils/rand/rand.go[R42-49]

+	if n <= 0 {
+		panic("invalid argument to Intn")
+	}
+	maxVal := big.NewInt(int64(n))
+	result, err := cryptorand.Int(cryptorand.Reader, maxVal)
+	if err != nil {
+		panic("crypto/rand failed: " + err.Error())
+	}
Evidence
PR Compliance ID 3 requires handling failure points and edge cases without uncontrolled failures,
and PR Compliance ID 4 requires not exposing internal error details; the added panic() paths
violate both by crashing and embedding internal crypto/rand error strings in the panic text.

Rule 3: Generic: Robust Error Handling and Edge Case Management
Rule 4: Generic: Secure Error Handling
utils/rand/rand.go[42-49]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`utils/rand/rand.go` uses `panic()` for invalid bounds and `crypto/rand` failures, which can crash the process and may leak internal error details via panic messages.

## Issue Context
Compliance requires robust error handling (no uncontrolled crashes where possible) and secure error handling (don’t expose internal details to user-facing outputs).

## Fix Focus Areas
- utils/rand/rand.go[42-49]
- utils/rand/rand.go[60-62]
- utils/rand/rand.go[72-74]
- utils/rand/rand.go[84-86]
- utils/rand/rand.go[96-98]
- utils/rand/rand.go[106-112]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Static purge misclassified 🐞 Bug ✓ Correctness
Description
IsStaticProvider ignores pairingPurge, so a static provider still serving an active WS subscription
after epoch handover can be treated as non-static and have reply signature verification enabled,
likely terminating the subscription stream.
Code

protocol/lavasession/consumer_session_manager.go[R99-125]

+// IsStaticProvider returns true when the given provider address belongs to a
+// static provider in the current pairing (including backup providers).
+//
+// This is used by higher-level flows (e.g. WS subscriptions) to decide whether
+// to skip reply signature verification, matching the behavior of regular RPC
+// calls for static providers.
+func (csm *ConsumerSessionManager) IsStaticProvider(providerAddr string) bool {
+	if csm == nil || providerAddr == "" {
+		return false
+	}
+
+	csm.lock.RLock()
+	defer csm.lock.RUnlock()
+
+	if cswp, ok := csm.pairing[providerAddr]; ok && cswp != nil {
+		cswp.Lock.RLock()
+		defer cswp.Lock.RUnlock()
+		return cswp.StaticProvider
+	}
+
+	if cswp, ok := csm.backupProviders[providerAddr]; ok && cswp != nil {
+		cswp.Lock.RLock()
+		defer cswp.Lock.RUnlock()
+		return cswp.StaticProvider
+	}
+
+	return false
Evidence
WS subscription verification explicitly uses ConsumerSessionManager.IsStaticProvider to decide
whether to call VerifyRelayReply. Providers can remain active during epoch handover while residing
in pairingPurge (connections are intentionally not purged for active subscriptions), but
IsStaticProvider only checks pairing and backupProviders, so static providers in pairingPurge will
be misdetected.

protocol/lavasession/consumer_session_manager.go[99-126]
protocol/lavasession/consumer_session_manager.go[203-214]
protocol/lavasession/consumer_session_manager.go[324-356]
protocol/chainlib/consumer_ws_subscription_manager.go[560-581]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`ConsumerSessionManager.IsStaticProvider` is used by WS subscription verification to decide whether to skip reply signature verification for static providers. During epoch handover, providers can be moved into `pairingPurge` while still actively serving subscriptions, but `IsStaticProvider` does not check `pairingPurge`, causing static providers to be misclassified and signature verification to be incorrectly enforced.

### Issue Context
- Purged providers may remain in use (subscriptions) and are explicitly excluded from immediate connection purging.
- WS subscription message verification uses `IsStaticProvider` to decide whether to call `VerifyRelayReply`.

### Fix Focus Areas
- protocol/lavasession/consumer_session_manager.go[99-126]
- protocol/lavasession/consumer_session_manager.go[203-214]
- protocol/lavasession/consumer_session_manager.go[324-356]
- protocol/chainlib/consumer_ws_subscription_manager.go[560-581]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Ticker never stopped 🐞 Bug ⛯ Reliability
Description
PeriodicProbeProviders creates a time.Ticker but no longer stops it; when ctx is canceled, the
function returns without releasing ticker resources.
Code

protocol/lavasession/consumer_session_manager.go[R359-363]

func (csm *ConsumerSessionManager) PeriodicProbeProviders(ctx context.Context, interval time.Duration) {
	ticker := time.NewTicker(interval)
-	defer ticker.Stop() // Ensure ticker is stopped to prevent goroutine/channel leak

	for {
		select {
Evidence
The current implementation returns on ctx.Done() without calling ticker.Stop(), which can leak
ticker resources when probe loops are started/stopped repeatedly (tests, reconfiguration, lifecycle
restarts).

protocol/lavasession/consumer_session_manager.go[359-372]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`PeriodicProbeProviders` creates a `time.Ticker` but does not stop it on exit. When `ctx.Done()` triggers, the function returns without calling `ticker.Stop()`, leaking underlying timer resources.

### Issue Context
This function can be started/stopped across component lifecycles and tests; not stopping tickers is a common source of resource leaks.

### Fix Focus Areas
- protocol/lavasession/consumer_session_manager.go[359-372]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Unstructured proxy test logging 📘 Rule violation ⛨ Security
Description
The proxy code adds println(...) and log.Println(...), producing unstructured logs and printing
full response payloads, which can hinder auditing and may expose sensitive data in logs. Compliance
requires structured logging and avoiding logging sensitive payloads.
Code

testutil/e2e/proxy/proxy.go[R236-241]

+					println(process.port+" ::: Fake Response ::: ", orderedJSON)
					fakeCount += 1
				}
				time.Sleep(500 * time.Millisecond)
-				conn.WriteMessage(msgType, []byte(orderedJSON))
+				if err := conn.WriteMessage(msgType, []byte(orderedJSON)); err != nil {
+					log.Println("Write error (cached response):", err)
Evidence
PR Compliance ID 5 requires structured logging and forbids sensitive data in logs; the added
println/log.Println statements are unstructured and include full JSON response content and raw
errors.

Rule 5: Generic: Secure Logging Practices
testutil/e2e/proxy/proxy.go[236-241]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`testutil/e2e/proxy/proxy.go` introduces unstructured logging (`println`, `log.Println`) and prints full JSON responses.

## Issue Context
Compliance requires structured logs for auditability and prohibits logging potentially sensitive payload data.

## Fix Focus Areas
- testutil/e2e/proxy/proxy.go[235-243]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Selection debug allocs 🐞 Bug ➹ Performance
Description
Weighted selection constructs per-candidate probability maps and a large attributes slice on every
selection before calling LavaFormatDebug; these allocations occur even when debug logging is
disabled.
Code

protocol/provideroptimizer/weighted_selector.go[R678-717]

+			// Calculate selection probability for each provider
+			selectionProbabilities := make(map[string]float64)
+			for _, p := range providerScores {
+				selectionProbabilities[p.Address] = (p.SelectionWeight / totalScore) * 100.0
+			}
+
+			// Log comprehensive selection summary
+			logAttrs := []utils.Attribute{
+				utils.LogAttr("GUID", ctx),
+				utils.LogAttr("selected_provider", ps.Address),
+				utils.LogAttr("selected_score", ps.SelectionWeight),
+				utils.LogAttr("selected_probability_pct", selectionProbabilities[ps.Address]),
+				utils.LogAttr("total_score", totalScore),
+				utils.LogAttr("random_value", randomValue),
+				utils.LogAttr("num_candidates", len(providerScores)),
+			}
+
+			// Add all candidates' scores and probabilities with parameter breakdown
+			for i, p := range providerScores {
+				prefix := fmt.Sprintf("candidate_%d", i+1)
+				logAttrs = append(logAttrs,
+					utils.LogAttr(prefix+"_provider", p.Address),
+					utils.LogAttr(prefix+"_score", p.SelectionWeight),
+					utils.LogAttr(prefix+"_probability_pct", selectionProbabilities[p.Address]),
+				)
+
+				// Add parameter breakdown if available
+				if i < len(scoreDetails) {
+					detail := scoreDetails[i]
+					logAttrs = append(logAttrs,
+						utils.LogAttr(prefix+"_availability", detail.Availability),
+						utils.LogAttr(prefix+"_latency", detail.Latency),
+						utils.LogAttr(prefix+"_sync", detail.Sync),
+						utils.LogAttr(prefix+"_stake", detail.Stake),
+						utils.LogAttr(prefix+"_composite", detail.Composite),
+					)
+				}
+			}
+
+			utils.LavaFormatDebug("Provider selection completed", logAttrs...)
Evidence
The selection path unconditionally allocates and populates selectionProbabilities and logAttrs
for all candidates. LavaFormatLog does log-level gating internally, but that happens after these
allocations are already performed, so disabled debug logs still pay the cost.

protocol/provideroptimizer/weighted_selector.go[670-717]
utils/lavalog.go[301-340]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`SelectProviderWithStats` builds a probability map and a large attribute slice for all candidates before calling `LavaFormatDebug`. Even when debug logs are disabled, this work still happens, adding avoidable allocations in a potentially frequent code path.

### Issue Context
`LavaFormatLog` has an internal log-level early return, but callers still pay for any pre-call computation. The fix should prevent building per-candidate log payloads when debug is not enabled.

### Fix Focus Areas
- protocol/provideroptimizer/weighted_selector.go[670-717]
- utils/lavalog.go[301-340]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread utils/rand/rand.go
Comment on lines +42 to +49
if n <= 0 {
panic("invalid argument to Intn")
}
maxVal := big.NewInt(int64(n))
result, err := cryptorand.Int(cryptorand.Reader, maxVal)
if err != nil {
panic("crypto/rand failed: " + err.Error())
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. threadsaferand panics on errors 📘 Rule violation ⛯ Reliability

The new crypto/rand implementation calls panic() on invalid bounds and on crypto/rand
failures, which can crash the process instead of handling errors gracefully. The panic message
concatenates err.Error(), which may expose internal error details if it reaches user-visible
output.
Agent Prompt
## Issue description
`utils/rand/rand.go` uses `panic()` for invalid bounds and `crypto/rand` failures, which can crash the process and may leak internal error details via panic messages.

## Issue Context
Compliance requires robust error handling (no uncontrolled crashes where possible) and secure error handling (don’t expose internal details to user-facing outputs).

## Fix Focus Areas
- utils/rand/rand.go[42-49]
- utils/rand/rand.go[60-62]
- utils/rand/rand.go[72-74]
- utils/rand/rand.go[84-86]
- utils/rand/rand.go[96-98]
- utils/rand/rand.go[106-112]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +99 to +125
// IsStaticProvider returns true when the given provider address belongs to a
// static provider in the current pairing (including backup providers).
//
// This is used by higher-level flows (e.g. WS subscriptions) to decide whether
// to skip reply signature verification, matching the behavior of regular RPC
// calls for static providers.
func (csm *ConsumerSessionManager) IsStaticProvider(providerAddr string) bool {
if csm == nil || providerAddr == "" {
return false
}

csm.lock.RLock()
defer csm.lock.RUnlock()

if cswp, ok := csm.pairing[providerAddr]; ok && cswp != nil {
cswp.Lock.RLock()
defer cswp.Lock.RUnlock()
return cswp.StaticProvider
}

if cswp, ok := csm.backupProviders[providerAddr]; ok && cswp != nil {
cswp.Lock.RLock()
defer cswp.Lock.RUnlock()
return cswp.StaticProvider
}

return false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Static purge misclassified 🐞 Bug ✓ Correctness

IsStaticProvider ignores pairingPurge, so a static provider still serving an active WS subscription
after epoch handover can be treated as non-static and have reply signature verification enabled,
likely terminating the subscription stream.
Agent Prompt
### Issue description
`ConsumerSessionManager.IsStaticProvider` is used by WS subscription verification to decide whether to skip reply signature verification for static providers. During epoch handover, providers can be moved into `pairingPurge` while still actively serving subscriptions, but `IsStaticProvider` does not check `pairingPurge`, causing static providers to be misclassified and signature verification to be incorrectly enforced.

### Issue Context
- Purged providers may remain in use (subscriptions) and are explicitly excluded from immediate connection purging.
- WS subscription message verification uses `IsStaticProvider` to decide whether to call `VerifyRelayReply`.

### Fix Focus Areas
- protocol/lavasession/consumer_session_manager.go[99-126]
- protocol/lavasession/consumer_session_manager.go[203-214]
- protocol/lavasession/consumer_session_manager.go[324-356]
- protocol/chainlib/consumer_ws_subscription_manager.go[560-581]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 359 to 363
func (csm *ConsumerSessionManager) PeriodicProbeProviders(ctx context.Context, interval time.Duration) {
ticker := time.NewTicker(interval)
defer ticker.Stop() // Ensure ticker is stopped to prevent goroutine/channel leak

for {
select {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Ticker never stopped 🐞 Bug ⛯ Reliability

PeriodicProbeProviders creates a time.Ticker but no longer stops it; when ctx is canceled, the
function returns without releasing ticker resources.
Agent Prompt
### Issue description
`PeriodicProbeProviders` creates a `time.Ticker` but does not stop it on exit. When `ctx.Done()` triggers, the function returns without calling `ticker.Stop()`, leaking underlying timer resources.

### Issue Context
This function can be started/stopped across component lifecycles and tests; not stopping tickers is a common source of resource leaks.

### Fix Focus Areas
- protocol/lavasession/consumer_session_manager.go[359-372]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@nimrod-teich nimrod-teich merged commit 9be5998 into main Feb 22, 2026
59 of 61 checks passed
@nimrod-teich nimrod-teich deleted the wrs_algo_feature branch February 22, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants