Repository navigation
ic402 v2.17.3
Patch — session-close fixes found by an adversarial review of 2.17.2. No API, type,
PaymentResult or example.did change; no new state; schema stays v1.
Fixed
recoverEscrowcould drain an escrow under an in-flight close. It accepted#closingand
#expiredas well as#closed, capped only per call. A payer racing it against their own ICP close
drained the escrow, so the settle failed and reopened the session, and repeating it recovered the
merchant's consumed share too. It now accepts#closedonly.- An expiry-sweep close that never ran stranded the deposit. The sweep set
#expiredand called
the close with notry/catch. If that message was rejected or trapped before the close started,
the session stayed#expiredwith its full escrow until the 24 h GC deleted the record. The sweep
now reverts it to#openso the next tick retries, and one failed close no longer stops the sweep. - A ledger reject on the settle left the session resting in
#closing. A reject on that
guaranteed-response call moved nothing, so it is now handled like a failed settle: the session
goes back to#openand the close is retried. A ledger outage therefore no longer parks sessions. forceResolveSessionduring a live ICP close double-credited the daily limit once that close
succeeded. The close now finishes with#closed+ its daily release only if it is still
#closing; its transfers still run.- A
#closedsession still holding escrow gets the full 24 h to recover it. A failed refund and
forceResolveSessionnow refreshlastActivityAt; GC used to measure from the last voucher, so a
long-idle session's record could be deleted on the next tick.
Visible changes
recoverEscrowon#closing/#expiredreturns#err. Close an#expiredsession with
closeSession; a session resting in#closing(a refund rejected by the ledger, a trap, or an
earlier version) needs the controller'sforceResolveSessionbefore the payer can recover it.closeSession/forceCloseSessionreturn#settlementFailed("Settle: ledger call rejected: …")
on a settle reject instead of throwing.
Not changed
- A
forceResolveSessionduring a live close whose settle then fails: the close reopens the session
(funds first, as before), so the daily limit can still be double-credited in that case. The EVM
half of the force-resolve race is unchanged too. recoverEscrowstill caps each call, not the total: after a controller forces a session whose
settle never ran, repeated calls can recover part of the merchant's share.- Sessions from before 2.17.2 that rest
#expiredafter being settled: re-closing one still reopens
it, so leave them to the 24 h GC. - A rejected or trapped sweep self-call can't be induced in a test, so that revert is covered by
review only; the sweep carrying on past a close that fails mid-close is tested.