[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-exchange] branch master updated (87a8d2d2 -> d7cfb11f)
From: |
gnunet |
Subject: |
[taler-exchange] branch master updated (87a8d2d2 -> d7cfb11f) |
Date: |
Sun, 15 Mar 2020 00:56:00 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a change to branch master
in repository exchange.
from 87a8d2d2 remove unused code
new d292b8ed code cleanup and additional error checking logic for #6124,
but no actual semantic change
new b3a52548 Merge branch 'master' of git+ssh://git.taler.net/exchange
new f8095d72 fix shutdown logic of test
new d7cfb11f fix new ag logic
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
doc/prebuilt | 2 +-
src/exchange/taler-exchange-aggregator.c | 31 ++++++++++++--------
src/exchange/taler-exchange-httpd_responses.c | 42 ++++++++++++++++++---------
src/exchange/taler-exchange-httpd_withdraw.c | 31 +++++++++++++-------
src/include/taler_error_codes.h | 7 +++++
src/testing/test_taler_exchange_aggregator.c | 32 +++++++++++++++-----
6 files changed, 100 insertions(+), 45 deletions(-)
diff --git a/doc/prebuilt b/doc/prebuilt
index ca53235c..934a6a18 160000
--- a/doc/prebuilt
+++ b/doc/prebuilt
@@ -1 +1 @@
-Subproject commit ca53235ccfa0458ebf11c204888ca370e20ec3f5
+Subproject commit 934a6a18301e81c4fd1b3a8cda2dc13dca4741cc
diff --git a/src/exchange/taler-exchange-aggregator.c
b/src/exchange/taler-exchange-aggregator.c
index c3b94b3d..c44d0f70 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -523,8 +523,9 @@ aggregate_cb (void *cls,
const json_t *wire)
{
struct AggregationUnit *au = cls;
- struct TALER_Amount delta;
+ struct TALER_Amount old;
enum GNUNET_DB_QueryStatus qs;
+ struct TALER_Amount delta;
/* NOTE: potential optimization: use custom SQL API to not
fetch these: */
@@ -541,12 +542,16 @@ aggregate_cb (void *cls,
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
- /* compute contribution of this coin after fees */
/* add to total */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Adding transaction amount %s from row %llu to aggregation\n",
TALER_amount2s (amount_with_fee),
(unsigned long long) row_id);
+ /* save the existing total aggregate in 'old', for later */
+ old = au->total_amount;
+ /* we begin with the total contribution of the current coin */
+ au->total_amount = *amount_with_fee;
+ /* compute contribution of this coin (after fees) */
au->have_refund = GNUNET_NO;
qs = db_plugin->select_refunds_by_coin (db_plugin->cls,
au->session,
@@ -562,43 +567,45 @@ aggregate_cb (void *cls,
}
if (GNUNET_NO == au->have_refund)
{
+ struct TALER_Amount tmp;
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Subtracting deposit fee %s for non-refunded coin\n",
TALER_amount2s (deposit_fee));
if (GNUNET_SYSERR ==
- TALER_amount_subtract (&delta,
- amount_with_fee,
+ TALER_amount_subtract (&tmp,
+ &au->total_amount,
deposit_fee))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Fatally malformed record at %llu over amount %s (deposit
fee exceeds deposited value)\n",
(unsigned long long) row_id,
TALER_amount2s (&au->total_amount));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (old.currency,
+ &au->total_amount));
}
else
{
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_get_zero (au->total_amount.currency,
- &delta));
+ au->total_amount = tmp;
}
}
- else
- {
- delta = *amount_with_fee;
- }
+ /* now add the au->total_amount with the (remaining) contribution of
+ the current coin to the 'old' value with the current aggregate value */
{
struct TALER_Amount tmp;
if (GNUNET_OK !=
TALER_amount_add (&tmp,
&au->total_amount,
- &delta))
+ &old))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Overflow or currency incompatibility during aggregation at
%llu\n",
(unsigned long long) row_id);
/* Skip this one, but keep going! */
+ au->total_amount = old;
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
au->total_amount = tmp;
diff --git a/src/exchange/taler-exchange-httpd_responses.c
b/src/exchange/taler-exchange-httpd_responses.c
index 0e7704e4..e2a20243 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -433,10 +433,13 @@ TEH_RESPONSE_reply_coin_insufficient_funds (struct
MHD_Connection *connection,
history = TEH_RESPONSE_compile_transaction_history (coin_pub,
tl);
if (NULL == history)
+ {
+ GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_COIN_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
"failed to convert transaction history
to JSON");
+ }
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
"{s:s, s:I, s:o}",
@@ -462,10 +465,17 @@ TEH_RESPONSE_compile_reserve_history (const struct
struct TALER_Amount deposit_total;
struct TALER_Amount withdraw_total;
json_t *json_history;
- int ret;
+ enum InitAmounts
+ {
+ /** Nothing initialized */
+ IA_NONE = 0,
+ /** deposit_total initialized */
+ IA_DEPOSIT = 1,
+ /** withdraw_total initialized */
+ IA_WITHDRAW = 2
+ } init = IA_NONE;
json_history = json_array ();
- ret = 0;
for (const struct TALER_EXCHANGEDB_ReserveHistory *pos = rh;
NULL != pos;
pos = pos->next)
@@ -473,8 +483,11 @@ TEH_RESPONSE_compile_reserve_history (const struct
switch (pos->type)
{
case TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE:
- if (0 == (1 & ret))
+ if (0 == (IA_DEPOSIT & init))
+ {
deposit_total = pos->details.bank->amount;
+ init |= IA_DEPOSIT;
+ }
else if (GNUNET_OK !=
TALER_amount_add (&deposit_total,
&deposit_total,
@@ -484,7 +497,6 @@ TEH_RESPONSE_compile_reserve_history (const struct
json_decref (json_history);
return NULL;
}
- ret |= 1;
if (0 !=
json_array_append_new (json_history,
json_pack ("{s:s, s:o, s:s, s:o, s:o}",
@@ -514,9 +526,10 @@ TEH_RESPONSE_compile_reserve_history (const struct
struct TALER_Amount value;
value = pos->details.withdraw->amount_with_fee;
- if (0 == (2 & ret))
+ if (0 == (IA_WITHDRAW & init))
{
withdraw_total = value;
+ init |= IA_WITHDRAW;
}
else
{
@@ -530,7 +543,6 @@ TEH_RESPONSE_compile_reserve_history (const struct
return NULL;
}
}
- ret |= 2;
if (0 !=
json_array_append_new (json_history,
json_pack ("{s:s, s:o, s:o, s:o, s:o, s:o}",
@@ -568,8 +580,11 @@ TEH_RESPONSE_compile_reserve_history (const struct
struct TALER_ExchangeSignatureP sig;
recoup = pos->details.recoup;
- if (0 == (1 & ret))
+ if (0 == (IA_DEPOSIT & init))
+ {
deposit_total = recoup->value;
+ init |= IA_DEPOSIT;
+ }
else if (GNUNET_OK !=
TALER_amount_add (&deposit_total,
&deposit_total,
@@ -579,7 +594,6 @@ TEH_RESPONSE_compile_reserve_history (const struct
json_decref (json_history);
return NULL;
}
- ret |= 1;
pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP);
pc.purpose.size = htonl (sizeof (struct TALER_RecoupConfirmationPS));
pc.timestamp = GNUNET_TIME_absolute_hton (recoup->timestamp);
@@ -628,9 +642,10 @@ TEH_RESPONSE_compile_reserve_history (const struct
struct TALER_Amount value;
value = pos->details.closing->amount;
- if (0 == (2 & ret))
+ if (0 == (IA_WITHDRAW & init))
{
withdraw_total = value;
+ init |= IA_WITHDRAW;
}
else
{
@@ -644,7 +659,6 @@ TEH_RESPONSE_compile_reserve_history (const struct
return NULL;
}
}
- ret |= 2;
rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED);
rcc.purpose.size = htonl (sizeof (struct
TALER_ReserveCloseConfirmationPS));
@@ -703,15 +717,17 @@ TEH_RESPONSE_compile_reserve_history (const struct
}
}
- if (0 == (1 & ret))
+ if (0 == (IA_DEPOSIT & init))
{
+ /* We should not have gotten here, without deposits no reserve
+ should exist! */
GNUNET_break (0);
json_decref (json_history);
return NULL;
}
- if (0 == (2 & ret))
+ if (0 == (IA_WITHDRAW & init))
{
- /* did not encounter any withdraw operations, set to zero */
+ /* did not encounter any withdraw operations, set withdraw_total to zero */
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (deposit_total.currency,
&withdraw_total));
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c
b/src/exchange/taler-exchange-httpd_withdraw.c
index ddb543c8..1abf1932 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -44,33 +44,40 @@
/**
* Send reserve status information to client with the
* message that we have insufficient funds for the
- * requested /reserve/withdraw operation.
+ * requested withdraw operation.
*
* @param connection connection to the client
+ * @param ebalance expected balance based on our database
* @param rh reserve history to return
* @return MHD result code
*/
static int
reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *connection,
+ const struct TALER_Amount *ebalance,
const struct
TALER_EXCHANGEDB_ReserveHistory *rh)
{
- json_t *json_balance;
json_t *json_history;
struct TALER_Amount balance;
json_history = TEH_RESPONSE_compile_reserve_history (rh,
&balance);
- if ((NULL == json_history)
- /* Address the case where the ptr is not null, but
- * it fails "internally" to dump as string (= corrupted). */
- || (0 == json_dumpb (json_history, NULL, 0, 0)))
+ if (NULL == json_history)
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
"balance calculation failure");
- json_balance = TALER_JSON_from_amount (&balance);
-
+ if (0 !=
+ TALER_amount_cmp (&balance,
+ ebalance))
+ {
+ GNUNET_break (0);
+ json_decref (json_history);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+
TALER_EC_WITHDRAW_HISTORY_RESERVE_BALANCE_CORRUPT,
+ "internal balance inconsistency error");
+ }
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
"{s:s, s:I, s:o, s:o}",
@@ -78,7 +85,8 @@ reply_reserve_withdraw_insufficient_funds (struct
MHD_Connection *connection,
"code",
(json_int_t)
TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
- "balance", json_balance,
+ "balance", TALER_JSON_from_amount (
+ &balance),
"history", json_history);
}
@@ -285,6 +293,7 @@ withdraw_transaction (void *cls,
return GNUNET_DB_STATUS_HARD_ERROR;
}
*mhd_ret = reply_reserve_withdraw_insufficient_funds (connection,
+ &r.balance,
rh);
TEH_plugin->free_reserve_history (TEH_plugin->cls,
rh);
@@ -455,7 +464,7 @@ TEH_RESERVE_handler_reserve_withdraw (const struct
TEH_RequestHandler *rh,
&wc.wsrd.reserve_pub.eddsa_pub))
{
TALER_LOG_WARNING (
- "Client supplied invalid signature for /reserve/withdraw request\n");
+ "Client supplied invalid signature for withdraw request\n");
GNUNET_JSON_parse_free (spec);
TEH_KS_release (wc.key_state);
return TALER_MHD_reply_with_error (connection,
@@ -484,7 +493,7 @@ TEH_RESERVE_handler_reserve_withdraw (const struct
TEH_RequestHandler *rh,
if (GNUNET_OK !=
TEH_DB_run_transaction (connection,
- "run reserve withdraw",
+ "run withdraw",
&mhd_ret,
&withdraw_transaction,
&wc))
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index f485f2da..e6bd7364 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -381,6 +381,13 @@ enum TALER_ErrorCode
*/
TALER_EC_DENOMINATION_KEY_LOST = 1116,
+ /**
+ * The exchange's database entry with the reserve balance summary
+ * is inconsistent with its own history of the reserve.
+ * Returned with an HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_WITHDRAW_HISTORY_RESERVE_BALANCE_CORRUPT = 1117,
+
/**
* The exchange failed to obtain the transaction history of the given
* reserve from the database. This response is provided with HTTP
diff --git a/src/testing/test_taler_exchange_aggregator.c
b/src/testing/test_taler_exchange_aggregator.c
index 66cdecff..fe96d635 100644
--- a/src/testing/test_taler_exchange_aggregator.c
+++ b/src/testing/test_taler_exchange_aggregator.c
@@ -71,6 +71,24 @@ static char *config_filename;
TALER_TESTING_cmd_exec_transfer (label "-transfer", cfg_fn)
+/**
+ * Function run on shutdown to unload the DB plugin.
+ *
+ * @param cls NULL
+ */
+static void
+unload_db (void *cls)
+{
+ (void) cls;
+ if (NULL != dbc.plugin)
+ {
+ dbc.plugin->drop_tables (dbc.plugin->cls);
+ TALER_EXCHANGEDB_plugin_unload (dbc.plugin);
+ dbc.plugin = NULL;
+ }
+}
+
+
/**
* Collects all the tests.
*/
@@ -431,6 +449,8 @@ run (void *cls,
TALER_TESTING_cmd_end ()
};
+ GNUNET_SCHEDULER_add_shutdown (&unload_db,
+ NULL);
TALER_TESTING_run_with_fakebank (is,
all,
bc.exchange_auth.wire_gateway_url);
@@ -473,8 +493,6 @@ prepare_database (void *cls,
cfg,
NULL, // no exchange process handle.
GNUNET_NO); // do not try to connect to the
exchange
-
-
return GNUNET_OK;
}
@@ -524,18 +542,16 @@ main (int argc,
return 77;
}
- if (GNUNET_OK != GNUNET_CONFIGURATION_parse_and_run (config_filename,
- &prepare_database,
- NULL))
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_parse_and_run (config_filename,
+ &prepare_database,
+ NULL))
{
TALER_LOG_WARNING ("Could not prepare database for tests.\n");
return result;
}
-
GNUNET_free (config_filename);
GNUNET_free (testname);
- dbc.plugin->drop_tables (dbc.plugin->cls);
- TALER_EXCHANGEDB_plugin_unload (dbc.plugin);
return GNUNET_OK == result ? 0 : 1;
}
--
To stop receiving notification emails like this one, please contact
address@hidden.
- [taler-exchange] branch master updated (87a8d2d2 -> d7cfb11f),
gnunet <=