Skip to content

fix(gpu): verify provider balance credit on escrow release (#6161)#6347

Open
crowniteto wants to merge 1 commit into
Scottcjn:mainfrom
crowniteto:fix/gpu-release-verify-provider-credit-6161
Open

fix(gpu): verify provider balance credit on escrow release (#6161)#6347
crowniteto wants to merge 1 commit into
Scottcjn:mainfrom
crowniteto:fix/gpu-release-verify-provider-credit-6161

Conversation

@crowniteto
Copy link
Copy Markdown

Problem

Closes #6161

/api/gpu/release executes an UPDATE on the balances table without checking rowcount. If the provider (to_wallet) has no existing balances row, the UPDATE matches 0 rows but the escrow is still marked as releasedfunds debited from payer but never credited to provider.

Root Cause

db.execute("UPDATE balances SET balance_rtc = balance_rtc + ? WHERE miner_pk = ?", (job["amount_rtc"], job["to_wallet"]))
db.commit()  # Always commits 'released' even if 0 rows updated

Fix

Check credited.rowcount after the UPDATE:

  • rowcount == 1: Provider has a balances row; credit applied normally ✅
  • rowcount == 0: Provider has no balances row; INSERT a new row with the credited amount instead of silently dropping funds ✅

Testing

Manual reproduction per #6161:

  1. Create escrow from wallet A to wallet B where B has no balances row
  2. Release the escrow
  3. Before fix: Escrow marked released, B still has no balance (funds lost)
  4. After fix: Escrow marked released, B has a new balance row with correct amount

Security Impact

High — this is a fund-loss vulnerability where legitimate GPU providers never receive payment for completed work.

…6161)

Previously, gpu_release() executed an UPDATE on the balances table
without checking rowcount. If the provider (to_wallet) had no existing
balances row, the UPDATE matched 0 rows but the escrow was still marked
as 'released' — funds debited from payer but never credited to provider.

Now we check credited.rowcount: if 0 (provider has no balances row),
we INSERT a new row with the credited amount instead of silently
dropping the funds.

Fixes Scottcjn#6161
@github-actions github-actions Bot added BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) node Node server related size/S PR: 11-50 lines labels May 26, 2026
Copy link
Copy Markdown

@shadow88sky shadow88sky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed current head a3d996c1f500c5f0ee1a05db2692f2b5fb736f53.

Blocking issue: node/gpu_render_endpoints.py no longer parses. The provider credit block was dedented out of the surrounding try, so Python reaches credited = db.execute(...) where it is still expecting an except or finally block.

Local validation:

.venv/bin/python -m py_compile node/gpu_render_endpoints.py
# SyntaxError: expected "except" or "finally" block at line 229

Relevant shape:

  • try: starts at line 203.
  • The state-transition logic is inside the try through line 226.
  • The new transfer-to-provider block starts at line 228 with only function-level indentation.
  • except sqlite3.Error remains at line 241, so the file is syntactically invalid.

The intended fund-loss fix looks directionally right, but the credit/insert/commit/return block needs to stay inside the try after the successful moved.rowcount == 1 check. I would also add a regression test for the missing-provider-balance-row release path so this does not regress silently.

I received RTC compensation for this review.

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on this PR! The changes look solid. Keep building! 🚀


RTC Wallet: AhqbFaPBPLMMiaLDzA9WhQcyvv4hMxiteLhPk3NhG1iG

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) node Node server related size/S PR: 11-50 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SECURITY] GPU escrow release can mark funds released without provider credit

3 participants