commit 6cd56c6daebe4404c8f1b5e632ee934f65eb5817 parent 36e90d8b5367468ecd77f0e0b4cd2a1a2b663609 Author: Christian Grothoff <christian@grothoff.org> Date: Sun, 16 Feb 2025 14:36:36 +0100 implement protocol v25 Diffstat:
13 files changed, 522 insertions(+), 58 deletions(-)
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am @@ -150,6 +150,7 @@ taler_exchange_httpd_SOURCES = \ taler-exchange-httpd_aml-decisions-get.c \ taler-exchange-httpd_aml-statistics-get.c taler-exchange-httpd_aml-statistics-get.h \ taler-exchange-httpd_aml-measures-get.c taler-exchange-httpd_aml-measures-get.h \ + taler-exchange-httpd_aml-transfer-get.c taler-exchange-httpd_aml-transfer-get.h \ taler-exchange-httpd_auditors.c taler-exchange-httpd_auditors.h \ taler-exchange-httpd_batch-deposit.c taler-exchange-httpd_batch-deposit.h \ taler-exchange-httpd_coins_get.c taler-exchange-httpd_coins_get.h \ diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c @@ -36,6 +36,7 @@ #include "taler-exchange-httpd_aml-attributes-get.h" #include "taler-exchange-httpd_aml-decision.h" #include "taler-exchange-httpd_aml-statistics-get.h" +#include "taler-exchange-httpd_aml-transfer-get.h" #include "taler-exchange-httpd_aml-measures-get.h" #include "taler-exchange-httpd_auditors.h" #include "taler-exchange-httpd_batch-deposit.h" @@ -611,6 +612,14 @@ handle_get_aml (struct TEH_RequestContext *rc, .handler = &TEH_handler_aml_measures_get }, { + .op = "transfers-credit", + .handler = &TEH_handler_aml_transfer_credit_get + }, + { + .op = "transfers-debit", + .handler = &TEH_handler_aml_transfer_debit_get + }, + { .op = NULL, .handler = NULL }, diff --git a/src/exchange/taler-exchange-httpd_aml-decisions-get.c b/src/exchange/taler-exchange-httpd_aml-decisions-get.c @@ -143,33 +143,6 @@ TEH_handler_aml_decisions_get ( TALER_EXCHANGE_YNA_ALL, &investigation_filter); { - enum GNUNET_DB_QueryStatus qs; - - qs = TEH_plugin->test_aml_officer (TEH_plugin->cls, - officer_pub); - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - return TALER_MHD_reply_with_error ( - rc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "test_aml_officer"); - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - GNUNET_break_op (0); - return TALER_MHD_reply_static ( - rc->connection, - MHD_HTTP_FORBIDDEN, - NULL, - NULL, - 0); - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - break; - } - } - { json_t *records; enum GNUNET_DB_QueryStatus qs; diff --git a/src/exchange/taler-exchange-httpd_config.h b/src/exchange/taler-exchange-httpd_config.h @@ -41,7 +41,7 @@ * * Returned via both /config and /keys endpoints. */ -#define EXCHANGE_PROTOCOL_VERSION "24:0:7" +#define EXCHANGE_PROTOCOL_VERSION "25:0:8" /** diff --git a/src/exchange/taler-exchange-httpd_legitimization-measures-get.c b/src/exchange/taler-exchange-httpd_legitimization-measures-get.c @@ -122,33 +122,6 @@ TEH_handler_legitimization_measures_get ( TALER_EXCHANGE_YNA_ALL, &active_filter); { - enum GNUNET_DB_QueryStatus qs; - - qs = TEH_plugin->test_aml_officer (TEH_plugin->cls, - officer_pub); - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - return TALER_MHD_reply_with_error ( - rc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "test_aml_officer"); - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - GNUNET_break_op (0); - return TALER_MHD_reply_static ( - rc->connection, - MHD_HTTP_FORBIDDEN, - NULL, - NULL, - 0); - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - break; - } - } - { json_t *measures; enum GNUNET_DB_QueryStatus qs; diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am @@ -283,6 +283,8 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_select_contract.h pg_select_contract.c \ pg_select_contract_by_purse.h pg_select_contract_by_purse.c \ pg_select_deposit_amounts_for_kyc_check.h pg_select_deposit_amounts_for_kyc_check.c \ + pg_select_exchange_credit_transfers.h pg_select_exchange_credit_transfers.c \ + pg_select_exchange_debit_transfers.h pg_select_exchange_debit_transfers.c \ pg_select_kyc_attributes.h pg_select_kyc_attributes.c \ pg_select_merge_amounts_for_kyc_check.h pg_select_merge_amounts_for_kyc_check.c \ pg_select_purse.h pg_select_purse.c \ diff --git a/src/exchangedb/pg_select_exchange_credit_transfers.c b/src/exchangedb/pg_select_exchange_credit_transfers.c @@ -0,0 +1,170 @@ +/* + 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 exchangedb/pg_select_exchange_credit_transfers.c + * @brief Implementation of the select_exchange_credit_transfers 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_select_exchange_credit_transfers.h" +#include "pg_helper.h" + +/** + * Closure for #handle_aml_result. + */ +struct SelectTransferContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlTransferCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct PostgresClosure *pg; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #TEH_PG_select_exchange_debit_transfers(). + * + * @param cls closure of type `struct SelectTransferContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_transfer_result (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct SelectTransferContext *stc = cls; + struct PostgresClosure *pg = stc->pg; + + for (unsigned int i = 0; i<num_results; i++) + { + char *payto_uri; + uint64_t rowid; + struct GNUNET_TIME_Absolute execution_time; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial_id", + &rowid), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri), + GNUNET_PQ_result_spec_absolute_time ("execution_time", + &execution_time), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + stc->status = GNUNET_SYSERR; + return; + } + stc->cb (stc->cb_cls, + rowid, + payto_uri, + execution_time, + &amount); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +TEH_PG_select_exchange_credit_transfers ( + void *cls, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct SelectTransferContext stc = { + .pg = pg, + .cb = cb, + .cb_cls = cb_cls, + .status = GNUNET_OK + }; + 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_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "select_exchange_credit_transfers_inc", + "SELECT" + " ri.reserve_in_serial_id AS serial_id" + ",wt.payto_uri" + ",ri.execution_date AS execution_time" + ",ri.credit AS amount" + " FROM reserves_in ri" + " LEFT JOIN wire_targets wt" + " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE (ri.reserve_in_serial_id > $1)" + " ORDER BY ri.reserve_in_serial_id ASC" + " LIMIT $2"); + PREPARE (pg, + "select_exchange_credit_transfers_dec", + "SELECT" + " ri.reserve_in_serial_id AS serial_id" + ",wt.payto_uri" + ",ri.execution_date AS execution_time" + ",ri.credit AS amount" + " FROM reserves_in ri" + " LEFT JOIN wire_targets wt" + " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE (ri.reserve_in_serial_id < $1)" + " ORDER BY ri.reserve_in_serial_id DESC" + " LIMIT $2"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + (limit > 0) + ? "select_exchange_credit_transfers_inc" + : "select_exchange_credit_transfers_dec", + params, + &handle_transfer_result, + &stc); + if (GNUNET_OK != stc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/pg_select_exchange_credit_transfers.h b/src/exchangedb/pg_select_exchange_credit_transfers.h @@ -0,0 +1,49 @@ +/* + 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 exchangedb/pg_select_exchange_credit_transfers.h + * @brief implementation of the select_exchange_credit_transfers function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_SELECT_EXCHANGE_CREDIT_TRANSFERS_H +#define PG_SELECT_EXCHANGE_CREDIT_TRANSFERS_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * Return AML-relevant wire transfer credit data. + * + * @param cls closure + * @param threshold minimum wire amount to return data for + * @param offset offset in table to filter by + * @param limit maximum number of entries to return, negative for descending + * @param cb function to call on each result + * @param cb_cls closure to pass to @a cb + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_PG_select_exchange_credit_transfers ( + void *cls, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls); + +#endif diff --git a/src/exchangedb/pg_select_exchange_debit_transfers.c b/src/exchangedb/pg_select_exchange_debit_transfers.c @@ -0,0 +1,171 @@ +/* + 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 exchangedb/pg_select_exchange_debit_transfers.c + * @brief Implementation of the select_exchange_debit_transfers 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_select_exchange_debit_transfers.h" +#include "pg_helper.h" + + +/** + * Closure for #handle_aml_result. + */ +struct SelectTransferContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlTransferCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct PostgresClosure *pg; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #TEH_PG_select_exchange_debit_transfers(). + * + * @param cls closure of type `struct SelectTransferContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_transfer_result (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct SelectTransferContext *stc = cls; + struct PostgresClosure *pg = stc->pg; + + for (unsigned int i = 0; i<num_results; i++) + { + char *payto_uri; + uint64_t rowid; + struct GNUNET_TIME_Absolute execution_time; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial_id", + &rowid), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri), + GNUNET_PQ_result_spec_absolute_time ("execution_time", + &execution_time), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + stc->status = GNUNET_SYSERR; + return; + } + stc->cb (stc->cb_cls, + rowid, + payto_uri, + execution_time, + &amount); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +TEH_PG_select_exchange_debit_transfers ( + void *cls, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct SelectTransferContext stc = { + .pg = pg, + .cb = cb, + .cb_cls = cb_cls, + .status = GNUNET_OK + }; + 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_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "select_exchange_debit_transfers_inc", + "SELECT" + " wo.wireout_uuid AS serial_id" + ",wt.payto_uri" + ",wo.execution_date AS execution_time" + ",wo.amount" + " FROM wire_out wo" + " LEFT JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " WHERE (wo.wireout_uuid > $1)" + " ORDER BY wo.wireout_uuid ASC" + " LIMIT $2"); + PREPARE (pg, + "select_exchange_debit_transfers_dec", + "SELECT" + " wo.wireout_uuid AS serial_id" + ",wt.payto_uri" + ",wo.execution_date AS execution_time" + ",wo.amount" + " FROM wire_out wo" + " LEFT JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " WHERE (wo.wireout_uuid < $1)" + " ORDER BY wo.wireout_uuid DESC" + " LIMIT $2"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + (limit > 0) + ? "select_exchange_debit_transfers_inc" + : "select_exchange_debit_transfers_dec", + params, + &handle_transfer_result, + &stc); + if (GNUNET_OK != stc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/pg_select_exchange_debit_transfers.h b/src/exchangedb/pg_select_exchange_debit_transfers.h @@ -0,0 +1,49 @@ +/* + 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 exchangedb/pg_select_exchange_debit_transfers.h + * @brief implementation of the select_exchange_debit_transfers function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_SELECT_EXCHANGE_DEBIT_TRANSFERS_H +#define PG_SELECT_EXCHANGE_DEBIT_TRANSFERS_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + +/** + * Return AML-relevant wire transfer debit data. + * + * @param cls closure + * @param threshold minimum wire amount to return data for + * @param offset offset in table to filter by + * @param limit maximum number of entries to return, negative for descending + * @param cb function to call on each result + * @param cb_cls closure to pass to @a cb + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_PG_select_exchange_debit_transfers ( + void *cls, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls); + + +#endif diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014--2023 Taler Systems SA + Copyright (C) 2014--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 @@ -187,6 +187,8 @@ #include "pg_select_contract.h" #include "pg_select_contract_by_purse.h" #include "pg_select_deposit_amounts_for_kyc_check.h" +#include "pg_select_exchange_credit_transfers.h" +#include "pg_select_exchange_debit_transfers.h" #include "pg_select_kyc_attributes.h" #include "pg_select_merge_amounts_for_kyc_check.h" #include "pg_select_purse.h" @@ -724,6 +726,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &TEH_PG_lookup_h_payto_by_access_token; plugin->insert_sanction_list_hit = &TEH_PG_insert_sanction_list_hit; + plugin->select_exchange_debit_transfers + = &TEH_PG_select_exchange_debit_transfers; + plugin->select_exchange_credit_transfers + = &TEH_PG_select_exchange_credit_transfers; plugin->select_all_kyc_attributes = &TEH_PG_select_all_kyc_attributes; plugin->begin_shard diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -3698,6 +3698,24 @@ typedef bool /** + * Callback that is given AML-relevant transfer data. + * + * @param cls closure + * @param row_id current row in AML status table + * @param payto_uri account involved with the wire transfer + * @param execution_time when was the transfer made + * @param amount wire amount of the transfer + */ +typedef void +(*TALER_EXCHANGEDB_AmlTransferCallback)( + void *cls, + uint64_t row_id, + const char *payto_uri, + struct GNUNET_TIME_Absolute execution_time, + const struct TALER_Amount *amount); + + +/** * @brief The plugin API, returned from the plugin's "init" function. * The argument given to "init" is simply a configuration handle. */ @@ -7908,6 +7926,49 @@ struct TALER_EXCHANGEDB_Plugin void *cls, const struct TALER_NormalizedPaytoHashP *h_payto); + + /** + * Return AML-relevant wire transfer credit data. + * + * @param cls closure + * @param threshold minimum wire amount to return data for + * @param offset offset in table to filter by + * @param limit maximum number of entries to return, negative for descending + * @param cb function to call on each result + * @param cb_cls closure to pass to @a cb + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*select_exchange_credit_transfers) ( + void *cls, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls); + + + /** + * Return AML-relevant wire transfer debit data. + * + * @param cls closure + * @param threshold minimum wire amount to return data for + * @param offset offset in table to filter by + * @param limit maximum number of entries to return, negative for descending + * @param cb function to call on each result + * @param cb_cls closure to pass to @a cb + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*select_exchange_debit_transfers) ( + void *cls, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls); + + }; #endif /* _TALER_EXCHANGE_DB_H */ diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c @@ -40,12 +40,12 @@ * Which version of the Taler protocol is implemented * by this library? Used to determine compatibility. */ -#define EXCHANGE_PROTOCOL_CURRENT 24 +#define EXCHANGE_PROTOCOL_CURRENT 25 /** * How many versions are we backwards compatible with? */ -#define EXCHANGE_PROTOCOL_AGE 5 +#define EXCHANGE_PROTOCOL_AGE 6 /** * Set to 1 for extra debug logging.