exchange

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

commit 89fd00cbe83163c0429e83df608df85169ba334b
parent d939c1a03f0518c61143c2cca51f5b40cdba069c
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue,  4 Nov 2025 14:03:25 +0100

implement #9316

Diffstat:
Msrc/auditor/Makefile.am | 1+
Msrc/auditor/taler-auditor-httpd.c | 9+++++++++
Msrc/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-get.h | 6+++---
Asrc/auditor/taler-auditor-httpd_pending-deposits-get.c | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditor/taler-auditor-httpd_pending-deposits-get.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/pg_select_early_aggregations.c | 173+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/pg_select_early_aggregations.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 424 insertions(+), 3 deletions(-)

diff --git a/src/auditor/Makefile.am b/src/auditor/Makefile.am @@ -199,6 +199,7 @@ taler_auditor_httpd_SOURCES = \ taler-auditor-httpd_bad-sig-losses-get.c taler-auditor-httpd_bad-sig-losses-get.h \ taler-auditor-httpd_closure-lags-get.c taler-auditor-httpd_closure-lags-get.h \ taler-auditor-httpd_progress-get.c taler-auditor-httpd_progress-get.h \ + taler-auditor-httpd_pending-deposits-get.c taler-auditor-httpd_pending-deposits-get.h \ taler-auditor-httpd_reserve-in-inconsistency-get.c taler-auditor-httpd_reserve-in-inconsistency-get.h \ taler-auditor-httpd_reserve-not-closed-inconsistency-get.c taler-auditor-httpd_reserve-not-closed-inconsistency-get.h \ taler-auditor-httpd_denominations-without-sigs-get.c taler-auditor-httpd_denominations-without-sigs-get.h \ diff --git a/src/auditor/taler-auditor-httpd.c b/src/auditor/taler-auditor-httpd.c @@ -54,6 +54,7 @@ #include "taler-auditor-httpd_denominations-without-sigs-get.h" #include "taler-auditor-httpd_misattribution-in-inconsistency-get.h" #include "taler-auditor-httpd_reserves-get.h" +#include "taler-auditor-httpd_pending-deposits-get.h" #include "taler-auditor-httpd_purses-get.h" #include "taler-auditor-httpd_historic-denomination-revenue-get.h" #include "taler-auditor-httpd_historic-reserve-summary-get.h" @@ -344,6 +345,14 @@ handle_mhd_request (void *cls, .handler = &TAH_DEPOSIT_CONFIRMATION_handler_get, .response_code = MHD_HTTP_OK, .requires_auth = true }, + { .url = "/monitoring/pending-deposits", + .method = MHD_HTTP_METHOD_GET, + .mime_type = "application/json", + .data = NULL, + .data_size = 0, + .handler = &TAH_pending_deposits_handler_get, + .response_code = MHD_HTTP_OK, + .requires_auth = true }, { .url = "/monitoring/deposit-confirmation", .method = MHD_HTTP_METHOD_DELETE, .mime_type = "application/json", diff --git a/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-get.h b/src/auditor/taler-auditor-httpd_amount-arithmetic-inconsistency-get.h @@ -13,8 +13,8 @@ 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/> */ -#ifndef SRC_TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_GET_H -#define SRC_TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_GET_H +#ifndef TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_GET_H +#define TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_GET_H #include <gnunet/gnunet_util_lib.h> #include <microhttpd.h> @@ -53,4 +53,4 @@ TAH_AMOUNT_ARITHMETIC_INCONSISTENCY_handler_get (struct TAH_RequestHandler *rh, const char *const args[]); -#endif // SRC_TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_GET_H +#endif // TALER_AUDITOR_HTTPD_AMOUNT_ARITHMETIC_INCONSISTENCY_GET_H diff --git a/src/auditor/taler-auditor-httpd_pending-deposits-get.c b/src/auditor/taler-auditor-httpd_pending-deposits-get.c @@ -0,0 +1,143 @@ +/* + This file is part of TALER + Copyright (C) 2025 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/> + */ +#include "taler/platform.h" +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_json_lib.h> +#include <jansson.h> +#include <microhttpd.h> +#include <pthread.h> +#include "taler/taler_json_lib.h" +#include "taler/taler_mhd_lib.h" +#include "taler-auditor-httpd.h" +#include "taler-auditor-httpd_pending-deposits-get.h" + + +/** + * Add pending deposit to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param row_id row ID of the alert in the auditor database + * @param batch_deposit_serial_id where in the exchange table are we + * @param total_amount value of all missing deposits, including fees + * @param wire_target_h_payto hash of the recipient account's payto URI + * @param deadline what was the earliest requested wire transfer deadline + * @param suppressed true if this report was suppressed + */ +static void +add_pending_deposit ( + void *cls, + uint64_t row_id, + uint64_t batch_deposit_serial_id, + const struct TALER_Amount *total_amount, + const struct TALER_FullPaytoHashP *wire_target_h_payto, + struct GNUNET_TIME_Timestamp deadline, + bool suppressed) +{ + json_t *list = cls; + json_t *obj; + + obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_uint64 ("row_id", + row_id), + GNUNET_JSON_pack_uint64 ("batch_deposit_serial_id", + batch_deposit_serial_id), + TALER_JSON_pack_amount ("total_amount", + total_amount), + GNUNET_JSON_pack_data_auto ("h_wire", + wire_target_h_payto), + GNUNET_JSON_pack_timestamp ("deadline", + deadline), + GNUNET_JSON_pack_bool ("suppressed", + suppressed) + ); + GNUNET_break (0 == + json_array_append_new (list, + obj)); +} + + +MHD_RESULT +TAH_pending_deposits_handler_get ( + struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size, + const char *const args[]) +{ + json_t *ja; + enum GNUNET_DB_QueryStatus qs; + int64_t limit = -20; + uint64_t offset; + bool return_suppressed = false; + + if (GNUNET_SYSERR == + TAH_plugin->preflight (TAH_plugin->cls)) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_SETUP_FAILED, + NULL); + } + TALER_MHD_parse_request_snumber (connection, + "limit", + &limit); + if (limit < 0) + offset = INT64_MAX; + else + offset = 0; + TALER_MHD_parse_request_number (connection, + "offset", + &offset); + { + const char *ret_s = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "return_suppressed"); + if ( (NULL != ret_s) && + (0 == strcmp (ret_s, + "true")) ) + { + return_suppressed = true; + } + } + ja = json_array (); + GNUNET_break (NULL != ja); + qs = TAH_plugin->select_pending_deposits ( + TAH_plugin->cls, + GNUNET_TIME_absolute_get (), + limit, + offset, + return_suppressed, + &add_pending_deposit, + ja); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + json_decref (ja); + TALER_LOG_WARNING ( + "Failed to handle GET /pending-deposits in database\n"); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "select_pending_deposits"); + } + return TALER_MHD_REPLY_JSON_PACK ( + connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_array_steal ("pending_deposits", + ja)); +} diff --git a/src/auditor/taler-auditor-httpd_pending-deposits-get.h b/src/auditor/taler-auditor-httpd_pending-deposits-get.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2025 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/> + */ +#ifndef TALER_AUDITOR_HTTPD_PENDING_DEPOSITS_GET_H +#define TALER_AUDITOR_HTTPD_PENDING_DEPOSITS_GET_H + +#include <gnunet/gnunet_util_lib.h> +#include <microhttpd.h> +#include "taler-auditor-httpd.h" + +/** + * Handle a GET "/pending-deposits" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @param args NULL-terminated array of remaining parts of the URI broken up at '/' + * @return MHD result code + */ +MHD_RESULT +TAH_pending_deposits_handler_get ( + struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size, + const char *const args[]); + + +#endif // TALER_AUDITOR_HTTPD_PENDING_DEPOSITS_GET_H diff --git a/src/auditordb/pg_select_early_aggregations.c b/src/auditordb/pg_select_early_aggregations.c @@ -0,0 +1,173 @@ +/* + This file is part of TALER + Copyright (C) 2025 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 auditordb/pg_select_early_aggregations.c + * @brief Implementation of the select_early_aggregations function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_select_early_aggregations.h" +#include "pg_helper.h" + + +/** + * Closure for #early_aggregation_cb(). + */ +struct EarlyAggregationContext +{ + + /** + * Function to call for each early aggregation. + */ + TALER_AUDITORDB_EarlyAggregationsCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct PostgresClosure *pg; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #TAH_PG_select_purse_expired(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct EarlyAggregationContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +early_aggregation_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct EarlyAggregationContext *eic = cls; + struct PostgresClosure *pg = eic->pg; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_EarlyAggregation ea; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &ea.row_id), + GNUNET_PQ_result_spec_uint64 ("batch_deposit_serial_id", + &ea.batch_deposit_serial_id), + GNUNET_PQ_result_spec_uint64 ("tracking_serial_id", + &ea.tracking_serial_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &ea.total), + GNUNET_PQ_result_spec_bool ("suppressed", + &ea.suppressed), + GNUNET_PQ_result_spec_end + }; + + /* just to be safe in case the structure changes */ + memset (&ea, + 0, + sizeof (ea)); + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + eic->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + eic->cb (eic->cb_cls, + &ea); + } + eic->qs = num_results; +} + + +enum GNUNET_DB_QueryStatus +TAH_PG_select_early_aggregations ( + void *cls, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_EarlyAggregationsCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + uint64_t ulimit = (limit < 0) ? -limit : limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_end + }; + struct EarlyAggregationContext eic = { + .cb = cb, + .cb_cls = cb_cls, + .pg = pg + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "auditor_select_early_aggregations_asc", + "SELECT" + " row_id" + ",batch_deposit_serial_id" + ",tracking_serial_id" + ",amount" + ",suppressed" + " FROM auditor_early_aggregations" + " WHERE row_id > $1" + " AND ($3 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $2;"); + PREPARE (pg, + "auditor_select_early_aggregations_desc", + "SELECT" + " row_id" + ",batch_deposit_serial_id" + ",tracking_serial_id" + ",amount" + ",suppressed" + " FROM auditor_early_aggregations" + " WHERE row_id < $1" + " AND ($3 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $2;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + (limit < 0) + ? "auditor_select_early_aggregations_desc" + : "auditor_select_early_aggregations_asc ", + params, + &early_aggregation_cb, + &eic); + if (0 > qs) + return qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != eic.qs); + return eic.qs; +} diff --git a/src/auditordb/pg_select_early_aggregations.h b/src/auditordb/pg_select_early_aggregations.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2025 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 auditordb/pg_select_early_aggregations.h + * @brief implementation of the select_early_aggregations function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_SELECT_EARLY_AGGREGATIONS_H +#define PG_SELECT_EARLY_AGGREGATIONS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + +/** + * Returns all aggregations that were found that were done + * too early. + * + * @param cls closure + * @param limit number of rows to return, negative to iterate backwards + * @param offset starting offset, exclusive + * @param return_suppressed true to also return suppressed events + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TAH_PG_select_early_aggregations ( + void *cls, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_EarlyAggregationsCallback cb, + void *cb_cls); + + +#endif