Skip to content

[Backend] Add Retry Logic and Fallback Provider to IPFS Service #501

@llinsss

Description

@llinsss

⚠️ This is a backend issue — work is done inside the backend/ folder

Description

backend/src/modules/blockchain/ipfs.service.ts uploads medical record hashes to IPFS via a single Kubo RPC client. If the IPFS node is unavailable, the upload throws immediately with no retry, causing the entire medical record sync to fail. There is also no fallback provider (e.g. Pinata, Web3.Storage) if the primary node is down.

Current State

  • IPFSService.upload() — single try/catch, no retry
  • IPFSService.retrieve() — single attempt, no fallback
  • No health check for the IPFS node
  • BlockchainSyncService calls IPFSService directly and propagates failures upward

What Needs to Be Built

1. Retry Logic with Exponential Backoff

async upload(data: string | Buffer, retries = 3): Promise<string> {
  for (let attempt = 1; attempt <= retries; attempt++) {
    try {
      return await this.primaryUpload(data);
    } catch (err) {
      if (attempt === retries) break;
      await sleep(500 * 2 ** attempt);
    }
  }
  return this.fallbackUpload(data); // Pinata fallback
}

2. Pinata Fallback Provider

  • Add PINATA_API_KEY and PINATA_SECRET_KEY to blockchain.config.ts
  • Implement fallbackUpload() using Pinata's REST API
  • Log which provider was used for each upload

3. IPFS Node Health Check

GET /blockchain/ipfs/health
  • Ping the IPFS node and return { status: 'ok' | 'degraded' | 'down', provider: 'kubo' | 'pinata' }
  • Expose via ObservabilityController or a new BlockchainController

4. Retrieve Fallback

  • On retrieve(cid), try primary node first, then Pinata gateway on failure

Acceptance Criteria

  • Failed uploads retry up to 3 times with exponential backoff
  • If all retries fail, upload falls back to Pinata
  • GET /blockchain/ipfs/health returns current provider status
  • Retrieve also falls back to Pinata gateway on primary failure
  • Provider used is logged for each operation
  • Unit tests mock both providers and verify fallback behaviour

Files to Modify

  • backend/src/modules/blockchain/ipfs.service.ts
  • backend/src/config/blockchain.config.ts (add Pinata config)
  • backend/src/modules/blockchain/blockchain.module.ts (expose health endpoint)
  • backend/src/modules/blockchain/ipfs.service.spec.ts (new)

Environment Variables Required

PINATA_API_KEY=
PINATA_SECRET_KEY=

Priority

High — IPFS failures currently break medical record blockchain sync entirely

Estimated Effort

2 days

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions