exchange

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

commit 12b87cf4f96005a78dfb33c2cb69801c72f319b5
parent 830ebef2ea959ccbec0d62a04b947a020ff278c8
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Sat,  3 Aug 2024 18:51:46 +0200

fix KYC long-polling logic

Diffstat:
Msrc/benchmark/.gitignore | 1+
Msrc/exchange/taler-exchange-httpd_kyc-check.c | 55++++++++++++++++++++++++++++++++++++-------------------
Msrc/exchange/taler-exchange-httpd_kyc-info.c | 16++++++++++++++--
Msrc/exchangedb/Makefile.am | 1+
Msrc/exchangedb/pg_insert_aml_decision.c | 7-------
Msrc/exchangedb/pg_insert_kyc_attributes.c | 7-------
Msrc/exchangedb/pg_insert_kyc_failure.c | 4----
Asrc/exchangedb/pg_lookup_h_payto_by_access_token.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/pg_lookup_h_payto_by_access_token.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Msrc/exchangedb/pg_update_kyc_process_by_row.c | 6------
Msrc/exchangedb/plugin_exchangedb_postgres.c | 3+++
Msrc/include/taler_exchangedb_plugin.h | 21+++++++++++++++++++--
12 files changed, 178 insertions(+), 47 deletions(-)

