commit 73c070c5bbe418f95774d8eedf5b43cebe037fb6
parent 2459fbdd7fbb320ca4723447add0a00276041d3e
Author: Florian Dold <dold@taler.net>
Date: Wed, 9 Sep 2026 15:57:49 +0200
merchantdb: wake KYC checker when status is requested
Send the KYC_UPDATE_FORCED notification when reading account KYC
status. The previous channel belonged to ACCOUNTS_CHANGED, whose
handler leaves existing inquiries on their periodic schedule. A
merchant could therefore keep reporting pending KYC after the exchange
had completed it, until the checker was restarted or its delay expired.
Issue: https://bugs.taler.net/n/11783
Diffstat:
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/src/backenddb/iterate_kyc_statuses.sql b/src/backenddb/iterate_kyc_statuses.sql
@@ -71,7 +71,7 @@ BEGIN
UPDATE merchant_kyc
SET next_kyc_poll=in_now
WHERE kyc_serial_id = my_kyc_record.kyc_serial_id;
- NOTIFY XDQM4Z4N0D3GX0H9JEXH70EBC2T3KY7HC0TJB0Z60D2H781RXR6AG; -- MERCHANT_EXCHANGE_KYC_UPDATE_FORCED
+ NOTIFY XJ40P0CFMZ0DT6SFZ70VRQ19KG1HP6AJ1Q6VCDZN4N2FGPSAG4KDG; -- MERCHANT_EXCHANGE_KYC_UPDATE_FORCED
RETURN QUERY
SELECT
my_h_wire,
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
@@ -8370,10 +8370,16 @@ test_insert_kyc_failure (
.size = htons (sizeof (general_event)),
.type = htons (TALER_DBEVENT_MERCHANT_KYC_STATUS_CHANGED)
};
+ struct GNUNET_DB_EventHeaderP refresh_event = {
+ .size = htons (sizeof (refresh_event)),
+ .type = htons (TALER_DBEVENT_MERCHANT_EXCHANGE_KYC_UPDATE_FORCED)
+ };
struct GNUNET_DB_EventHandler *account_eh = NULL;
struct GNUNET_DB_EventHandler *general_eh = NULL;
+ struct GNUNET_DB_EventHandler *refresh_eh = NULL;
unsigned int account_events = 0;
unsigned int general_events = 0;
+ unsigned int refresh_events = 0;
struct KycFailureExpected expected = {
.account = account,
.exchange_url = exchange_url,
@@ -8409,6 +8415,17 @@ test_insert_kyc_failure (
"Failed to listen for general KYC events\n");
goto cleanup;
}
+ refresh_eh = TALER_MERCHANTDB_event_listen (
+ pg,
+ &refresh_event,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &kyc_event_cb,
+ &refresh_events);
+ if (NULL == refresh_eh)
+ {
+ GNUNET_break (0);
+ goto cleanup;
+ }
expected.timestamp = GNUNET_TIME_timestamp_get ();
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
@@ -8458,6 +8475,19 @@ test_insert_kyc_failure (
"Inserted KYC failure did not match expectations\n");
goto cleanup;
}
+ /* Reading the status must wake the KYC checker, including an inquiry
+ sleeping until its next periodic check. An ACCOUNTS_CHANGED event
+ reloads the account list but leaves existing inquiries asleep. */
+ GNUNET_PQ_event_do_poll (pg->conn);
+ if (1 != refresh_events)
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Reading KYC status generated %u forced refresh events,"
+ " expected one\n",
+ refresh_events);
+ goto cleanup;
+ }
expected.timestamp = GNUNET_TIME_timestamp_get ();
expected.exchange_http_status = MHD_HTTP_ACCEPTED;
@@ -8510,9 +8540,21 @@ test_insert_kyc_failure (
"Updated KYC failure did not match expectations\n");
goto cleanup;
}
+ GNUNET_PQ_event_do_poll (pg->conn);
+ if (2 != refresh_events)
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Reading updated KYC status generated %u forced refresh"
+ " events, expected two\n",
+ refresh_events);
+ goto cleanup;
+ }
ret = 0;
cleanup:
+ if (NULL != refresh_eh)
+ TALER_MERCHANTDB_event_listen_cancel (refresh_eh);
if (NULL != general_eh)
TALER_MERCHANTDB_event_listen_cancel (general_eh);
if (NULL != account_eh)