From b7e3f047b98d670b9838f0b905c1316190f6c1cb Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 23 Aug 2024 15:41:05 +0200 Subject: add logic to remove missing wire out reports that are have been addressed --- src/auditor/taler-helper-auditor-wire-debit.c | 86 +++++++++++++++++++++- src/auditordb/Makefile.am | 1 + .../pg_delete_wire_out_inconsistency_if_matching.c | 54 ++++++++++++++ .../pg_delete_wire_out_inconsistency_if_matching.h | 35 +++++++++ src/auditordb/plugin_auditordb_postgres.c | 16 ++-- src/include/taler_auditordb_plugin.h | 4 + 6 files changed, 187 insertions(+), 9 deletions(-) create mode 100644 src/auditordb/pg_delete_wire_out_inconsistency_if_matching.c create mode 100644 src/auditordb/pg_delete_wire_out_inconsistency_if_matching.h diff --git a/src/auditor/taler-helper-auditor-wire-debit.c b/src/auditor/taler-helper-auditor-wire-debit.c index 34044d1d9..5d853ebc5 100644 --- a/src/auditor/taler-helper-auditor-wire-debit.c +++ b/src/auditor/taler-helper-auditor-wire-debit.c @@ -747,6 +747,76 @@ check_rc_matches (void *cls, } +/** + * Maximum required length for make_missing_diag(). + */ +#define MAX_DIAG_LEN 128 + +/** + * Make diagnostic string for missing wire transfer. + * + * @param[out] where to write the diagnostic + * @param wtid wire transfer ID to include + */ +static void +make_missing_diag (char diag[MAX_DIAG_LEN], + const struct TALER_WireTransferIdentifierRawP *wtid) +{ + char *wtid_s; + + wtid_s = GNUNET_STRINGS_data_to_string_alloc (wtid, + sizeof (*wtid)); + GNUNET_snprintf (diag, + MAX_DIAG_LEN, + "expected outgoing wire transfer %s missing", + wtid_s); + GNUNET_free (wtid_s); +} + + +/** + * Check if an existing report on a missing wire + * out operation justified the @a roi. If so, + * clear the existing report. + * + * @param roi reserve out operation to check + * @return #GNUNET_YES if @a roi was justified by a previous report, + * #GNUNET_NO of @a roi was not justified by a previous missing report + * #GNUNET_SYSERR on database trouble + */ +static enum GNUNET_GenericReturnValue +check_reported_inconsistency (struct ReserveOutInfo *roi) +{ + char diag[MAX_DIAG_LEN]; + struct TALER_AUDITORDB_WireOutInconsistency woi = { + .wire_out_row_id = roi->details.serial_id, + .destination_account = (char *) roi->details.credit_account_uri, + .diagnostic = diag, + .expected = roi->details.amount, + .claimed = zero, + }; + enum GNUNET_DB_QueryStatus qs; + + make_missing_diag (diag, + &roi->details.wtid); + qs = TALER_ARL_adb->delete_wire_out_inconsistency_if_matching ( + TALER_ARL_adb->cls, + &woi); + if (qs < 0) + { + global_qs = qs; + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return GNUNET_SYSERR; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + return GNUNET_NO; + TALER_ARL_amount_subtract (&TALER_ARL_USE_AB (total_bad_amount_out_minus), + &TALER_ARL_USE_AB (total_bad_amount_out_minus), + &roi->details.amount); + return GNUNET_YES; +} + + /** * Check if a profit drain operation justified the @a roi * @@ -929,10 +999,14 @@ complain_out_not_found (void *cls, &ctx); if (ctx.found) return GNUNET_OK; + ret = check_reported_inconsistency (roi); + if (GNUNET_NO != ret) + return ret; ret = check_profit_drain (roi); if (GNUNET_NO != ret) return ret; + { struct TALER_AUDITORDB_WireOutInconsistency woi = { .row_id = roi->details.serial_id, @@ -965,7 +1039,7 @@ complain_out_not_found (void *cls, * as claimed by the exchange DB. * * @param cls a `struct WireAccount` - * @param rowid unique serial ID for the refresh session in our DB + * @param rowid unique serial ID in wire_out table * @param date timestamp of the transfer (roughly) * @param wtid wire transfer subject * @param payto_uri wire transfer details of the receiver @@ -1005,16 +1079,20 @@ wire_out_cb ( justified), so the entire amount is missing / still to be done. This is moderately harmless, it might just be that the taler-exchange-transfer tool or bank has not yet fully caught up with - the transfers it should do. */ + the transfers it should do. + May be cleared later by check_reported_inconsistency() */ + char diag[MAX_DIAG_LEN]; struct TALER_AUDITORDB_WireOutInconsistency woi = { - .row_id = rowid, .destination_account = (char *) payto_uri, - .diagnostic = "expected outgoing wire transfer missing", + .diagnostic = diag, + .wire_out_row_id = rowid, .expected = *amount, .claimed = zero, }; enum GNUNET_DB_QueryStatus qs; + make_missing_diag (diag, + wtid); qs = TALER_ARL_adb->insert_wire_out_inconsistency ( TALER_ARL_adb->cls, &woi); diff --git a/src/auditordb/Makefile.am b/src/auditordb/Makefile.am index d4bb7f171..de6a7cd99 100644 --- a/src/auditordb/Makefile.am +++ b/src/auditordb/Makefile.am @@ -168,6 +168,7 @@ pg_update_wire_format_inconsistency.c pg_update_wire_format_inconsistency.h \ pg_get_wire_out_inconsistency.c pg_get_wire_out_inconsistency.h \ pg_del_wire_out_inconsistency.c pg_del_wire_out_inconsistency.h \ pg_insert_wire_out_inconsistency.c pg_insert_wire_out_inconsistency.h \ +pg_delete_wire_out_inconsistency_if_matching.c pg_delete_wire_out_inconsistency_if_matching.h \ pg_update_wire_out_inconsistency.c pg_update_wire_out_inconsistency.h \ pg_get_reserve_balance_summary_wrong_inconsistency.c pg_get_reserve_balance_summary_wrong_inconsistency.h \ pg_del_reserve_balance_summary_wrong_inconsistency.c pg_del_reserve_balance_summary_wrong_inconsistency.h \ diff --git a/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.c b/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.c new file mode 100644 index 000000000..3e959bf5d --- /dev/null +++ b/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.c @@ -0,0 +1,54 @@ +/* + 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 + */ +#include "platform.h" +#include "taler_pq_lib.h" +#include "pg_helper.h" +#include "pg_delete_wire_out_inconsistency_if_matching.h" + + +enum GNUNET_DB_QueryStatus +TAH_PG_delete_wire_out_inconsistency_if_matching ( + void *cls, + const struct TALER_AUDITORDB_WireOutInconsistency *dc) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->destination_account), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_uint64 (&dc->wire_out_row_id), + TALER_PQ_query_param_amount (pg->conn, + &dc->expected), + TALER_PQ_query_param_amount (pg->conn, + &dc->claimed), + GNUNET_PQ_query_param_end + }; + + PREPARE (pg, + "auditor_wire_out_inconsistency_delete_if_matching", + "DELETE FROM auditor_wire_out_inconsistency " + " WHERE destination_account=$1" + " AND diagnostic=$2" + " AND wire_out_serial_id=$3" + " AND (expected).val=($4::taler_amount).val" + " AND (expected).frac=($4::taler_amount).frac" + " AND (claimed).val=($5::taler_amount).val" + " AND (claimed).frac=($5::taler_amount).frac;" + ); + return GNUNET_PQ_eval_prepared_non_select ( + pg->conn, + "auditor_wire_out_inconsistency_delete_if_matching", + params); +} diff --git a/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.h b/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.h new file mode 100644 index 000000000..b81bc418c --- /dev/null +++ b/src/auditordb/pg_delete_wire_out_inconsistency_if_matching.h @@ -0,0 +1,35 @@ +/* + 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 + */ +#ifndef PG_DELETE_WIRE_OUT_INCONSISTENCY_IF_MATCHING_H +#define PG_DELETE_WIRE_OUT_INCONSISTENCY_IF_MATCHING_H + +#include "taler_util.h" +#include "taler_auditordb_plugin.h" + + +/** + * Delete information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +TAH_PG_delete_wire_out_inconsistency_if_matching ( + void *cls, + const struct TALER_AUDITORDB_WireOutInconsistency *dc); + +#endif diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 0d24b7872..5dc8251c9 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -161,6 +161,7 @@ #include "pg_get_wire_out_inconsistency.h" #include "pg_del_wire_out_inconsistency.h" #include "pg_insert_wire_out_inconsistency.h" +#include "pg_delete_wire_out_inconsistency_if_matching.h" #include "pg_update_wire_out_inconsistency.h" #include "pg_get_reserve_balance_summary_wrong_inconsistency.h" @@ -798,11 +799,16 @@ libtaler_plugin_auditordb_postgres_init (void *cls) &TAH_PG_update_wire_format_inconsistency; - plugin->delete_wire_out_inconsistency = &TAH_PG_del_wire_out_inconsistency; - plugin->insert_wire_out_inconsistency = &TAH_PG_insert_wire_out_inconsistency; - plugin->get_wire_out_inconsistency = &TAH_PG_get_wire_out_inconsistency; - plugin->update_wire_out_inconsistency = &TAH_PG_update_wire_out_inconsistency; - + plugin->delete_wire_out_inconsistency + = &TAH_PG_del_wire_out_inconsistency; + plugin->insert_wire_out_inconsistency + = &TAH_PG_insert_wire_out_inconsistency; + plugin->delete_wire_out_inconsistency_if_matching + = &TAH_PG_delete_wire_out_inconsistency_if_matching; + plugin->get_wire_out_inconsistency + = &TAH_PG_get_wire_out_inconsistency; + plugin->update_wire_out_inconsistency + = &TAH_PG_update_wire_out_inconsistency; plugin->delete_reserve_balance_summary_wrong_inconsistency = &TAH_PG_del_reserve_balance_summary_wrong_inconsistency; diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index 1dd26a8ce..0adb2ea8f 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -1840,6 +1840,10 @@ struct TALER_AUDITORDB_Plugin void *cls, const struct TALER_AUDITORDB_WireOutInconsistency *dc); + enum GNUNET_DB_QueryStatus + (*delete_wire_out_inconsistency_if_matching)( + void *cls, + const struct TALER_AUDITORDB_WireOutInconsistency *dc); enum GNUNET_DB_QueryStatus (*update_wire_out_inconsistency)( -- cgit v1.2.3