Skip to content

feat(stellar): implement circuit breaker for all Stellar RPC calls#868

Merged
Anuoluwapo25 merged 4 commits into
bakeronchain:mainfrom
Obiajulu-gif:fix/stellar-rpc-circuit-breaker
Apr 29, 2026
Merged

feat(stellar): implement circuit breaker for all Stellar RPC calls#868
Anuoluwapo25 merged 4 commits into
bakeronchain:mainfrom
Obiajulu-gif:fix/stellar-rpc-circuit-breaker

Conversation

@Obiajulu-gif
Copy link
Copy Markdown
Contributor

@Obiajulu-gif Obiajulu-gif commented Apr 27, 2026

Problem

This pr closes #611

All Stellar RPC calls (contract reads/writes, Horizon queries) were made without any circuit breaker. If the Soroban RPC endpoint degraded or became unresponsive, the server would continue making slow, blocking calls indefinitely — tying up resources and propagating failures to all dependents.


Solution

A custom CircuitBreaker class implementing the standard three-state pattern:

State Behaviour
CLOSED All calls pass through normally
OPEN Calls are rejected immediately with CircuitOpenError
HALF_OPEN One probe call is allowed to test recovery

State transitions are logged on every change:

[circuit:stellar-rpc] State transition: CLOSED → OPEN (will probe after 30000ms)
[circuit:stellar-rpc] State transition: OPEN → HALF_OPEN
[circuit:stellar-rpc] State transition: HALF_OPEN → CLOSED

Changes

server/src/services/stellar-contract.service.ts

  • Added CircuitState type, CircuitBreaker class, CircuitOpenError class
  • Created singleton stellarRpcCircuitBreaker instance (configurable via env vars)
  • Wrapped all 12 RPC-calling functions with stellarRpcCircuitBreaker.call()

server/src/routes/health.routes.ts

  • Imported stellarRpcCircuitBreaker
  • Added stellarRpc field to GET /api/health response:
{
  "stellarRpc": {
    "state": "CLOSED",
    "consecutiveFailures": 0,
    "openedAt": null
  }
}

Configuration

Env Var Default Description
STELLAR_CB_FAILURE_THRESHOLD 5 Consecutive failures before opening
STELLAR_CB_RESET_TIMEOUT_MS 30000 ms before probing recovery

Obiajulu-gif and others added 2 commits April 27, 2026 05:06
- Add CircuitBreaker class with CLOSED/OPEN/HALF_OPEN state machine
- Open circuit after N consecutive failures (default: 5, env: STELLAR_CB_FAILURE_THRESHOLD)
- Transition to HALF_OPEN after reset timeout (default: 30s, env: STELLAR_CB_RESET_TIMEOUT_MS)
- Close circuit on first successful probe in HALF_OPEN state
- Log all state transitions (CLOSED -> OPEN -> HALF_OPEN -> CLOSED)
- Wrap all 12 Stellar RPC functions with stellarRpcCircuitBreaker.call():
  callVerifyMilestone, emitRejectionEvent, callMintScholarNFT, isEnrolled,
  submitScholarshipProposal, castVote, cancelProposal, reclaimInactiveEscrow,
  getLearnTokenBalance, getGovernanceTokenBalance, getGovernanceVotingPower,
  getGovernanceDelegation
- Expose circuit state (state, consecutiveFailures, openedAt) in GET /api/health
  under the 'stellarRpc' key

Closes #<ISSUE_NUMBER>
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Apr 27, 2026

@Obiajulu-gif Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Anuoluwapo25
Copy link
Copy Markdown
Contributor

kindly fix conflicts.....And i noticed you don't give people issues on your repo...nice

@Anuoluwapo25 Anuoluwapo25 merged commit fd8b69d into bakeronchain:main Apr 29, 2026
2 of 9 checks passed
Anuoluwapo25 added a commit that referenced this pull request May 26, 2026
…aker

feat(stellar): implement circuit breaker for all Stellar RPC calls
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add circuit breaker pattern for Stellar RPC calls

2 participants