aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-10-12 22:16:40 +0200
committerChristian Grothoff <christian@grothoff.org>2022-10-12 22:16:40 +0200
commit4702b156dc8130a842745035c936de8817c7c700 (patch)
treef1c2d6c9013d2fa904c82b6cbc2b1effb9c6e16a /src
parent3b34acdb72cd450974a3bbde6169f1bf9644a302 (diff)
downloadexchange-4702b156dc8130a842745035c936de8817c7c700.tar.xz
-work on reserve control tests
Diffstat (limited to 'src')
-rw-r--r--src/exchange/taler-exchange-httpd.c44
-rw-r--r--src/exchange/taler-exchange-httpd_reserves_attest.c27
-rw-r--r--src/exchange/taler-exchange-httpd_reserves_attest.h8
-rw-r--r--src/exchange/taler-exchange-httpd_reserves_open.c15
-rw-r--r--src/exchangedb/common-0001.sql5
-rw-r--r--src/exchangedb/exchange-0001-part.sql4
-rw-r--r--src/exchangedb/pg_insert_records_by_table.c7
-rw-r--r--src/exchangedb/procedures.sql41
-rw-r--r--src/include/taler_exchangedb_plugin.h1
-rw-r--r--src/lib/exchange_api_reserves_attest.c8
-rw-r--r--src/lib/exchange_api_reserves_get_attestable.c4
-rw-r--r--src/testing/test_exchange_p2p.c14
-rw-r--r--src/testing/testing_api_cmd_reserve_open.c6
13 files changed, 100 insertions, 84 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index a45c9d2b4..34f93879a 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -389,10 +389,6 @@ handle_post_reserves (struct TEH_RequestContext *rc,
.handler = &TEH_handler_reserves_open
},
{
- .op = "attest",
- .handler = &TEH_handler_reserves_attest
- },
- {
.op = "close",
.handler = &TEH_handler_reserves_close
},
@@ -1055,27 +1051,6 @@ handle_post_auditors (struct TEH_RequestContext *rc,
/**
- * Handle a GET "/reserves/$RID/$XXX" request.
- *
- * @param rc request context
- * @param args array of additional options (length: 1, just the reserve_pub)
- * @return MHD result code
- */
-static MHD_RESULT
-handler_reserves_get3 (struct TEH_RequestContext *rc,
- const char *const args[3])
-{
- if (0 == strcmp (args[2],
- "attest"))
- return TEH_handler_reserves_get_attest (rc,
- args);
- GNUNET_break_op (0);
- return r404 (rc->connection,
- "/reserves/$RID/*");
-}
-
-
-/**
* Handle incoming HTTP request.
*
* @param cls closure for MHD daemon (unused)
@@ -1190,15 +1165,21 @@ handle_mhd_request (void *cls,
},
{
.url = "reserves",
+ .method = MHD_HTTP_METHOD_POST,
+ .handler.post = &handle_post_reserves,
+ .nargs = 2
+ },
+ {
+ .url = "reserves-attest",
.method = MHD_HTTP_METHOD_GET,
- .handler.get = &handler_reserves_get3,
- .nargs = 3
+ .handler.get = &TEH_handler_reserves_get_attest,
+ .nargs = 1
},
{
- .url = "reserves",
+ .url = "reserves-attest",
.method = MHD_HTTP_METHOD_POST,
- .handler.post = &handle_post_reserves,
- .nargs = 2
+ .handler.post = &TEH_handler_reserves_attest,
+ .nargs = 1
},
/* coins */
{
@@ -1441,7 +1422,8 @@ handle_mhd_request (void *cls,
continue;
found = true;
/* The URL is a match! What we now do depends on the method. */
- if (0 == strcasecmp (method, MHD_HTTP_METHOD_OPTIONS))
+ if (0 == strcasecmp (method,
+ MHD_HTTP_METHOD_OPTIONS))
{
GNUNET_async_scope_restore (&old_scope);
return TALER_MHD_reply_cors_preflight (connection);
diff --git a/src/exchange/taler-exchange-httpd_reserves_attest.c b/src/exchange/taler-exchange-httpd_reserves_attest.c
index a740bb25a..f88f2c300 100644
--- a/src/exchange/taler-exchange-httpd_reserves_attest.c
+++ b/src/exchange/taler-exchange-httpd_reserves_attest.c
@@ -48,7 +48,7 @@ struct ReserveAttestContext
/**
* Public key of the reserve the inquiry is about.
*/
- const struct TALER_ReservePublicKeyP *reserve_pub;
+ struct TALER_ReservePublicKeyP reserve_pub;
/**
* Hash of the payto URI of this reserve.
@@ -122,7 +122,7 @@ reply_reserve_attest_success (struct MHD_Connection *connection,
&TEH_keys_exchange_sign_,
now,
rhc->etime,
- rhc->reserve_pub,
+ &rhc->reserve_pub,
rhc->json_attest,
&exchange_pub,
&exchange_sig);
@@ -273,8 +273,8 @@ reserve_attest_transaction (void *cls,
MHD_RESULT
TEH_handler_reserves_attest (struct TEH_RequestContext *rc,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const json_t *root)
+ const json_t *root,
+ const char *const args[1])
{
struct ReserveAttestContext rsc = {
.etime = GNUNET_TIME_UNIT_FOREVER_TS
@@ -291,7 +291,18 @@ TEH_handler_reserves_attest (struct TEH_RequestContext *rc,
};
struct GNUNET_TIME_Timestamp now;
- rsc.reserve_pub = reserve_pub;
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[0],
+ strlen (args[0]),
+ &rsc.reserve_pub,
+ sizeof (rsc.reserve_pub)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_RESERVE_PUB_MALFORMED,
+ args[0]);
+ }
{
enum GNUNET_GenericReturnValue res;
@@ -324,7 +335,7 @@ TEH_handler_reserves_attest (struct TEH_RequestContext *rc,
if (GNUNET_OK !=
TALER_wallet_reserve_attest_request_verify (rsc.timestamp,
rsc.details,
- reserve_pub,
+ &rsc.reserve_pub,
&rsc.reserve_sig))
{
GNUNET_break_op (0);
@@ -338,7 +349,7 @@ TEH_handler_reserves_attest (struct TEH_RequestContext *rc,
char *payto_uri;
payto_uri = TALER_reserve_make_payto (TEH_base_url,
- rsc.reserve_pub);
+ &rsc.reserve_pub);
TALER_payto_hash (payto_uri,
&rsc.h_payto);
GNUNET_free (payto_uri);
@@ -360,7 +371,7 @@ TEH_handler_reserves_attest (struct TEH_RequestContext *rc,
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN,
- NULL);
+ args[0]);
}
if (TALER_EC_NONE != rsc.ec)
{
diff --git a/src/exchange/taler-exchange-httpd_reserves_attest.h b/src/exchange/taler-exchange-httpd_reserves_attest.h
index d5ec8fd70..66bbdf712 100644
--- a/src/exchange/taler-exchange-httpd_reserves_attest.h
+++ b/src/exchange/taler-exchange-httpd_reserves_attest.h
@@ -26,16 +26,16 @@
/**
- * Handle a POST "/reserves/$RID/attest" request.
+ * Handle a POST "/reserves-attest/$RID" request.
*
* @param rc request context
- * @param reserve_pub public key of the reserve
* @param root uploaded body from the client
+ * @param args args[0] has public key of the reserve
* @return MHD result code
*/
MHD_RESULT
TEH_handler_reserves_attest (struct TEH_RequestContext *rc,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const json_t *root);
+ const json_t *root,
+ const char *const args[1]);
#endif
diff --git a/src/exchange/taler-exchange-httpd_reserves_open.c b/src/exchange/taler-exchange-httpd_reserves_open.c
index 6ad2592f2..ced291d77 100644
--- a/src/exchange/taler-exchange-httpd_reserves_open.c
+++ b/src/exchange/taler-exchange-httpd_reserves_open.c
@@ -108,6 +108,7 @@ struct ReserveOpenContext
* for the operation.
*/
bool no_funds;
+
};
@@ -122,6 +123,8 @@ static MHD_RESULT
reply_reserve_open_success (struct MHD_Connection *connection,
const struct ReserveOpenContext *rsc)
{
+ struct GNUNET_TIME_Timestamp now;
+ struct GNUNET_TIME_Timestamp re;
unsigned int status;
status = MHD_HTTP_OK;
@@ -129,11 +132,18 @@ reply_reserve_open_success (struct MHD_Connection *connection,
<,
rsc->desired_expiration))
status = MHD_HTTP_PAYMENT_REQUIRED;
+ now = GNUNET_TIME_timestamp_get ();
+ if (GNUNET_TIME_timestamp_cmp (rsc->reserve_expiration,
+ <,
+ now))
+ re = now;
+ else
+ re = rsc->reserve_expiration;
return TALER_MHD_REPLY_JSON_PACK (
connection,
status,
GNUNET_JSON_pack_timestamp ("reserve_expiration",
- rsc->reserve_expiration),
+ re),
TALER_JSON_pack_amount ("open_cost",
&rsc->open_cost));
}
@@ -234,7 +244,8 @@ reserve_open_transaction (void *cls,
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Do reserve open\n");
+ "Do reserve open with reserve payment of %s\n",
+ TALER_amount2s (&rsc->total));
qs = TEH_plugin->do_reserve_open (TEH_plugin->cls,
/* inputs */
rsc->reserve_pub,
diff --git a/src/exchangedb/common-0001.sql b/src/exchangedb/common-0001.sql
index 21f531102..68d8643ed 100644
--- a/src/exchangedb/common-0001.sql
+++ b/src/exchangedb/common-0001.sql
@@ -460,8 +460,7 @@ BEGIN
'CREATE TABLE IF NOT EXISTS %I'
'(reserve_open_deposit_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY' -- UNIQUE / PRIMARY KEY'
',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
- ',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=32)'
- ',request_timestamp INT8 NOT NULL'
+ ',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32)'
',coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)'
',coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)'
',contribution_val INT8 NOT NULL'
@@ -482,7 +481,7 @@ BEGIN
EXECUTE FORMAT (
'CREATE INDEX IF NOT EXISTS ' || table_name || '_by_reserve '
'ON ' || table_name || ' '
- '(reserve_pub,request_timestamp);'
+ '(reserve_pub);'
);
END
$$;
diff --git a/src/exchangedb/exchange-0001-part.sql b/src/exchangedb/exchange-0001-part.sql
index c9c3e2f04..48515a478 100644
--- a/src/exchangedb/exchange-0001-part.sql
+++ b/src/exchangedb/exchange-0001-part.sql
@@ -259,8 +259,8 @@ SELECT create_table_reserves_open_deposits();
COMMENT ON TABLE reserves_open_deposits
IS 'coin contributions paying for a reserve to remain open';
-COMMENT ON COLUMN reserves_open_deposits.request_timestamp
- IS 'Identifies the specific reserve open request being paid for.';
+COMMENT ON COLUMN reserves_open_deposits.reserve_pub
+ IS 'Identifies the specific reserve being paid for (possibly together with reserve_sig).';
CREATE TABLE IF NOT EXISTS reserves_open_deposits_default
PARTITION OF reserves_open_deposits
diff --git a/src/exchangedb/pg_insert_records_by_table.c b/src/exchangedb/pg_insert_records_by_table.c
index f70cce225..90d389873 100644
--- a/src/exchangedb/pg_insert_records_by_table.c
+++ b/src/exchangedb/pg_insert_records_by_table.c
@@ -358,8 +358,6 @@ irbt_cb_table_reserves_open_requests (struct PostgresClosure *pg,
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&td->serial),
GNUNET_PQ_query_param_timestamp (
- &td->details.reserves_open_requests.request_timestamp),
- GNUNET_PQ_query_param_timestamp (
&td->details.reserves_open_requests.expiration_date),
GNUNET_PQ_query_param_auto_from_type (
&td->details.reserves_open_requests.reserve_sig),
@@ -402,8 +400,6 @@ irbt_cb_table_reserves_open_deposits (
{
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&td->serial),
- GNUNET_PQ_query_param_timestamp (
- &td->details.reserves_open_deposits.request_timestamp),
GNUNET_PQ_query_param_auto_from_type (
&td->details.reserves_open_deposits.coin_pub),
GNUNET_PQ_query_param_auto_from_type (
@@ -421,13 +417,12 @@ irbt_cb_table_reserves_open_deposits (
"(reserve_open_deposit_uuid"
",reserve_sig"
",reserve_pub"
- ",request_timestamp"
",coin_pub"
",coin_sig"
",contribution_val"
",contribution_frac"
") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8);");
+ "($1, $2, $3, $4, $5, $6, $7);");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"insert_into_table_reserves_open_deposits",
params);
diff --git a/src/exchangedb/procedures.sql b/src/exchangedb/procedures.sql
index 90fb7d321..912a37dbc 100644
--- a/src/exchangedb/procedures.sql
+++ b/src/exchangedb/procedures.sql
@@ -2119,7 +2119,6 @@ BEGIN
INSERT INTO exchange.reserves_open_deposits
(reserve_sig
,reserve_pub
- ,request_timestamp
,coin_pub
,coin_sig
,contribution_val
@@ -2128,7 +2127,6 @@ INSERT INTO exchange.reserves_open_deposits
VALUES
(in_reserve_sig
,in_reserve_pub
- ,in_request_timestamp
,in_coin_pub
,in_coin_sig
,in_coin_total_val
@@ -2237,8 +2235,9 @@ WHERE
IF NOT FOUND
THEN
- -- FIXME: do we need to set a 'not found'?
- RETURN;
+ -- FIXME: do we need to set a 'not found'?
+ RAISE NOTICE 'reserve not found';
+ RETURN;
END IF;
-- Do not allow expiration time to start in the past already
@@ -2272,9 +2271,10 @@ THEN
my_purses_allowed = my_purses_allowed + (in_default_purse_limit * my_years_tmp);
END IF;
+
-- Compute cost based on annual fees
IF (my_years > 0)
-THEN
+THEN
my_cost_val = my_years * in_open_fee_val;
my_cost_tmp = my_years * in_open_fee_frac / 100000000;
IF (CAST (my_cost_val + my_cost_tmp AS INT8) < my_cost_val)
@@ -2282,8 +2282,9 @@ THEN
out_open_cost_val=9223372036854775807;
out_open_cost_frac=2147483647;
out_final_expiration=my_expiration_date;
- out_no_funds=true;
- RETURN;
+ out_no_funds=FALSE;
+ RAISE NOTICE 'arithmetic issue computing amount';
+ RETURN;
END IF;
my_cost_val = CAST (my_cost_val + my_cost_tmp AS INT8);
my_cost_frac = my_years * in_open_fee_frac % 100000000;
@@ -2297,6 +2298,7 @@ THEN
out_open_cost_val = 0;
out_open_cost_frac = 0;
out_no_funds=FALSE;
+ RAISE NOTICE 'no change required';
RETURN;
END IF;
@@ -2305,10 +2307,22 @@ IF ( (in_total_paid_val < my_cost_val) OR
( (in_total_paid_val = my_cost_val) AND
(in_total_paid_frac < my_cost_frac) ) )
THEN
- out_final_expiration=my_reserve_expiration;
out_open_cost_val = my_cost_val;
out_open_cost_frac = my_cost_frac;
- out_no_funds=TRUE;
+ out_no_funds=FALSE;
+ -- We must return a failure, which is indicated by
+ -- the expiration being below the desired expiration.
+ IF (my_reserve_expiration >= in_desired_expiration)
+ THEN
+ -- This case is relevant especially if the purse
+ -- count was to be increased and the payment was
+ -- insufficient to cover this for the full period.
+ RAISE NOTICE 'forcing low expiration time';
+ out_final_expiration = 0;
+ ELSE
+ out_final_expiration = my_reserve_expiration;
+ END IF;
+ RAISE NOTICE 'amount paid too low';
RETURN;
END IF;
@@ -2329,11 +2343,12 @@ ELSE
my_balance_val=0;
my_balance_frac=my_balance_frac - in_reserve_payment_frac;
ELSE
- out_final_expiration=my_reserve_expiration;
+ out_final_expiration = my_reserve_expiration;
out_open_cost_val = my_cost_val;
out_open_cost_frac = my_cost_frac;
out_no_funds=TRUE;
- RETURN;
+ RAISE NOTICE 'reserve balance too low';
+ RETURN;
END IF;
END IF;
@@ -2341,12 +2356,12 @@ UPDATE reserves SET
current_balance_val=my_balance_val
,current_balance_frac=my_balance_frac
,gc_date=my_reserve_expiration + in_reserve_gc_delay
- ,expiration_date=my_reserve_expiration
+ ,expiration_date=my_expiration_date
,purses_allowed=my_purses_allowed
WHERE
reserve_pub=in_reserve_pub;
-out_final_expiration=my_reserve_expiration;
+out_final_expiration=my_expiration_date;
out_open_cost_val = my_cost_val;
out_open_cost_frac = my_cost_frac;
out_no_funds=FALSE;
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 008909c31..06fa2479d 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -331,7 +331,6 @@ struct TALER_EXCHANGEDB_TableData
struct
{
struct TALER_ReservePublicKeyP reserve_pub;
- struct GNUNET_TIME_Timestamp request_timestamp;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_ReserveSignatureP reserve_sig;
diff --git a/src/lib/exchange_api_reserves_attest.c b/src/lib/exchange_api_reserves_attest.c
index a7a89a2ef..c1cf82761 100644
--- a/src/lib/exchange_api_reserves_attest.c
+++ b/src/lib/exchange_api_reserves_attest.c
@@ -16,7 +16,7 @@
*/
/**
* @file lib/exchange_api_reserves_attest.c
- * @brief Implementation of the POST /reserves/$RESERVE_PUB/attest requests
+ * @brief Implementation of the POST /reserves-attest/$RESERVE_PUB requests
* @author Christian Grothoff
*/
#include "platform.h"
@@ -33,7 +33,7 @@
/**
- * @brief A /reserves/$RID/attest Handle
+ * @brief A /reserves-attest/$RID Handle
*/
struct TALER_EXCHANGE_ReservesAttestHandle
{
@@ -141,7 +141,7 @@ handle_reserves_attest_ok (struct TALER_EXCHANGE_ReservesAttestHandle *rsh,
/**
* Function called when we're done processing the
- * HTTP /reserves/$RID/attest request.
+ * HTTP /reserves-attest/$RID request.
*
* @param cls the `struct TALER_EXCHANGE_ReservesAttestHandle`
* @param response_code HTTP response code, 0 on error
@@ -280,7 +280,7 @@ TALER_EXCHANGE_reserves_attest (
*end = '\0';
GNUNET_snprintf (arg_str,
sizeof (arg_str),
- "/reserves/%s/attest",
+ "/reserves-attest/%s",
pub_str);
}
rsh->url = TEAH_path_to_url (exchange,
diff --git a/src/lib/exchange_api_reserves_get_attestable.c b/src/lib/exchange_api_reserves_get_attestable.c
index 401418cd4..3a5fd25d8 100644
--- a/src/lib/exchange_api_reserves_get_attestable.c
+++ b/src/lib/exchange_api_reserves_get_attestable.c
@@ -133,7 +133,7 @@ handle_reserves_get_attestable_ok (
/**
* Function called when we're done processing the
- * HTTP GET /reserves/$RID/attest request.
+ * HTTP GET /reserves-attest/$RID request.
*
* @param cls the `struct TALER_EXCHANGE_ReservesGetAttestableHandle`
* @param response_code HTTP response code, 0 on error
@@ -241,7 +241,7 @@ TALER_EXCHANGE_reserves_get_attestable (
*end = '\0';
GNUNET_snprintf (arg_str,
sizeof (arg_str),
- "/reserves/%s/attest",
+ "/reserves-attest/%s",
pub_str);
}
rgah = GNUNET_new (struct TALER_EXCHANGE_ReservesGetAttestHandle);
diff --git a/src/testing/test_exchange_p2p.c b/src/testing/test_exchange_p2p.c
index d0a0a9898..693391c6c 100644
--- a/src/testing/test_exchange_p2p.c
+++ b/src/testing/test_exchange_p2p.c
@@ -382,7 +382,7 @@ run (void *cls,
MHD_HTTP_PAYMENT_REQUIRED, // FIXME: or CONFLICT?
NULL,
NULL),
- TALER_TESTING_cmd_reserve_open ("reserve-open-101-ok",
+ TALER_TESTING_cmd_reserve_open ("reserve-open-101-ok-a",
"create-reserve-101",
"EUR:0.01",
GNUNET_TIME_UNIT_MONTHS,
@@ -394,30 +394,32 @@ run (void *cls,
"create-reserve-101",
"EUR:1.03",
MHD_HTTP_OK),
- TALER_TESTING_cmd_reserve_open ("reserve-open-101-ok",
+ TALER_TESTING_cmd_reserve_open ("reserve-open-101-ok-b",
"create-reserve-101",
"EUR:0",
GNUNET_TIME_UNIT_MONTHS,
2, /* min purses */
MHD_HTTP_OK,
"withdraw-coin-100",
- "EUR:0.02",
+ "EUR:0.03", /* 0.02 for the reserve open, 0.01 for deposit fee */
NULL,
NULL),
- /* FIXME: use purse quota here */
+ /* FIXME: use purse creation with purse quota here */
TALER_TESTING_cmd_reserve_get_attestable ("reserve-101-attestable",
"create-reserve-101",
- MHD_HTTP_OK,
+ MHD_HTTP_NOT_FOUND,
NULL),
TALER_TESTING_cmd_reserve_get_attestable ("reserve-101-attest",
"create-reserve-101",
- MHD_HTTP_CONFLICT,
+ MHD_HTTP_NOT_FOUND,
"nx-attribute-name",
NULL),
+#if 0
TALER_TESTING_cmd_reserve_close ("reserve-101-close",
"create-reserve-101",
NULL, /* to origin */
MHD_HTTP_OK),
+#endif
TALER_TESTING_cmd_end ()
};
diff --git a/src/testing/testing_api_cmd_reserve_open.c b/src/testing/testing_api_cmd_reserve_open.c
index 67209d02e..cc0e649d2 100644
--- a/src/testing/testing_api_cmd_reserve_open.c
+++ b/src/testing/testing_api_cmd_reserve_open.c
@@ -319,6 +319,7 @@ TALER_TESTING_cmd_reserve_open (const char *label,
ss->cpl++;
va_end (ap);
GNUNET_assert (0 == (ss->cpl % 2));
+ ss->cpl /= 2; /* name and amount per coin */
ss->cd = GNUNET_new_array (ss->cpl,
struct CoinDetail);
i = 0;
@@ -326,11 +327,12 @@ TALER_TESTING_cmd_reserve_open (const char *label,
expected_response_code);
while (NULL != (name = va_arg (ap, const char *)))
{
- ss->cd[i].name = name;
+ struct CoinDetail *cd = &ss->cd[i];
+ cd->name = name;
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount (va_arg (ap,
const char *),
- &ss->cd[i].amount));
+ &cd->amount));
i++;
}
va_end (ap);