commit 4732a631de54c23b7e81be64b7a9b66cd497c5a4
parent 9ea74128d8f25d758de8d9319176a33cfda0b222
Author: Christian Grothoff <christian@grothoff.org>
Date: Sat, 10 Oct 2026 17:32:25 +0200
implement v2/vLimitConflict
Diffstat:
6 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/src/donau/donau-httpd_get-config.h b/src/donau/donau-httpd_get-config.h
@@ -41,12 +41,11 @@
*
* Returned via both /config and /keys endpoints.
*/
-/* Revision bumped from 0 to 1: POST /batch-submit now answers 409
- DONAU_DONOR_IDENTIFIER_NONCE_REUSE for receipts it cannot store,
- where it used to answer 201 Created and drop them. `current' is
- unchanged: no request or response schema changed, and a client that
- never reuses a nonce sees no difference. */
-#define DONAU_PROTOCOL_VERSION "1:1:1"
+/* v2: POST /batch-issue answers an exceeded yearly donation limit with
+ 409 instead of 400 (same error code), so that clients can tell it
+ apart from a malformed request. Clients that dispatch on the error
+ code see no difference, hence `age' is incremented as well. */
+#define DONAU_PROTOCOL_VERSION "2:0:2"
/**
diff --git a/src/donau/donau-httpd_post-batch-issue-CHARITY_ID.c b/src/donau/donau-httpd_post-batch-issue-CHARITY_ID.c
@@ -572,14 +572,13 @@ start:
}
if (! smaller_than_max_per_year)
{
- GNUNET_break_op (0);
free_bkps (num_bkps,
bkps);
json_decref (blind_signatures);
for (unsigned int i = 0; i<num_bkps; i++)
GNUNET_CRYPTO_blinded_sig_decref (du_sigs[i].blinded_sig);
return TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_BAD_REQUEST,
+ MHD_HTTP_CONFLICT,
TALER_EC_DONAU_EXCEEDING_DONATION_LIMIT,
NULL);
}
diff --git a/src/lib/donau_api_batch_issue_receipts.c b/src/lib/donau_api_batch_issue_receipts.c
@@ -266,7 +266,8 @@ handle_batch_issue_finished (void *cls,
biresp.hr.hint = TALER_JSON_get_error_hint (j);
break;
case MHD_HTTP_CONFLICT:
- // Donation limit is not sufficient
+ // wrong year for the donation unit, or donation limit is not
+ // sufficient (the latter was a 400 before protocol v2)
biresp.hr.ec = TALER_JSON_get_error_code (j);
biresp.hr.hint = TALER_JSON_get_error_hint (j);
break;
diff --git a/src/lib/donau_api_handle.c b/src/lib/donau_api_handle.c
@@ -37,12 +37,12 @@
* Which version of the Donau protocol is implemented
* by this library? Used to determine compatibility.
*/
-#define DONAU_PROTOCOL_CURRENT 1
+#define DONAU_PROTOCOL_CURRENT 2
/**
* How many versions are we backwards compatible with?
*/
-#define DONAU_PROTOCOL_AGE 1
+#define DONAU_PROTOCOL_AGE 2
/**
* Set to 1 for extra debug logging.
diff --git a/src/testing/test_donau_api.c b/src/testing/test_donau_api.c
@@ -112,6 +112,24 @@ run (void *cls,
"1234", // salt for tax id hash
"EUR:5", /* Amount to be issued*/
MHD_HTTP_OK),
+ /* EUR:5 + EUR:11 exceeds the yearly limit of EUR:15 */
+ TALER_TESTING_cmd_issue_receipts ("issue-receipts-over-limit",
+ "patch-charity",
+ uses_cs,
+ GNUNET_TIME_get_current_year (),
+ "7560001010000", // tax id
+ "1234", // salt for tax id hash
+ "EUR:11", /* Amount to be issued*/
+ MHD_HTTP_CONFLICT),
+ /* the refused request did not use up any of the limit */
+ TALER_TESTING_cmd_issue_receipts ("issue-receipts-up-to-limit",
+ "patch-charity",
+ uses_cs,
+ GNUNET_TIME_get_current_year (),
+ "7560001010000", // tax id
+ "1234", // salt for tax id hash
+ "EUR:10", /* Amount to be issued*/
+ MHD_HTTP_OK),
TALER_TESTING_cmd_submit_receipts ("submit-receipts",
"issue-receipts", // cmd trait reference
GNUNET_TIME_get_current_year (),
diff --git a/src/testing/testing_api_cmd_issue_receipts.c b/src/testing/testing_api_cmd_issue_receipts.c
@@ -192,6 +192,11 @@ issue_receipts_status_cb (struct StatusState *ss,
TALER_TESTING_interpreter_fail (ss->is);
return;
}
+ if (MHD_HTTP_OK != biresp->hr.http_status)
+ {
+ TALER_TESTING_interpreter_next (ss->is);
+ return;
+ }
{
struct DONAU_BlindedDonationUnitSignature *blinded_sigs =
biresp->details.ok.blinded_sigs;
@@ -566,9 +571,11 @@ cleanup (void *cls,
GNUNET_free (ss->blinding_secrets);
if (NULL != ss->receipts)
{
+ /* receipts are only signed if the Donau answered 200 */
for (unsigned int i = 0; i < ss->num_bkp; i++)
- GNUNET_CRYPTO_unblinded_sig_decref (
- ss->receipts[i].donation_unit_sig.unblinded_sig);
+ if (NULL != ss->receipts[i].donation_unit_sig.unblinded_sig)
+ GNUNET_CRYPTO_unblinded_sig_decref (
+ ss->receipts[i].donation_unit_sig.unblinded_sig);
GNUNET_free (ss->receipts);
}
if (NULL != ss->bkps)