From 4ea4f03aea4bf78854e19261edba42f17aad1955 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 2 Oct 2022 12:28:40 +0200 Subject: taler-exchange-httpd_reserves_open.c now builds (but not complete) --- src/exchange/Makefile.am | 1 + src/exchange/taler-exchange-httpd.c | 2 +- src/exchange/taler-exchange-httpd_common_deposit.c | 48 ----- .../taler-exchange-httpd_reserves_attest.c | 2 +- src/exchange/taler-exchange-httpd_reserves_close.c | 2 +- src/exchange/taler-exchange-httpd_reserves_get.c | 2 +- .../taler-exchange-httpd_reserves_get_attest.c | 4 +- src/exchange/taler-exchange-httpd_reserves_open.c | 196 ++++++++++++++++----- 8 files changed, 161 insertions(+), 96 deletions(-) (limited to 'src/exchange') diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index 4d7d6d948..db7aca469 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -163,6 +163,7 @@ taler_exchange_httpd_SOURCES = \ taler-exchange-httpd_refund.c taler-exchange-httpd_refund.h \ taler-exchange-httpd_reserves_get.c taler-exchange-httpd_reserves_get.h \ taler-exchange-httpd_reserves_history.c taler-exchange-httpd_reserves_history.h \ + taler-exchange-httpd_reserves_open.c taler-exchange-httpd_reserves_open.h \ taler-exchange-httpd_reserves_purse.c taler-exchange-httpd_reserves_purse.h \ taler-exchange-httpd_reserves_status.c taler-exchange-httpd_reserves_status.h \ taler-exchange-httpd_responses.c taler-exchange-httpd_responses.h \ diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 496d3d29f..9349a5a21 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -395,7 +395,7 @@ handle_post_reserves (struct TEH_RequestContext *rc, GNUNET_break_op (0); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_GENERIC_RESERVE_PUB_MALFORMED, + TALER_EC_GENERIC_RESERVE_PUB_MALFORMED, args[0]); } for (unsigned int i = 0; NULL != h[i].op; i++) diff --git a/src/exchange/taler-exchange-httpd_common_deposit.c b/src/exchange/taler-exchange-httpd_common_deposit.c index ecb13630c..0c91f0bc9 100644 --- a/src/exchange/taler-exchange-httpd_common_deposit.c +++ b/src/exchange/taler-exchange-httpd_common_deposit.c @@ -265,51 +265,3 @@ TEH_common_purse_deposit_free_coin (struct TEH_PurseDepositedCoin *coin) if (! coin->cpi.no_age_commitment) GNUNET_free (coin->age_commitment.keys); /* Only the keys have been allocated */ } - - -#if LEGACY - -if (0 > - TALER_amount_add (&pcc->deposit_total, - &pcc->deposit_total, - &coin->amount_minus_fee)) -{ - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT, - "total deposit contribution"); -} - - -{ - MHD_RESULT mhd_ret = MHD_NO; - enum GNUNET_DB_QueryStatus qs; - - /* make sure coin is 'known' in database */ - for (unsigned int tries = 0; triescpi, - connection, - &coin->known_coin_id, - &mhd_ret); - /* no transaction => no serialization failures should be possible */ - if (GNUNET_DB_STATUS_SOFT_ERROR != qs) - break; - } - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - { - GNUNET_break (0); - return (MHD_YES == - TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_COMMIT_FAILED, - "make_coin_known")) - ? GNUNET_NO : GNUNET_SYSERR; - } - if (qs < 0) - return (MHD_YES == mhd_ret) ? GNUNET_NO : GNUNET_SYSERR; -} -return GNUNET_OK; -} -#endif diff --git a/src/exchange/taler-exchange-httpd_reserves_attest.c b/src/exchange/taler-exchange-httpd_reserves_attest.c index 94399f076..2bde9eb2b 100644 --- a/src/exchange/taler-exchange-httpd_reserves_attest.c +++ b/src/exchange/taler-exchange-httpd_reserves_attest.c @@ -281,7 +281,7 @@ TEH_handler_reserves_attest (struct TEH_RequestContext *rc, { return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_RESERVES_STATUS_UNKNOWN, + TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN, NULL); } mhd_ret = reply_reserve_attest_success (rc->connection, diff --git a/src/exchange/taler-exchange-httpd_reserves_close.c b/src/exchange/taler-exchange-httpd_reserves_close.c index 286669240..4d44fe6cf 100644 --- a/src/exchange/taler-exchange-httpd_reserves_close.c +++ b/src/exchange/taler-exchange-httpd_reserves_close.c @@ -148,7 +148,7 @@ reserve_close_transaction (void *cls, *mhd_ret = TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_RESERVES_STATUS_UNKNOWN, + TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN, NULL); return GNUNET_DB_STATUS_HARD_ERROR; } diff --git a/src/exchange/taler-exchange-httpd_reserves_get.c b/src/exchange/taler-exchange-httpd_reserves_get.c index 19fb7df8e..88f7aca9c 100644 --- a/src/exchange/taler-exchange-httpd_reserves_get.c +++ b/src/exchange/taler-exchange-httpd_reserves_get.c @@ -247,7 +247,7 @@ TEH_handler_reserves_get (struct TEH_RequestContext *rc, GNUNET_break_op (0); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, - TALER_EC_MERCHANT_GENERIC_RESERVE_PUB_MALFORMED, + TALER_EC_GENERIC_RESERVE_PUB_MALFORMED, args[0]); } { diff --git a/src/exchange/taler-exchange-httpd_reserves_get_attest.c b/src/exchange/taler-exchange-httpd_reserves_get_attest.c index 7d98babc0..741c342eb 100644 --- a/src/exchange/taler-exchange-httpd_reserves_get_attest.c +++ b/src/exchange/taler-exchange-httpd_reserves_get_attest.c @@ -110,7 +110,7 @@ TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc, GNUNET_break_op (0); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, - TALER_EC_MERCHANT_GENERIC_RESERVE_PUB_MALFORMED, + TALER_EC_GENERIC_RESERVE_PUB_MALFORMED, args[0]); } { @@ -132,7 +132,7 @@ TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc, { return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_RESERVES_STATUS_UNKNOWN, + TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN, args[0]); } return TALER_MHD_REPLY_JSON_PACK ( diff --git a/src/exchange/taler-exchange-httpd_reserves_open.c b/src/exchange/taler-exchange-httpd_reserves_open.c index 9ef736f90..160814b65 100644 --- a/src/exchange/taler-exchange-httpd_reserves_open.c +++ b/src/exchange/taler-exchange-httpd_reserves_open.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 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 @@ -24,6 +24,7 @@ #include "taler_mhd_lib.h" #include "taler_json_lib.h" #include "taler_dbevents.h" +#include "taler-exchange-httpd_common_deposit.h" #include "taler-exchange-httpd_keys.h" #include "taler-exchange-httpd_reserves_open.h" #include "taler-exchange-httpd_responses.h" @@ -47,6 +48,16 @@ struct ReserveOpenContext */ const struct TALER_ReservePublicKeyP *reserve_pub; + /** + * Desired (minimum) expiration time for the reserve. + */ + struct GNUNET_TIME_Timestamp desired_expiration; + + /** + * Actual expiration time for the reserve. + */ + struct GNUNET_TIME_Timestamp reserve_expiration; + /** * Timestamp of the request. */ @@ -58,19 +69,34 @@ struct ReserveOpenContext struct TALER_ReserveSignatureP reserve_sig; /** - * Open of the reserve, set in the callback. + * Global fees applying to the request. */ - struct TALER_EXCHANGEDB_ReserveOpen *rh; + const struct TEH_GlobalFee *gf; /** - * Global fees applying to the request. + * Amount to be paid from the reserve. */ - const struct TEH_GlobalFee *gf; + struct TALER_Amount reserve_payment; + + /** + * Actual cost to open the reserve. + */ + struct TALER_Amount open_cost; + + /** + * Information about payments by coin. + */ + struct TEH_PurseDepositedCoin *payments; + + /** + * Length of the @e payments array. + */ + unsigned int payments_len; /** - * Current reserve balance. + * Desired minimum purse limit. */ - struct TALER_Amount balance; + uint32_t purse_limit; }; @@ -83,15 +109,32 @@ struct ReserveOpenContext */ static MHD_RESULT reply_reserve_open_success (struct MHD_Connection *connection, - const struct ReserveOpenContext *rhc) + const struct ReserveOpenContext *rsc) { - const struct TALER_EXCHANGEDB_ReserveOpen *rh = rhc->rh; - return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, - TALER_JSON_pack_amount ("balance", - &rhc->balance)); + GNUNET_JSON_pack_timestamp ("reserve_expiration", + rsc->reserve_expiration), + TALER_JSON_pack_amount ("open_cost", + &rsc->open_cost)); +} + + +/** + * Cleans up information in @a rsc, but does not + * free @a rsc itself (allocated on the stack!). + * + * @param[in] rsc struct with information to clean up + */ +static void +cleanup_rsc (struct ReserveOpenContext *rsc) +{ + for (unsigned int i = 0; ipayments_len; i++) + { + TEH_common_purse_deposit_free_coin (&rsc->payments[i]); + } + GNUNET_free (rsc->payments); } @@ -118,6 +161,8 @@ reserve_open_transaction (void *cls, struct ReserveOpenContext *rsc = cls; enum GNUNET_DB_QueryStatus qs; + (void) rsc; +#if 0 if (! TALER_amount_is_zero (&rsc->gf->fees.open)) { bool balance_ok = false; @@ -161,14 +206,29 @@ reserve_open_transaction (void *cls, rsc->reserve_pub, &rsc->balance, &rsc->rh); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) +#endif + qs = GNUNET_DB_STATUS_HARD_ERROR; + switch (qs) { + case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); *mhd_ret = TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_FETCH_FAILED, "get_reserve_open"); + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_DB_STATUS_SOFT_ERROR: + return qs; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + *mhd_ret + = TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN, + NULL); + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; } return qs; } @@ -180,15 +240,23 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc, const json_t *root) { struct ReserveOpenContext rsc; - MHD_RESULT mhd_ret; + json_t *payments; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_timestamp ("request_timestamp", &rsc.timestamp), + GNUNET_JSON_spec_timestamp ("reserve_expiration", + &rsc.desired_expiration), GNUNET_JSON_spec_fixed_auto ("reserve_sig", &rsc.reserve_sig), + GNUNET_JSON_spec_uint32 ("purse_limit", + &rsc.purse_limit), + GNUNET_JSON_spec_json ("payments", + &payments), + TALER_JSON_spec_amount ("reserve_payment", + TEH_currency, + &rsc.reserve_payment), GNUNET_JSON_spec_end () }; - struct GNUNET_TIME_Timestamp now; rsc.reserve_pub = reserve_pub; { @@ -208,17 +276,50 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc, return MHD_YES; /* failure */ } } - now = GNUNET_TIME_timestamp_get (); - 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); + struct GNUNET_TIME_Timestamp now; + + now = GNUNET_TIME_timestamp_get (); + 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.payments_len = json_array_size (payments); + rsc.payments = GNUNET_new_array (rsc.payments_len, + struct TEH_PurseDepositedCoin); + for (unsigned int i = 0; iconnection, + coin, + json_array_get (payments, + i)); + if (GNUNET_SYSERR == res) + { + GNUNET_break (0); + cleanup_rsc (&rsc); + return MHD_NO; /* hard failure */ + } + if (GNUNET_NO == res) + { + GNUNET_break_op (0); + cleanup_rsc (&rsc); + return MHD_YES; /* failure */ + } + } + { struct TEH_KeyStateHandle *keys; @@ -227,6 +328,7 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc, { GNUNET_break (0); GNUNET_JSON_parse_free (spec); + cleanup_rsc (&rsc); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, @@ -238,43 +340,53 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc, if (NULL == rsc.gf) { GNUNET_break (0); + cleanup_rsc (&rsc); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION, NULL); } + if (GNUNET_OK != - TALER_wallet_reserve_open_verify (rsc.timestamp, - &rsc.gf->fees.open, + TALER_wallet_reserve_open_verify (&rsc.reserve_payment, + rsc.timestamp, + rsc.desired_expiration, + rsc.purse_limit, reserve_pub, &rsc.reserve_sig)) { GNUNET_break_op (0); + cleanup_rsc (&rsc); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_FORBIDDEN, TALER_EC_EXCHANGE_RESERVES_OPEN_BAD_SIGNATURE, NULL); } - rsc.rh = NULL; - if (GNUNET_OK != - TEH_DB_run_transaction (rc->connection, - "reserve open", - TEH_MT_REQUEST_OTHER, - &mhd_ret, - &reserve_open_transaction, - &rsc)) + { - return mhd_ret; + MHD_RESULT mhd_ret; + + if (GNUNET_OK != + TEH_DB_run_transaction (rc->connection, + "reserve open", + TEH_MT_REQUEST_OTHER, + &mhd_ret, + &reserve_open_transaction, + &rsc)) + { + cleanup_rsc (&rsc); + return mhd_ret; + } } - if (NULL == rsc.rh) + { - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_RESERVES_STATUS_UNKNOWN, - NULL); + MHD_RESULT mhd_ret; + + mhd_ret = reply_reserve_open_success (rc->connection, + &rsc); + cleanup_rsc (&rsc); + return mhd_ret; } - return reply_reserve_open_success (rc->connection, - &rsc); } -- cgit v1.2.3