Skip to content

fix: cooperative close uses actual spent amount instead of voucher ceiling#191

Open
gakonst wants to merge 1 commit intomainfrom
fix/cooperative-close-spent-amount
Open

fix: cooperative close uses actual spent amount instead of voucher ceiling#191
gakonst wants to merge 1 commit intomainfrom
fix/cooperative-close-spent-amount

Conversation

@gakonst
Copy link
Copy Markdown
Contributor

@gakonst gakonst commented Apr 3, 2026

Problem

On cooperative close, the server required the close voucher's cumulativeAmount to be >= highest_voucher_amount (the pre-authorized reservation). This meant clients were charged the full reservation even when actual usage was much lower.

Reproduced with Dune MPP: A SELECT 1 query (88ms execution, 4 bytes result) was charged the full $4.00 reservation instead of actual compute cost.

Root Cause

handle_close() validated:

if cumulative_amount < channel.highest_voucher_amount { // ❌ rejects actual-spend closes

And unconditionally overwrote the voucher:

highest_voucher_amount: cumulative_amount, // ❌ always stomps

Fix

Ports the fix from mppx (wevm/mppx#196) and wallet (tempoxyz/wallet#349):

  1. Minimum close amount is now max(channel.spent, on_chain.settled) instead of highest_voucher_amount, allowing clients to close at actual usage cost.

  2. Store update only overwrites highest_voucher_amount when the close amount is actually higher, preserving the original voucher for settlement.

Testing

All 240 existing tests pass. The behavioral change only affects cooperative close when the client sends a voucher below the highest pre-authorized amount but above actual spend — previously rejected, now accepted.

…iling

On cooperative close, the server required the close voucher's
cumulativeAmount to be >= highest_voucher_amount (the pre-authorized
reservation). This meant clients were charged the full reservation
even when actual usage was much lower (e.g., $4 for a SELECT 1 query).

This ports the fix from mppx (wevm/mppx#196) and wallet
(tempoxyz/wallet#349):

1. The minimum close amount is now max(channel.spent, on_chain.settled)
   instead of highest_voucher_amount, allowing clients to close at
   actual usage cost.

2. The store update only overwrites highest_voucher_amount when the
   close amount is actually higher, preserving the original voucher
   for settlement if the close is at a lower (actual spent) amount.

Amp-Thread-ID: https://ampcode.com/threads/T-019d5503-2e85-70ff-81ed-b5093c920fd5
Co-authored-by: Amp <amp@ampcode.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

⚠️ Changelog not found.

A changelog entry is required before merging. We've generated a suggested changelog based on your changes:

Preview
---
mpp: patch
---

Fixed cooperative close verification to use the actual spent amount as the minimum close amount (instead of the highest voucher amount), so clients are only charged for actual usage. Also fixed an issue where finalizing a channel could incorrectly overwrite a higher voucher amount with a lower on-chain value.

Add changelog to commit this to your branch.

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.

1 participant