exchange

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

commit af660c11f94d80edd8f89ccaca9da2195e23ffcc
parent 04ba57964684d50087462df2ec4cace1c8e5dbec
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue,  3 Nov 2026 22:48:58 +0100

keep checking the rest even if one denomination is missing

Diffstat:
Msrc/auditor/taler-helper-auditor-coins.c | 4+++-
Msrc/auditor/taler-helper-auditor-reserves.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c @@ -1472,7 +1472,9 @@ withdraw_cb ( cc->qs = qs; return GNUNET_SYSERR; } - return GNUNET_OK; + /* We cannot account for this planchet, but the other planchets + of the batch must still be processed. */ + continue; } ds = get_denomination_summary (cc, issue); diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c @@ -582,10 +582,12 @@ handle_withdrawals ( const struct TALER_Amount *amount_with_fee) { struct ReserveSummary *rs; - const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue; struct TALER_Amount auditor_amount; struct TALER_Amount auditor_fee; struct TALER_Amount auditor_amount_with_fee; + struct TALER_AgeMask age_mask = { 0 }; + bool have_age_mask = false; + bool missing_denom = false; enum GNUNET_DB_QueryStatus qs; /* should be monotonically increasing */ @@ -613,6 +615,8 @@ handle_withdrawals ( } for (size_t i = 0; i < num_denom_serials; i++) { + const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue; + /* lookup denomination pub data (make sure denom_pub is valid, establish fees); initializes wsrd.h_denomination_pub! */ qs = TALER_ARL_get_denomination_info_by_serial (denom_serials[i], @@ -638,12 +642,33 @@ handle_withdrawals ( "denomination key not found"); if (global_qs < 0) return GNUNET_SYSERR; - return GNUNET_OK; + /* We cannot account for this planchet, but the other planchets + of the batch must still be processed. */ + missing_denom = true; + continue; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Analyzing withdrawn denomination #%llu (%s)\n", (unsigned long long) denom_serials[i], TALER_amount2s (&issue->value)); + if (! have_age_mask) + { + age_mask = issue->age_mask; + have_age_mask = true; + } + else if (age_mask.bits != issue->age_mask.bits) + { + /* All denominations of one batch must share the age mask, as the + reserve signature is made over a single age mask. */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Denominations of withdraw row %llu disagree on the age mask\n", + (unsigned long long) rowid); + report_row_inconsistency ("withdraw", + rowid, + "denominations of the batch disagree on the age mask"); + if (global_qs < 0) + return GNUNET_SYSERR; + } /* check that execution date is within withdraw range for denom_pub */ GNUNET_log ( @@ -710,6 +735,33 @@ handle_withdrawals ( &issue->fees.withdraw); } /* end for all coins in batch */ + if (missing_denom) + { + /* We do not know the value of the entire batch, so we can check + neither the reserve signature nor the total; still debit the + reserve by the amount the exchange claims. The row inconsistency + reported above states that we could not verify it. */ + TALER_ARL_amount_add (&rs->total_out, + &rs->total_out, + amount_with_fee); + return GNUNET_OK; + } + if (age_proof_required && + (! have_age_mask)) + { + /* Without a denomination we do not know the age mask the reserve + signature was made over. */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Age-restricted withdraw row %llu has no denominations\n", + (unsigned long long) rowid); + report_row_inconsistency ("withdraw", + rowid, + "no denomination given for age-restricted withdraw"); + if (global_qs < 0) + return GNUNET_SYSERR; + return GNUNET_OK; + } + /* check reserve_sig (first: setup remaining members of wsrd) */ if (GNUNET_OK != TALER_wallet_withdraw_verify ( @@ -718,7 +770,7 @@ handle_withdrawals ( h_planchets, blinding_seed, age_proof_required - ? &issue->age_mask + ? &age_mask : NULL, age_proof_required ? max_age @@ -773,7 +825,7 @@ handle_withdrawals ( TALER_amount2s (&auditor_amount_with_fee)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Increasing withdraw profits by fee %s\n", - TALER_amount2s (&issue->fees.withdraw)); + TALER_amount2s (&auditor_fee)); TALER_ARL_amount_add (&rs->total_out, &rs->total_out, &auditor_amount_with_fee);