summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------contrib/gana0
-rw-r--r--src/exchange/taler-exchange-httpd_reserves_history.c25
-rw-r--r--src/exchange/taler-exchange-httpd_reserves_status.c19
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c1
-rw-r--r--src/include/taler_exchange_service.h33
-rw-r--r--src/lib/exchange_api_common.c44
-rw-r--r--src/lib/exchange_api_reserves_history.c7
-rw-r--r--src/lib/exchange_api_reserves_status.c3
-rw-r--r--src/lib/exchange_api_withdraw2.c14
9 files changed, 90 insertions, 56 deletions
diff --git a/contrib/gana b/contrib/gana
-Subproject 4cfefdf374de55fe9be3f0f039c7a13f496ab97
+Subproject 25eb78f2d0e20a137020dd0ab1c6474123843db
diff --git a/src/exchange/taler-exchange-httpd_reserves_history.c b/src/exchange/taler-exchange-httpd_reserves_history.c
index 4115988f9..96902d01c 100644
--- a/src/exchange/taler-exchange-httpd_reserves_history.c
+++ b/src/exchange/taler-exchange-httpd_reserves_history.c
@@ -32,6 +32,14 @@
/**
+ * How far do we allow a client's time to be off when
+ * checking the request timestamp?
+ */
+#define TIMESTAMP_TOLERANCE \
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
+
+
+/**
* Closure for #reserve_history_transaction.
*/
struct ReserveHistoryContext
@@ -121,8 +129,7 @@ reserve_history_transaction (void *cls,
struct ReserveHistoryContext *rsc = cls;
enum GNUNET_DB_QueryStatus qs;
- // FIXME: first deduct rsc->gf->fees.history from balance!
- // FIXME: pass rsc.gf->history_expiration?
+ // FIXME: first deduct rsc->gf->fees.history from reserve balance (and persist the signature justifying this)
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
rsc->reserve_pub,
&rsc->balance,
@@ -175,13 +182,21 @@ TEH_handler_reserves_history (struct TEH_RequestContext *rc,
}
}
now = GNUNET_TIME_timestamp_get ();
- /* FIXME: check that 'timestamp' is close to 'now' */
-
+ if (! GNUNET_TIME_absolute_approx_eq (now.abs_time,
+ rsc.timestamp.abs_time,
+ TIMESTAMP_TOLERANCE))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_EXCHANGE_GENERIC_CLOCK_SKEW,
+ NULL);
+ }
rsc.gf = TEH_keys_global_fee_by_time (TEH_keys_get_state (),
rsc.timestamp);
if (NULL == rsc.gf)
{
- GNUNET_break_op (0);
+ GNUNET_break (0);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION,
diff --git a/src/exchange/taler-exchange-httpd_reserves_status.c b/src/exchange/taler-exchange-httpd_reserves_status.c
index 0b6ee2d30..6a3260d12 100644
--- a/src/exchange/taler-exchange-httpd_reserves_status.c
+++ b/src/exchange/taler-exchange-httpd_reserves_status.c
@@ -30,6 +30,13 @@
#include "taler-exchange-httpd_reserves_status.h"
#include "taler-exchange-httpd_responses.h"
+/**
+ * How far do we allow a client's time to be off when
+ * checking the request timestamp?
+ */
+#define TIMESTAMP_TOLERANCE \
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
+
/**
* Closure for #reserve_status_transaction.
@@ -140,6 +147,7 @@ TEH_handler_reserves_status (struct TEH_RequestContext *rc,
&reserve_sig),
GNUNET_JSON_spec_end ()
};
+ struct GNUNET_TIME_Timestamp now;
rsc.reserve_pub = reserve_pub;
{
@@ -159,6 +167,17 @@ TEH_handler_reserves_status (struct TEH_RequestContext *rc,
return MHD_YES; /* failure */
}
}
+ now = GNUNET_TIME_timestamp_get ();
+ if (! GNUNET_TIME_absolute_approx_eq (now.abs_time,
+ timestamp.abs_time,
+ TIMESTAMP_TOLERANCE))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_EXCHANGE_GENERIC_CLOCK_SKEW,
+ NULL);
+ }
if (GNUNET_OK !=
TALER_wallet_reserve_status_verify (timestamp,
reserve_pub,
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 73f7b90d8..3f8716261 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -5595,6 +5595,7 @@ postgres_get_reserve_status (void *cls,
GNUNET_PQ_query_param_end
};
+ /* FIXME: actually implement reserve history truncation logic! */
rhc.reserve_pub = reserve_pub;
rhc.rh = NULL;
rhc.rh_tail = NULL;
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index f59e1b46c..41f01c97a 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1583,11 +1583,22 @@ struct TALER_EXCHANGE_ReserveStatus
{
/**
- * Reserve balance.
+ * Current reserve balance. May not be the difference between
+ * @e total_in and @e total_out because the @e may be truncated.
*/
struct TALER_Amount balance;
/**
+ * Total of all inbound transactions in @e history.
+ */
+ struct TALER_Amount total_in;
+
+ /**
+ * Total of all outbound transactions in @e history.
+ */
+ struct TALER_Amount total_out;
+
+ /**
* Reserve history.
*/
const struct TALER_EXCHANGE_ReserveHistoryEntry *history;
@@ -1687,11 +1698,23 @@ struct TALER_EXCHANGE_ReserveHistory
{
/**
- * Reserve balance.
+ * Reserve balance. May not be the difference between
+ * @e total_in and @e total_out because the @e may be truncated
+ * due to expiration.
*/
struct TALER_Amount balance;
/**
+ * Total of all inbound transactions in @e history.
+ */
+ struct TALER_Amount total_in;
+
+ /**
+ * Total of all outbound transactions in @e history.
+ */
+ struct TALER_Amount total_out;
+
+ /**
* Reserve history.
*/
const struct TALER_EXCHANGE_ReserveHistoryEntry *history;
@@ -2685,7 +2708,8 @@ TALER_EXCHANGE_verify_coin_history (
* @param history JSON array with the history
* @param reserve_pub public key of the reserve to inspect
* @param currency currency we expect the balance to be in
- * @param[out] balance final balance
+ * @param[out] total_in set to value of credits to reserve
+ * @param[out] total_out set to value of debits from reserve
* @param history_length number of entries in @a history
* @param[out] rhistory array of length @a history_length, set to the
* parsed history entries
@@ -2699,7 +2723,8 @@ TALER_EXCHANGE_parse_reserve_history (
const json_t *history,
const struct TALER_ReservePublicKeyP *reserve_pub,
const char *currency,
- struct TALER_Amount *balance,
+ struct TALER_Amount *total_in,
+ struct TALER_Amount *total_out,
unsigned int history_length,
struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory);
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index c9bff71f1..1da36fe8b 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -32,21 +32,20 @@ TALER_EXCHANGE_parse_reserve_history (
const json_t *history,
const struct TALER_ReservePublicKeyP *reserve_pub,
const char *currency,
- struct TALER_Amount *balance,
+ struct TALER_Amount *total_in,
+ struct TALER_Amount *total_out,
unsigned int history_length,
struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory)
{
struct GNUNET_HashCode uuid[history_length];
unsigned int uuid_off;
- struct TALER_Amount total_in;
- struct TALER_Amount total_out;
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (currency,
- &total_in));
+ total_in));
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (currency,
- &total_out));
+ total_out));
uuid_off = 0;
for (unsigned int off = 0; off<history_length; off++)
{
@@ -76,7 +75,7 @@ TALER_EXCHANGE_parse_reserve_history (
rhistory[off].amount = amount;
if (GNUNET_YES !=
TALER_amount_cmp_currency (&amount,
- &total_in))
+ total_in))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -99,8 +98,8 @@ TALER_EXCHANGE_parse_reserve_history (
rh->type = TALER_EXCHANGE_RTT_CREDIT;
if (0 >
- TALER_amount_add (&total_in,
- &total_in,
+ TALER_amount_add (total_in,
+ total_in,
&amount))
{
/* overflow in history already!? inconceivable! Bad exchange! */
@@ -206,8 +205,8 @@ TALER_EXCHANGE_parse_reserve_history (
uuid_off++;
if (0 >
- TALER_amount_add (&total_out,
- &total_out,
+ TALER_amount_add (total_out,
+ total_out,
&amount))
{
/* overflow in history already!? inconceivable! Bad exchange! */
@@ -274,8 +273,8 @@ TALER_EXCHANGE_parse_reserve_history (
return GNUNET_SYSERR;
}
if (0 >
- TALER_amount_add (&total_in,
- &total_in,
+ TALER_amount_add (total_in,
+ total_in,
&rh->amount))
{
/* overflow in history already!? inconceivable! Bad exchange! */
@@ -349,8 +348,8 @@ TALER_EXCHANGE_parse_reserve_history (
return GNUNET_SYSERR;
}
if (0 >
- TALER_amount_add (&total_out,
- &total_out,
+ TALER_amount_add (total_out,
+ total_out,
&rh->amount))
{
/* overflow in history already!? inconceivable! Bad exchange! */
@@ -366,23 +365,6 @@ TALER_EXCHANGE_parse_reserve_history (
return GNUNET_SYSERR;
}
}
-
- /* check balance = total_in - total_out < withdraw-amount */
- if (NULL != balance)
- {
- /* if balance is NULL, we may have a partial history
- in which case the subtraction may fail, so we do
- not even check that invariant in this case. */
- if (0 >
- TALER_amount_subtract (balance,
- &total_in,
- &total_out))
- {
- /* total_in < total_out, why did the exchange ever allow this!? */
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- }
return GNUNET_OK;
}
diff --git a/src/lib/exchange_api_reserves_history.c b/src/lib/exchange_api_reserves_history.c
index c0f6c42d2..d9c42d691 100644
--- a/src/lib/exchange_api_reserves_history.c
+++ b/src/lib/exchange_api_reserves_history.c
@@ -91,7 +91,6 @@ handle_reserves_history_ok (struct TALER_EXCHANGE_ReservesHistoryHandle *rsh,
{
json_t *history;
unsigned int len;
- struct TALER_Amount history_balance;
struct TALER_EXCHANGE_ReserveHistory rs = {
.hr.reply = j,
.hr.http_status = MHD_HTTP_OK
@@ -123,15 +122,13 @@ handle_reserves_history_ok (struct TALER_EXCHANGE_ReservesHistoryHandle *rsh,
rhistory = GNUNET_new_array (len,
struct TALER_EXCHANGE_ReserveHistoryEntry);
- // FIXME: even this history could be partial
- // (if the reserve is too old!); update API
- // and return incoming & outgoing totals separately?
if (GNUNET_OK !=
TALER_EXCHANGE_parse_reserve_history (rsh->exchange,
history,
&rsh->reserve_pub,
rs.details.ok.balance.currency,
- &history_balance,
+ &rs.details.ok.total_in,
+ &rs.details.ok.total_out,
len,
rhistory))
{
diff --git a/src/lib/exchange_api_reserves_status.c b/src/lib/exchange_api_reserves_status.c
index a99a080bc..eecd40b9c 100644
--- a/src/lib/exchange_api_reserves_status.c
+++ b/src/lib/exchange_api_reserves_status.c
@@ -127,7 +127,8 @@ handle_reserves_status_ok (struct TALER_EXCHANGE_ReservesStatusHandle *rsh,
history,
&rsh->reserve_pub,
rs.details.ok.balance.currency,
- NULL,
+ &rs.details.ok.total_in,
+ &rs.details.ok.total_out,
len,
rhistory))
{
diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c
index bc138db0f..a5371442f 100644
--- a/src/lib/exchange_api_withdraw2.c
+++ b/src/lib/exchange_api_withdraw2.c
@@ -148,7 +148,8 @@ reserve_withdraw_payment_required (
const json_t *json)
{
struct TALER_Amount balance;
- struct TALER_Amount balance_from_history;
+ struct TALER_Amount total_in_from_history;
+ struct TALER_Amount total_out_from_history;
json_t *history;
size_t len;
struct GNUNET_JSON_Specification spec[] = {
@@ -197,7 +198,8 @@ reserve_withdraw_payment_required (
history,
&wh->reserve_pub,
balance.currency,
- &balance_from_history,
+ &total_in_from_history,
+ &total_out_from_history,
len,
rhistory))
{
@@ -210,14 +212,6 @@ reserve_withdraw_payment_required (
len);
}
- if (0 !=
- TALER_amount_cmp (&balance_from_history,
- &balance))
- {
- /* exchange cannot add up balances!? */
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
/* Check that funds were really insufficient */
if (0 >= TALER_amount_cmp (&wh->requested_amount,
&balance))