diff --git a/src/benchmark/.gitignore b/src/benchmark/.gitignore @@ -1,3 +1,4 @@ taler-bank-benchmark taler-aggregator-benchmark *.edited +libeufin-bank.pid diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c b/src/exchange/taler-exchange-httpd_kyc-check.c @@ -229,25 +229,6 @@ TEH_handler_kyc_check ( &kyp->timeout); } - if ( (NULL == kyp->eh) && - GNUNET_TIME_absolute_is_future (kyp->timeout) ) - { - struct TALER_KycCompletedEventP rep = { - .header.size = htons (sizeof (rep)), - .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), - // .h_payto = kyp->h_payto // FIXME: h_payto not available here yet! - }; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Starting DB event listening\n"); - kyp->eh = TEH_plugin->event_listen ( - TEH_plugin->cls, - GNUNET_TIME_absolute_get_remaining (kyp->timeout), - &rep.header, - &db_event_cb, - rc); - } - if (! TALER_KYCLOGIC_is_enabled ()) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -341,7 +322,43 @@ TEH_handler_kyc_check ( if (kyc_required && GNUNET_TIME_absolute_is_future (kyp->timeout)) { + enum GNUNET_DB_QueryStatus qs; + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + }; + json_decref (jlimits); + if (NULL == kyp->eh) + { + /* FIXME-Performance: consider modifying lookup_kyc_requirement_by_row + to immediately return h_payto as well... */ + qs = TEH_plugin->lookup_h_payto_by_access_token ( + TEH_plugin->cls, + &access_token, + &rep.h_payto); + if (qs < 0) + { + GNUNET_break (0); + return TALER_MHD_reply_with_ec ( + rc->connection, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "lookup_h_payto_by_access_token"); + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting DB event listening\n"); + kyp->eh = TEH_plugin->event_listen ( + TEH_plugin->cls, + GNUNET_TIME_absolute_get_remaining (kyp->timeout), + &rep.header, + &db_event_cb, + rc); + /* goes again *immediately* (without suspending) + now that long-poller is in place; we will suspend + in the *next* iteration. */ + return MHD_YES; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Suspending HTTP request on timeout (%s) now...\n", GNUNET_TIME_relative2s (GNUNET_TIME_absolute_get_remaining ( diff --git a/src/exchange/taler-exchange-httpd_kyc-info.c b/src/exchange/taler-exchange-httpd_kyc-info.c @@ -373,10 +373,22 @@ TEH_handler_kyc_info ( { struct TALER_KycCompletedEventP rep = { .header.size = htons (sizeof (rep)), - .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), - .access_token = kyp->access_token + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED) }; + qs = TEH_plugin->lookup_h_payto_by_access_token ( + TEH_plugin->cls, + &kyp->access_token, + &rep.h_payto); + if (qs < 0) + { + GNUNET_break (0); + return TALER_MHD_reply_with_ec ( + rc->connection, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "lookup_h_payto_by_access_token"); + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting DB event listening\n"); kyp->eh = TEH_plugin->event_listen ( diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am @@ -149,6 +149,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_persist_policy_details.h pg_persist_policy_details.c \ pg_do_deposit.h pg_do_deposit.c \ pg_get_wire_hash_for_contract.h pg_get_wire_hash_for_contract.c \ + pg_lookup_h_payto_by_access_token.h pg_lookup_h_payto_by_access_token.c \ pg_add_policy_fulfillment_proof.h pg_add_policy_fulfillment_proof.c \ pg_do_melt.h pg_do_melt.c \ pg_do_refund.h pg_do_refund.c \ diff --git a/src/exchangedb/pg_insert_aml_decision.c b/src/exchangedb/pg_insert_aml_decision.c @@ -43,9 +43,6 @@ TEH_PG_insert_aml_decision ( struct GNUNET_TIME_Timestamp *last_date) { struct PostgresClosure *pg = cls; -#if FIXME - /* We used to do h_payto, now we need the - account access token! */ struct TALER_KycCompletedEventP rep = { .header.size = htons (sizeof (rep)), .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), @@ -53,10 +50,6 @@ TEH_PG_insert_aml_decision ( }; char *notify_s = GNUNET_PQ_get_event_notify_channel (&rep.header); -#else - char *notify_s - = GNUNET_strdup ("FIXME"); -#endif struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (h_payto), GNUNET_PQ_query_param_timestamp (&decision_time), diff --git a/src/exchangedb/pg_insert_kyc_attributes.c b/src/exchangedb/pg_insert_kyc_attributes.c @@ -48,9 +48,6 @@ TEH_PG_insert_kyc_attributes ( struct PostgresClosure *pg = cls; struct GNUNET_TIME_Timestamp expiration = GNUNET_TIME_absolute_to_timestamp (expiration_time); -#if FIXME - /* We used to do h_payto, now we need the - account access token! */ struct TALER_KycCompletedEventP rep = { .header.size = htons (sizeof (rep)), .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), @@ -58,10 +55,6 @@ TEH_PG_insert_kyc_attributes ( }; char *kyc_completed_notify_s = GNUNET_PQ_get_event_notify_channel (&rep.header); -#else - char *kyc_completed_notify_s - = GNUNET_strdup ("FIXME"); -#endif struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&process_row), GNUNET_PQ_query_param_auto_from_type (h_payto), diff --git a/src/exchangedb/pg_insert_kyc_failure.c b/src/exchangedb/pg_insert_kyc_failure.c @@ -74,9 +74,6 @@ TEH_PG_insert_kyc_failure ( if (qs > 0) { /* FIXME: might want to do this eventually in the same transaction... */ -#if FIXME - /* We used to do h_payto, now we need the - account access token! */ struct TALER_KycCompletedEventP rep = { .header.size = htons (sizeof (rep)), .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), @@ -87,7 +84,6 @@ TEH_PG_insert_kyc_failure ( &rep.header, NULL, 0); -#endif } return qs; } diff --git a/src/exchangedb/pg_lookup_h_payto_by_access_token.c b/src/exchangedb/pg_lookup_h_payto_by_access_token.c @@ -0,0 +1,59 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_lookup_h_payto_by_access_token.c + * @brief Implementation of the lookup_h_payto_by_access_token function for Postgres + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" +#include "pg_lookup_h_payto_by_access_token.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +TEH_PG_lookup_h_payto_by_access_token ( + void *cls, + const struct TALER_AccountAccessTokenP *access_token, + struct TALER_PaytoHashP *h_payto) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (access_token), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ( + "wire_target_h_payto", + h_payto), + GNUNET_PQ_result_spec_end + }; + + PREPARE (pg, + "lookup_h_payto_by_access_token", + "SELECT " + " wire_target_h_payto" + " FROM wire_targets" + " WHERE (access_token = $1);"); + return GNUNET_PQ_eval_prepared_singleton_select ( + pg->conn, + "lookup_h_payto_by_access_token", + params, + rs); + +} diff --git a/src/exchangedb/pg_lookup_h_payto_by_access_token.h b/src/exchangedb/pg_lookup_h_payto_by_access_token.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_lookup_h_payto_by_access_token.h + * @brief implementation of the lookup_h_payto_by_access_token function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_LOOKUP_H_PAYTO_BY_ACCESS_TOKEN_H +#define PG_LOOKUP_H_PAYTO_BY_ACCESS_TOKEN_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * Lookup @a h_payto based on an @a access_token. + * + * @param cls closure + * @param access_token + * set to token for access control + * @param[out] h_payto set to the the hash of the + * payto URI of the account (if found) + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_PG_lookup_h_payto_by_access_token ( + void *cls, + const struct TALER_AccountAccessTokenP *access_token, + struct TALER_PaytoHashP *h_payto); + +#endif diff --git a/src/exchangedb/pg_update_kyc_process_by_row.c b/src/exchangedb/pg_update_kyc_process_by_row.c @@ -98,13 +98,11 @@ TEH_PG_update_kyc_process_by_row ( if (GNUNET_TIME_absolute_is_future (expiration)) { enum GNUNET_DB_QueryStatus qs2; -#if FIXME struct TALER_KycCompletedEventP rep = { .header.size = htons (sizeof (rep)), .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), .h_payto = *h_payto }; -#endif uint32_t trigger_type = 1; struct GNUNET_PQ_QueryParam params2[] = { GNUNET_PQ_query_param_auto_from_type (h_payto), @@ -112,14 +110,10 @@ TEH_PG_update_kyc_process_by_row ( GNUNET_PQ_query_param_end }; -#if FIXME - /* We used to do h_payto, now we need the - account access token! */ GNUNET_PQ_event_notify (pg->conn, &rep.header, NULL, 0); -#endif PREPARE (pg, "alert_kyc_status_change", "INSERT INTO kyc_alerts" diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c @@ -41,6 +41,7 @@ #include "pg_do_reserve_open.h" #include "pg_get_coin_transactions.h" #include "pg_get_expired_reserves.h" +#include "pg_lookup_h_payto_by_access_token.h" #include "pg_get_purse_request.h" #include "pg_get_reserve_history.h" #include "pg_get_unfinished_close_requests.h" @@ -765,6 +766,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &TEH_PG_add_denomination_key; plugin->lookup_signing_key = &TEH_PG_lookup_signing_key; + plugin->lookup_h_payto_by_access_token + = &TEH_PG_lookup_h_payto_by_access_token; plugin->begin_shard = &TEH_PG_begin_shard; plugin->abort_shard diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -238,9 +238,9 @@ struct TALER_KycCompletedEventP struct GNUNET_DB_EventHeaderP header; /** - * Access token the KYC was completed for. + * Hash of payto://-URI for which the KYC state changed. */ - struct TALER_AccountAccessTokenP access_token; + struct TALER_PaytoHashP h_payto; }; @@ -7379,6 +7379,23 @@ struct TALER_EXCHANGEDB_Plugin /** + * Lookup @a h_payto based on an @a access_token. + * + * @param cls closure + * @param access_token + * set to token for access control + * @param[out] h_payto set to the the hash of the + * payto URI of the account (if found) + * @return database transaction status + */ + enum GNUNET_DB_QueryStatus + (*lookup_h_payto_by_access_token)( + void *cls, + const struct TALER_AccountAccessTokenP *access_token, + struct TALER_PaytoHashP *h_payto); + + + /** * Lookup measure data for a legitimization process. * * @param cls closure