Commit Graph
276 Commits
Author SHA1 Message Date
9qeklajc 2f2820eb33 fix test 2026-08-04 01:44:01 +02:00
9qeklajc a6c129c02d harden autotopup 2026-08-04 01:32:25 +02:00
9qeklajc a2e2a5c662 clean up 2026-08-04 01:13:20 +02:00
9qeklajc 8e8a9a46b6 Merge remote-tracking branch 'origin/main' into ppq-auto-topup
# Conflicts:
#	routstr/upstream/auto_topup.py
#	routstr/wallet.py
#	tests/unit/test_wallet.py
2026-08-04 00:24:27 +02:00
9qeklajc 3b2c5a0671 Merge remote-tracking branch 'origin/main' into fix/xcashu-cost-breakdown-port 2026-08-04 00:12:37 +02:00
9qeklajc 694bc04623 harden melting 2026-08-04 00:06:53 +02:00
9qeklajc da859f2f84 clean up 2026-08-03 23:32:06 +02:00
9qeklajc dd8c4a9a8a update migartion 2026-08-03 00:05:36 +02:00
9qeklajc 2b4e4c2430 Merge remote-tracking branch 'origin/main' into fix/mint-rate-limit-and-fallback
# Conflicts:
#	tests/unit/test_fee_payout_migration.py
2026-08-02 23:29:16 +02:00
9qeklajc e903aa3a9f clean up 2026-08-02 23:16:01 +02:00
9qeklajc f3eefc2638 Merge remote-tracking branch 'origin/main' into model-paths
# Conflicts:
#	routstr/core/settings.py
#	tests/unit/test_fee_payout_migration.py
2026-08-02 22:27:39 +02:00
9qeklajc dc13cde00c chore: remove unrelated PPQ PR changes 2026-07-31 02:42:14 +02:00
9qeklajc c0aad3b3ab test: isolate BOLT11 mint selection liabilities 2026-07-31 02:16:03 +02:00
9qeklajc 19236ecc9d fix(db): increase default connection pool capacity 2026-07-31 02:14:50 +02:00
9qeklajc 7a2b485af6 Merge main into ppq-auto-topup 2026-07-31 02:10:43 +02:00
9qeklajc 2ec6b27200 fix: resolve mint fallback review comments 2026-07-31 02:10:00 +02:00
9qeklajc f9980e5c66 fix: harden PPQ auto top-up reconciliation 2026-07-31 02:06:50 +02:00
9qeklajc 60566313dc fix: return persisted API-key refund token 2026-07-31 01:19:18 +02:00
9qeklajc 443c910b9e Merge branch 'main' into fix/mint-rate-limit-and-fallback 2026-07-30 08:38:27 +02:00
9qeklajc 4cc9aef61f fix: make payouts and proxy sessions safe 2026-07-30 02:57:49 +02:00
9qeklajc 3befe063f4 fix: annotate lightning settlement test session 2026-07-30 01:19:35 +02:00
9qeklajc 895ea90bfa Merge branch 'main' into fix/mint-rate-limit-and-fallback
# Conflicts:
#	routstr/core/settings.py
#	routstr/lightning.py
#	routstr/wallet.py
#	tests/integration/test_lightning_invoice_constraints.py
#	tests/unit/test_fee_payout_migration.py
#	tests/unit/test_fetch_all_balances.py
2026-07-30 01:09:32 +02:00
9qeklajc 5ea5024608 resolve review comments 2026-07-29 22:50:33 +02:00
9qeklajc bb2a05b67c add url and specific model infos to paht 2026-07-29 00:08:34 +02:00
9qeklajc e2f89a2645 fix: address follow-up model path review 2026-07-27 23:17:13 +02:00
9qeklajc c829685f80 fix Cashu fallback and Lightning settlement 2026-07-26 23:23:32 +02:00
9qeklajc 16fc548b48 fix: make model path identity selectable 2026-07-26 20:12:55 +02:00
9qeklajc 06dba681c5 fix: satisfy strict mypy in model-paths tests
Replace untyped lambdas with typed handler/provider functions; CI runs
mypy over tests as well.
2026-07-26 13:26:49 +02:00
9qeklajc f96acbb99c fix: address model-paths review findings
Provider scoping (items 1/2/6):
- Key visibility maps on (model_id.lower(), upstream_provider_id), matching
  refresh_model_maps, so a disable/override row on one provider never leaks
  onto another provider's model, and matching is case-insensitive.

