exchange

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

commit ba69ba689f60213f8c8a2433fd84d6f3319afd84
parent 26a20dafcb36935e4d2eb362c1da3ee066fd4899
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Mon, 17 Aug 2026 15:15:19 +0200

re-try on serialization failure

Diffstat:
Msrc/auditor/taler-helper-auditor-wire-debit.c | 52++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/src/auditor/taler-helper-auditor-wire-debit.c b/src/auditor/taler-helper-auditor-wire-debit.c @@ -206,11 +206,23 @@ struct ReserveClosure static struct GNUNET_CONTAINER_MultiHashMap *reserve_closures; /** + * How often do we retry the transaction after a serialization + * failure before we give up? + */ +#define MAX_RETRIES 3 + +/** * Return value from main(). */ static int global_ret; /** + * Number of serialization failures we have retried since the last + * successfully committed transaction. + */ +static unsigned int retries; + +/** * State of the current database transaction with * the auditor DB. */ @@ -599,21 +611,49 @@ commit (enum GNUNET_DB_QueryStatus qs) goto handle_db_error; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Transaction concluded!\n"); + retries = 0; if (1 == test_mode) GNUNET_SCHEDULER_shutdown (); return; handle_db_error: TALER_AUDITORDB_rollback (TALER_ARL_adb); - for (unsigned int max_retries = 3; max_retries>0; max_retries--) + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) { - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - break; + if (MAX_RETRIES < ++retries) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to commit the transaction after %u retries, terminating\n", + (unsigned int) MAX_RETRIES); + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return; + } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Serialization issue, trying again\n"); - qs = begin_transaction (); + /* Any bank request still in flight belongs to the attempt we are + abandoning. #process_debits() would leave it alone and start + nothing, so the restarted audit would never make progress. */ + for (struct WireAccount *wa = wa_head; + NULL != wa; + wa = wa->next) + { + if (NULL != wa->dhh) + { + TALER_BANK_debit_history_cancel (wa->dhh); + wa->dhh = NULL; + } + if (NULL != wa->dhh_task) + { + GNUNET_SCHEDULER_cancel (wa->dhh_task); + wa->dhh_task = NULL; + } + } + if (GNUNET_DB_STATUS_HARD_ERROR != begin_transaction ()) + return; /* the retry continues asynchronously from here */ } GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Hard database error, terminating\n"); + global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); } @@ -1662,6 +1702,10 @@ begin_transaction (void) NULL != wa; wa = wa->next) { + /* we are called again after a serialization failure, so the labels + may already have been computed */ + GNUNET_free (wa->label_wire_out_serial_id); + GNUNET_free (wa->label_wire_off_out); GNUNET_asprintf (&wa->label_wire_out_serial_id, "wire-%s-%s", wa->ai->section_name,