exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 8fa1244b92d3f779b67809713fa991f56d19ce78
parent 7253adbca4107f013c3c2340a016dc516af6b07b
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu,  6 Aug 2026 21:00:11 +0200

handle special case where money is transferred into a reserve that was initially created for a purse

Diffstat:
Msrc/exchangedb/do_import_credits.sql | 82++++++++++++++++++++++++++++++-------------------------------------------------
1 file changed, 31 insertions(+), 51 deletions(-)

diff --git a/src/exchangedb/do_import_credits.sql b/src/exchangedb/do_import_credits.sql @@ -141,57 +141,37 @@ BEGIN IF (conflict AND NOT dup) THEN - -- The reserve already existed, so the INSERT above did not credit it. - -- This is the body of the former exchange_do_batch_reserves_update(), - -- which the caller used to run in a *second* transaction, one - -- round-trip per affected reserve. It is reproduced here verbatim so - -- that this function behaves exactly as the sequence it replaces -- - -- including the fact that its INSERT can never fire, because the - -- statement above already put that very row into reserves_in. See - -- the separate report on the lost credit; fixing it here would have - -- buried a change of behaviour inside a refactoring. - INSERT INTO reserves_in - (reserve_pub - ,wire_reference - ,credit - ,exchange_account_section - ,wire_source_h_payto - ,execution_date - ) VALUES ( - ina_reserve_pub[i] - ,ina_wire_ref[i] - ,ina_credit[i] - ,in_exchange_account_name - ,ina_wire_source_h_payto[i] - ,in_reserve_expiration - ) - ON CONFLICT DO NOTHING; - IF FOUND - THEN - dup = FALSE; - UPDATE reserves rs - SET - current_balance.frac = (rs.current_balance).frac+(ina_credit[i]).frac - - CASE - WHEN (rs.current_balance).frac + (ina_credit[i]).frac >= 100000000 - THEN 100000000 - ELSE 0 - END - ,current_balance.val = (rs.current_balance).val+(ina_credit[i]).val - + CASE - WHEN (rs.current_balance).frac + (ina_credit[i]).frac >= 100000000 - THEN 1 - ELSE 0 - END - ,expiration_date=GREATEST(expiration_date,in_reserve_expiration) - ,gc_date=GREATEST(gc_date,in_reserve_expiration) - WHERE reserve_pub=ina_reserve_pub[i]; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,ina_notify[i]); - ELSE - dup = TRUE; - END IF; + -- The reserve already existed, so the INSERT INTO reserves above did + -- nothing and left the transfer uncredited. Add it to the balance the + -- reserve already has. + -- + -- Because reserves_in.reserve_pub is that table's primary key, getting + -- here at all means the reserve had no reserves_in row: a reserve that + -- exists without ever having been wired to, i.e. one created by a purse + -- merge. The predecessor of this branch tried to INSERT that row a + -- second time and treated the resulting conflict as "already imported", + -- so the credit was recorded in reserves_in and then never added to + -- current_balance. + UPDATE reserves rs + SET + current_balance.frac = (rs.current_balance).frac+(ina_credit[i]).frac + - CASE + WHEN (rs.current_balance).frac + (ina_credit[i]).frac >= 100000000 + THEN 100000000 + ELSE 0 + END + ,current_balance.val = (rs.current_balance).val+(ina_credit[i]).val + + CASE + WHEN (rs.current_balance).frac + (ina_credit[i]).frac >= 100000000 + THEN 1 + ELSE 0 + END + ,expiration_date=GREATEST(expiration_date,in_reserve_expiration) + ,gc_date=GREATEST(gc_date,in_gc_date) + WHERE reserve_pub=ina_reserve_pub[i]; + EXECUTE FORMAT ( + 'NOTIFY %s' + ,ina_notify[i]); END IF; out_duplicate = dup;