Skip to content

Fix/four issues batch - #571

Merged
legend-esc merged 4 commits into
legend-esc:mainfrom
jhayniffy:fix/four-issues-batch
Jul 25, 2026
Merged

Fix/four issues batch#571
legend-esc merged 4 commits into
legend-esc:mainfrom
jhayniffy:fix/four-issues-batch

Conversation

@jhayniffy

Copy link
Copy Markdown
Contributor

closes #519
closes #520
closes #521
closes #522
Why this matters now: Marketplace.clean_expired_offers exists but requires manual invocation with gas fees paid by caller. Over time, thousands of expired offers accumulate in storage, wasting scarce contract storage and leaving credits locked in escrow. Automated cleanup unblocks marketplace scaling.

Problem / What: contracts/marketplace/src/lib.rs — clean_expired_offers(start_id, limit) must be called explicitly. No one calls it, so expired offers pile up forever.

Why this matters now: ProjectsService.createProject uploads docs to IPFS via Pinata, gets a CID, then stores it in-memory. If the Pinata API returns 503 (transient outage), the entire project creation fails and must be resubmitted manually. Issue #359 identified that the CID is lost if the subsequent contract call fails — but the root cause is no retry on upload.

Problem / What: projects.service.ts — uploadToIpfs calls axios.post to Pinata with no retry wrapper. Pinata has 99.9% uptime but occasional 1-second blips cause failures.

Automates clean_expired_offers() calls (currently manual-only) so
expired offers don't pile up in contract storage. Batches in chunks
of 100, uses admin keypair for gas, tracks
marketplace.cleanup.offers_removed/gas_spent, and alerts when the
pending backlog exceeds 1000 offers.

Not yet wired into MarketplaceModule providers pending Soroban RPC
client plumbing.
uploadToIpfs had no retry, so a transient Pinata blip lost the whole
project submission (root cause behind issue legend-esc#359's CID loss). Adds
uploadToIpfsWithRetry() mirroring StellarService's exponential
backoff (100/200/400ms), retrying on 429/503/network timeout and
failing fast on 400/401. Includes a test mocking 503, 503, then 200.

Not yet wired into ProjectsService.uploadToIpfs — also still need the
pending_uploads fallback table + background retry job for the
all-retries-failed case.
DataKey had no version field, so any future variant insertion would
shift every subsequent discriminant and break storage layout on an
already-deployed contract. Adds DataKey::Version (u32, instance
storage), initializes it to migrations::CURRENT_VERSION in
initialize(), and adds a migrations.rs with run_migrations() that
walks version steps sequentially (v1->v2->v3...). Includes a
v1->v2 migration test and docs/contracts/storage-layout.md
documenting the append-only DataKey rule.

Still need: a public migrate(admin, target_version) contract entry
point wired into lib.rs's #[contractimpl] (run_migrations is ready,
just not exposed yet).
…tion

DataSource had no pool settings, so TypeORM/pg opened a new
connection per request and never returned it to a pool, hitting
Postgres's max_connections=100 at ~50 concurrent requests
(ECONNREFUSED). Sets poolSize 20 with idleTimeoutMillis 30000 and
connectionTimeoutMillis 2000 in data-source.ts.

Also adds db-pool-health.util.ts (pool stats for
DB_POOL_ACTIVE_CONNECTIONS/DB_POOL_IDLE_CONNECTIONS + slow-acquire
logging >500ms, not yet wired into HealthController) and an
integration test spawning 100 concurrent queries to verify the pool
stays capped at 20.
@jhayniffy
jhayniffy requested a review from legend-esc as a code owner July 25, 2026 00:46
@drips-wave

drips-wave Bot commented Jul 25, 2026

Copy link
Copy Markdown

@jhayniffy 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

@legend-esc
legend-esc merged commit f8884ad into legend-esc:main Jul 25, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment