Skip to content

fix(cron): gate LND maintenance tasks behind cronConfig.lndTasksEnabled#430

Merged
islandbitcoin merged 1 commit into
mainfrom
fix/cron-gate-lnd-tasks
Jul 4, 2026
Merged

fix(cron): gate LND maintenance tasks behind cronConfig.lndTasksEnabled#430
islandbitcoin merged 1 commit into
mainfrom
fix/cron-gate-lnd-tasks

Conversation

@islandbitcoin

Copy link
Copy Markdown
Contributor

Problem

The daily flash-cronjob k8s Job crash-loops: deleteLndPaymentsBefore2Months throws OffChainServiceUnavailableError (no LND exists in Flash's IBEX-custodial architecture — it tries lnd1.galoy-dev-bitcoin.svc.cluster.local, upstream galoy's dev default), one failed task → exit 99 → Job retry loop. This was masked until charts 3.2.15 fixed the missing -c configPath; with the config finally loading, the task-level failure surfaced.

Task audit (what runs on Flash and what shouldn't)

Task Verdict
rebalancingInternalChannels, updateEscrows, updateRoutingRevenues LND-only → gated
updatePendingLightningInvoices, updatePendingLightningPayments, updateLnPaymentsCollection, updateLegacyOnChainReceipt LND machinery → gated
deleteLndPaymentsBefore2Months (the thrower), deleteFailedPaymentsAttemptAllLnds LND-only → gated
checkAllLndHealth() preamble + activateLndHealthCheck() bootstrap LND probes → gated
rebalance / swapOutJob keep existing rebalanceEnabled/swapEnabled gates
reconcileBridgeDepositsJob / reconcileBridgeWithdrawalsJob already self-gated on BridgeConfig.enabled → unchanged
deleteExpiredPaymentFlows, deleteExpiredInvoices pure mongo cleanup — Flash's real cron work → unconditional

Change

New cronConfig.lndTasksEnabled (schema default true — upstream parity). Verified through the real config loader:

  • config without cronConfig{rebalanceEnabled:true, swapEnabled:true, lndTasksEnabled:true} (unchanged behavior)
  • legacy cronConfig without the key → lndTasksEnabled:true injected (backward compatible)
  • explicit false → gated task list: expiry cleanup + bridge reconciliation only

tsc --noEmit clean; eslint clean.

Rollout

After this image ships via the pipeline, set cronConfig.lndTasksEnabled: false in the chart's galoy.config (charts repo — will ride the auto image-bump PR). Ordering matters: the values change must not land before this image (old schema has additionalProperties: false and would reject the unknown key).

🤖 Generated with Claude Code

The cron server unconditionally ran upstream galoy's LND/bitcoin
maintenance tasks (rebalancingInternalChannels, updateEscrows, pending
LN invoice/payment updates, LnPayments sync, routing revenues, legacy
onchain receipts, LND payment cleanup) plus checkAllLndHealth and
activateLndHealthCheck. Flash is IBEX-custodial with no LND nodes, so
deleteLndPaymentsBefore2Months throws OffChainServiceUnavailableError
on every run — one failed task exits 99, so the daily k8s Job has been
crash-looping (masked until now by the chart's missing -c configPath,
fixed in charts 3.2.15).

Add cronConfig.lndTasksEnabled (schema default true — upstream parity;
legacy configs without the key validate and behave unchanged, verified
through the real loader) and gate the LND task group and both health
checkers behind it. With it false, the cron runs exactly the tasks that
apply to Flash: mongo expiry cleanup (deleteExpiredPaymentFlows,
deleteExpiredInvoices) and Bridge↔IBEX reconciliation (already
self-gated on BridgeConfig.enabled). rebalance/swapOut keep their
existing config gates.

Deployments follow-up: set cronConfig.lndTasksEnabled=false in the
chart config once this image ships.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@islandbitcoin islandbitcoin merged commit cbc1fb6 into main Jul 4, 2026
14 checks passed
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.

2 participants