diff options
Diffstat (limited to 'src/exchange/taler-exchange-closer.c')
-rw-r--r-- | src/exchange/taler-exchange-closer.c | 127 |
1 files changed, 79 insertions, 48 deletions
diff --git a/src/exchange/taler-exchange-closer.c b/src/exchange/taler-exchange-closer.c index 92ba7babb..779525c4e 100644 --- a/src/exchange/taler-exchange-closer.c +++ b/src/exchange/taler-exchange-closer.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2016-2021 Taler Systems SA + Copyright (C) 2016-2022 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -204,14 +204,19 @@ commit_or_warn (void) * @param account_payto_uri information about the bank account that initially * caused the reserve to be created * @param expiration_date when did the reserve expire - * @return transaction status code + * @param close_request_row row of request asking for + * closure, 0 for expired reserves + * @return #GNUNET_OK on success (continue) + * #GNUNET_NO on non-fatal errors (try again) + * #GNUNET_SYSERR on fatal errors (abort) */ -static enum GNUNET_DB_QueryStatus +static enum GNUNET_GenericReturnValue expired_reserve_cb (void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *left, const char *account_payto_uri, - struct GNUNET_TIME_Timestamp expiration_date) + struct GNUNET_TIME_Timestamp expiration_date, + uint64_t close_request_row) { struct GNUNET_TIME_Timestamp now; struct TALER_WireTransferIdentifierRawP wtid; @@ -239,7 +244,7 @@ expired_reserve_cb (void *cls, account_payto_uri); global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); - return GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; } /* lookup `fees` from time of actual reserve expiration @@ -257,13 +262,22 @@ expired_reserve_cb (void *cls, &end_date, &fees, &master_sig); - if (0 >= qs) + switch (qs) { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not get wire fees for %s at %s. Aborting run.\n", wa->method, GNUNET_TIME_timestamp2s (expiration_date)); - return GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SOFT_ERROR: + return GNUNET_NO; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + /* continued below */ + break; } } @@ -281,8 +295,8 @@ expired_reserve_cb (void *cls, GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (left->currency, &amount_without_fee)); + ret = TALER_AAR_RESULT_ZERO; } - GNUNET_assert (TALER_AAR_RESULT_POSITIVE == ret); /* round down to enable transfer */ if (GNUNET_SYSERR == TALER_amount_round_down (&amount_without_fee, @@ -291,27 +305,25 @@ expired_reserve_cb (void *cls, GNUNET_break (0); global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); - return GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; } /* NOTE: sizeof (*reserve_pub) == sizeof (wtid) right now, but to be future-compatible, we use the memset + min construction */ memset (&wtid, 0, sizeof (wtid)); - memcpy (&wtid, - reserve_pub, - GNUNET_MIN (sizeof (wtid), - sizeof (*reserve_pub))); - if (TALER_AAR_INVALID_NEGATIVE_RESULT != ret) - qs = db_plugin->insert_reserve_closed (db_plugin->cls, - reserve_pub, - now, - account_payto_uri, - &wtid, - left, - &closing_fee); - else - qs = GNUNET_DB_STATUS_HARD_ERROR; + GNUNET_memcpy (&wtid, + reserve_pub, + GNUNET_MIN (sizeof (wtid), + sizeof (*reserve_pub))); + qs = db_plugin->insert_reserve_closed (db_plugin->cls, + reserve_pub, + now, + account_payto_uri, + &wtid, + left, + &closing_fee, + close_request_row); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Closing reserve %s over %s (%d, %d)\n", TALER_B2S (reserve_pub), @@ -319,22 +331,30 @@ expired_reserve_cb (void *cls, (int) ret, qs); /* Check for hard failure */ - if ( (TALER_AAR_INVALID_NEGATIVE_RESULT == ret) || - (GNUNET_DB_STATUS_HARD_ERROR == qs) ) + if (GNUNET_DB_STATUS_HARD_ERROR == qs) { GNUNET_break (0); global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); - return GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_SYSERR; } - if ( (TALER_AAR_RESULT_ZERO == ret) || - (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) ) + if (TALER_amount_is_zero (&amount_without_fee)) { /* Reserve balance was zero OR soft error */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Reserve was virtually empty, moving on\n"); - (void) commit_or_warn (); - return qs; + qs = commit_or_warn (); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SOFT_ERROR: + return GNUNET_NO; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + return GNUNET_OK; + } } /* success, perform wire transfer */ @@ -355,19 +375,25 @@ expired_reserve_cb (void *cls, buf_size); GNUNET_free (buf); } - if (GNUNET_DB_STATUS_HARD_ERROR == qs) + switch (qs) { + case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); - return GNUNET_DB_STATUS_HARD_ERROR; - } - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - { + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SOFT_ERROR: /* start again */ - return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + return GNUNET_NO; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return GNUNET_SYSERR; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; } - return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + return GNUNET_OK; } @@ -409,11 +435,18 @@ run_reserve_closures (void *cls) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Checking for reserves to close by date %s\n", GNUNET_TIME_timestamp2s (now)); - qs = db_plugin->get_expired_reserves (db_plugin->cls, - now, - &expired_reserve_cb, - NULL); - GNUNET_assert (1 >= qs); + qs = db_plugin->get_unfinished_close_requests (db_plugin->cls, + &expired_reserve_cb, + NULL); + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + /* Try expired reserves as well */ + qs = db_plugin->get_expired_reserves ( + db_plugin->cls, + now, + &expired_reserve_cb, + NULL); + } switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -436,13 +469,11 @@ run_reserve_closures (void *cls) if (GNUNET_YES == test_mode) { GNUNET_SCHEDULER_shutdown (); + return; } - else - { - task = GNUNET_SCHEDULER_add_delayed (closer_idle_sleep_interval, - &run_reserve_closures, - NULL); - } + task = GNUNET_SCHEDULER_add_delayed (closer_idle_sleep_interval, + &run_reserve_closures, + NULL); return; case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: (void) commit_or_warn (); |