Data safety (items 3/5):
- Degraded OpenRouter fetches (network error, 429, non-200, bad payload)
  return None (unknown) instead of []; a provider whose path set is unknown
  keeps its previously persisted rows instead of being wiped.
- Endpoint payload parsing moved fully inside try, with a list guard, so
  endpoints:null or non-list shapes are swallowed as documented.
- refresh with an empty live upstream list is a no-op; the unfiltered
  DELETE in the prune path is gone (prune now keys off enabled DB rows).

Hot path (items 4/12/14):
- Persist uses chunked bulk INSERTs (one statement per 500 rows) instead of
  per-row ORM adds; redundant ix_model_paths_model_id index dropped.
- Read routes filter in SQL instead of materializing the whole table, and
  output ordering is deterministic (public id + path), independent of rowid.
- Visibility no longer rebuilds fully priced Model objects per override row;
  it reads id/forwarded_model_id/canonical_slug straight off ModelRow.

Path/id contract (items 7/8/9/11):
- discovery_path_for_subprovider/discovery_base_paths hooks on
  BaseUpstreamProvider, overridden by OpenRouterUpstreamProvider, mirror
  _apply_provider_field so discovery and response stamping cannot drift
  (openrouter:OpenRouter now correctly maps to unknown).
- openrouter_author_slug falls back to a slash-containing forwarded_model_id,
  so admin-created alias rows are discoverable.
- public_model_id splits on the first slash, same as get_base_model_id, so
  discovery ids can be sent to chat completions verbatim.

Lifecycle (items 10/13):
- ENABLE_MODEL_PATHS_REFRESH kill switch; interval and flag re-read every
  loop iteration, and the task idles (not exits) while disabled.
- First 429 latches and aborts the remaining fan-out for the cycle; a
  per-cycle cache dedupes fetches across providers sharing a base URL.
- refresh_model_maps prunes paths of disabled/deleted providers so admin
  mutations take effect immediately; rows carry updated_at and both
  endpoints expose it.

Tests (item 15) rewritten through the public refresh entry point with
transport-level httpx.MockTransport fakes, FK enforcement on, and coverage
for the periodic loop. Migration re-chained onto 9c4d8e2f1a6b.
2026-07-26 13:23:31 +02:00
9qeklajc 73a3f12469 Merge remote-tracking branch 'origin/main' into model-paths 2026-07-26 13:09:07 +02:00
9qeklajc 39f801561b fix: recreate refund sweep migration on latest head 2026-07-26 12:52:24 +02:00
9qeklajc ff55788e2d fix: address PR 634 review feedback 2026-07-26 12:44:37 +02:00
9qeklajc 423e2cba73 ppq-auto-topup 2026-07-26 02:38:07 +02:00
9qeklajc 1138cdd4ef Merge main and recreate mint URL migration 2026-07-26 00:16:10 +02:00
9qeklajc 344c3c5f21 reapply fee migration 2026-07-25 23:42:50 +02:00
9qeklajc 4c6bc49e07 unify payment path 2026-07-25 00:36:32 +02:00
9qeklajc 1131c2d583 test: keep dynamic settings validation mypy-safe 2026-07-24 23:41:01 +02:00
9qeklajc 7108d554c8 merge: combine PR #632 with broader pool-exhaustion fixes 2026-07-24 23:22:01 +02:00
9qeklajc b0c70ecddc fix: send Cashu token creation payload in request body 2026-07-24 23:01:10 +02:00
Jeroen UbbinkandClaude Opus 4.8 a2cedd6769 feat: make the DB connection pool env-configurable
Add DATABASE_POOL_SIZE / DATABASE_MAX_OVERFLOW / DATABASE_POOL_TIMEOUT,
consumed like every other typed env var through the pydantic Settings
(constrained Fields, defaults 5/10/30 matching SQLAlchemy's own baseline
so leaving them unset is behaviour-neutral). An out-of-range or
non-integer value fails validation and refuses to boot — the same
fail-loud behaviour a malformed DATABASE_URL already has — rather than
silently starting up misconfigured. create_db_engine sizes the pool from
these and logs the effective values at startup so they can be confirmed
from the boot output during an incident. In-memory SQLite (StaticPool,
which rejects the pool kwargs) is detected and built without them.

