summaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-closer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-closer.c')
-rw-r--r--src/exchange/taler-exchange-closer.c127
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 ();