pool_pre_ping is deliberately not exposed: the default backend is a local
SQLite file with no network peer to drop idle connections, so it would add
a SELECT 1 per checkout for no benefit — and it detects dead connections,
not the live-but-wedged ones behind the exhaustion this series addresses.

These knobs are infrastructure the node needs before it can open a DB
session, so they can never be sourced from the DB (chicken-and-egg). A new
ENV_ONLY_FIELDS set keeps them out of the persisted settings blob and
stops a DB value from shadowing env in both SettingsService.initialize and
.update, so env stays authoritative.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 22:26:57 +02:00
Jeroen UbbinkandClaude Opus 4.8 7b0ade3987 fix: stop AsyncSession pool exhaustion in balance reads
fetch_all_balances shared a single AsyncSession across the tasks it ran
with asyncio.gather. AsyncSession is not safe for concurrent use: the
overlapping queries raised "concurrent operations are not permitted" and
left connections wedged until the QueuePool was exhausted, after which
admin/API endpoints returned 500/502 until a container restart.

Read all outstanding user liabilities up front in one short-lived session
with a single grouped query (balances_by_mint_and_unit), then run the
per-mint balance checks concurrently with no session in scope. A failure
reading liabilities now degrades gracefully — the page still reports the
known wallet custody and blanks only the unknowable user/owner split,
tagging each mint with the error — instead of 500-ing the whole page.

periodic_payout reads each liability fresh, immediately before the payout
decision, rather than from a single pre-loop snapshot: the per-mint round
trip is slow, and a user top-up during the cycle would otherwise let a
later mint/unit act on a stale-low liability and over-send funds owed to
users (related to the payout-safety concern in issue #611).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 22:26:25 +02:00
9qeklajc 81c0ff57e9 fix: expose cost breakdown in paid responses 2026-07-24 22:24:24 +02:00
9qeklajc 2410a4a6ce fix: address review findings on payout liability staleness, sweep races, and cancellation safety
- periodic_payout: fetch liability per mint/unit right before computing
  available balance, so a concurrent top-up can only shrink the payout
- refund sweep: atomically claim each refund before redeeming; release the
  claim on failure so retries still happen and concurrent sweeps cannot
  misreport a sweep as client-collected
- check_invoice_payment: catch BaseException so task cancellation after a
  successful mint still emits the reconciliation alert
- tests: DB-guard race test where both mints succeed (exactly one credit);
  pool_size=1 test proving the fee payout releases its connection during
  the external send
2026-07-24 22:14:57 +02:00
9qeklajc 7394b10e75 fix-concurent-issue 2026-07-24 21:29:21 +02:00
9qeklajc 04879cad56 Merge remote-tracking branch 'origin/main' into model-paths-pr588 2026-07-24 21:14:08 +02:00
9qeklajc 66ba31d0df Merge remote-tracking branch 'origin/main' into fix/streaming-billing-finalization 2026-07-24 02:05:58 +02:00
9qeklajc 16679c1f4e Merge branch 'main' into model-paths 2026-07-24 02:02:48 +02:00
9qeklajcandGitHub a9593ab416 Merge pull request #570 from jeroenubbink/feat/config-ownership-secrets
feat(config): store node secrets in an encrypted vault
2026-07-24 02:02:21 +02:00
9qeklajcandGitHub 6221ee8152 Merge pull request #628 from Routstr/fix/cashu-reservation-recovery
fix(wallet): recover stale Cashu reservations safely
2026-07-24 01:12:57 +02:00
9qeklajc 65ea28cb85 add test 2026-07-24 01:10:57 +02:00