commit de9ab28ab9e55597baf2ca32194ec65b441f0f36
parent cef3b713acde7d8a3c4ecf5b4f2df24d054e0046
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 27 Feb 2020 23:46:53 +0100
rename fest, make symbols better match new endpoint names
Diffstat:
31 files changed, 2103 insertions(+), 2140 deletions(-)
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
@@ -49,6 +49,7 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd.c taler-exchange-httpd.h \
taler-exchange-httpd_db.c taler-exchange-httpd_db.h \
taler-exchange-httpd_deposit.c taler-exchange-httpd_deposit.h \
+ taler-exchange-httpd_deposits_get.c taler-exchange-httpd_deposits_get.h \
taler-exchange-httpd_keystate.c taler-exchange-httpd_keystate.h \
taler-exchange-httpd_mhd.c taler-exchange-httpd_mhd.h \
taler-exchange-httpd_recoup.c taler-exchange-httpd_recoup.h \
@@ -56,13 +57,12 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd_refresh_melt.c taler-exchange-httpd_refresh_melt.h \
taler-exchange-httpd_refresh_reveal.c taler-exchange-httpd_refresh_reveal.h \
taler-exchange-httpd_refund.c taler-exchange-httpd_refund.h \
- taler-exchange-httpd_reserve_status.c taler-exchange-httpd_reserve_status.h \
- taler-exchange-httpd_reserve_withdraw.c taler-exchange-httpd_reserve_withdraw.h \
+ taler-exchange-httpd_reserves_get.c taler-exchange-httpd_reserves_get.h \
taler-exchange-httpd_responses.c taler-exchange-httpd_responses.h \
taler-exchange-httpd_terms.c taler-exchange-httpd_terms.h \
- taler-exchange-httpd_track_transaction.c taler-exchange-httpd_track_transaction.h \
- taler-exchange-httpd_track_transfer.c taler-exchange-httpd_track_transfer.h \
+ taler-exchange-httpd_transfers_get.c taler-exchange-httpd_transfers_get.h \
taler-exchange-httpd_wire.c taler-exchange-httpd_wire.h \
+ taler-exchange-httpd_withdraw.c taler-exchange-httpd_withdraw.h \
taler-exchange-httpd_validation.c taler-exchange-httpd_validation.h
taler_exchange_httpd_LDADD = \
$(LIBGCRYPT_LIBS) \
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
@@ -30,15 +30,15 @@
#include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_deposit.h"
#include "taler-exchange-httpd_refund.h"
-#include "taler-exchange-httpd_reserve_status.h"
-#include "taler-exchange-httpd_reserve_withdraw.h"
+#include "taler-exchange-httpd_reserves_get.h"
+#include "taler-exchange-httpd_withdraw.h"
#include "taler-exchange-httpd_recoup.h"
#include "taler-exchange-httpd_refresh_link.h"
#include "taler-exchange-httpd_refresh_melt.h"
#include "taler-exchange-httpd_refresh_reveal.h"
#include "taler-exchange-httpd_terms.h"
-#include "taler-exchange-httpd_track_transfer.h"
-#include "taler-exchange-httpd_track_transaction.h"
+#include "taler-exchange-httpd_transfers_get.h"
+#include "taler-exchange-httpd_deposits_get.h"
#include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_wire.h"
#include "taler_exchangedb_plugin.h"
diff --git a/src/exchange/taler-exchange-httpd_deposits_get.c b/src/exchange/taler-exchange-httpd_deposits_get.c
@@ -0,0 +1,422 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2017 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_deposits_get.c
+ * @brief Handle wire transfer tracking-related requests
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <jansson.h>
+#include <microhttpd.h>
+#include <pthread.h>
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
+#include "taler_signatures.h"
+#include "taler-exchange-httpd_keystate.h"
+#include "taler-exchange-httpd_deposits_get.h"
+#include "taler-exchange-httpd_responses.h"
+
+
+/**
+ * A merchant asked for details about a deposit, but
+ * we did not execute the deposit yet. Generate a 202 reply.
+ *
+ * @param connection connection to the client
+ * @param planned_exec_time planned execution time
+ * @return MHD result code
+ */
+static int
+reply_transfer_pending (struct MHD_Connection *connection,
+ struct GNUNET_TIME_Absolute planned_exec_time)
+{
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_ACCEPTED,
+ "{s:o}",
+ "execution_time",
+ GNUNET_JSON_from_time_abs (
+ planned_exec_time));
+}
+
+
+/**
+ * A merchant asked for details about a deposit. Provide
+ * them. Generates the 200 reply.
+ *
+ * @param connection connection to the client
+ * @param h_contract_terms hash of the contract
+ * @param h_wire hash of wire account details
+ * @param coin_pub public key of the coin
+ * @param coin_contribution how much did the coin we asked about
+ * contribute to the total transfer value? (deposit value minus fee)
+ * @param wtid raw wire transfer identifier
+ * @param exec_time execution time of the wire transfer
+ * @return MHD result code
+ */
+static int
+reply_track_transaction (struct MHD_Connection *connection,
+ const struct GNUNET_HashCode *h_contract_terms,
+ const struct GNUNET_HashCode *h_wire,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_Amount *coin_contribution,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ struct GNUNET_TIME_Absolute exec_time)
+{
+ struct TALER_ConfirmWirePS cw;
+ struct TALER_ExchangePublicKeyP pub;
+ struct TALER_ExchangeSignatureP sig;
+
+ cw.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE);
+ cw.purpose.size = htonl (sizeof (struct TALER_ConfirmWirePS));
+ cw.h_wire = *h_wire;
+ cw.h_contract_terms = *h_contract_terms;
+ cw.wtid = *wtid;
+ cw.coin_pub = *coin_pub;
+ cw.execution_time = GNUNET_TIME_absolute_hton (exec_time);
+ TALER_amount_hton (&cw.coin_contribution,
+ coin_contribution);
+ if (GNUNET_OK !=
+ TEH_KS_sign (&cw.purpose,
+ &pub,
+ &sig))
+ {
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
+ }
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o, s:o, s:o, s:o}",
+ "wtid", GNUNET_JSON_from_data_auto (
+ wtid),
+ "execution_time",
+ GNUNET_JSON_from_time_abs (exec_time),
+ "coin_contribution",
+ TALER_JSON_from_amount (
+ coin_contribution),
+ "exchange_sig",
+ GNUNET_JSON_from_data_auto (&sig),
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&pub));
+}
+
+
+/**
+ * Closure for #handle_wtid_data.
+ */
+struct DepositWtidContext
+{
+
+ /**
+ * Deposit details.
+ */
+ const struct TALER_DepositTrackPS *tps;
+
+ /**
+ * Public key of the merchant.
+ */
+ const struct TALER_MerchantPublicKeyP *merchant_pub;
+
+ /**
+ * Set by #handle_wtid data to the wire transfer ID.
+ */
+ struct TALER_WireTransferIdentifierRawP wtid;
+
+ /**
+ * Set by #handle_wtid data to the coin's contribution to the wire transfer.
+ */
+ struct TALER_Amount coin_contribution;
+
+ /**
+ * Set by #handle_wtid data to the fee charged to the coin.
+ */
+ struct TALER_Amount coin_fee;
+
+ /**
+ * Set by #handle_wtid data to the wire transfer execution time.
+ */
+ struct GNUNET_TIME_Absolute execution_time;
+
+ /**
+ * Set by #handle_wtid to the coin contribution to the transaction
+ * (that is, @e coin_contribution minus @e coin_fee).
+ */
+ struct TALER_Amount coin_delta;
+
+ /**
+ * Set to #GNUNET_YES by #handle_wtid if the wire transfer is still pending
+ * (and the above were not set).
+ * Set to #GNUNET_SYSERR if there was a serious error.
+ */
+ int pending;
+};
+
+
+/**
+ * Function called with the results of the lookup of the
+ * wire transfer identifier information.
+ *
+ * @param cls our context for transmission
+ * @param wtid raw wire transfer identifier, NULL
+ * if the transaction was not yet done
+ * @param coin_contribution how much did the coin we asked about
+ * contribute to the total transfer value? (deposit value including fee)
+ * @param coin_fee how much did the exchange charge for the deposit fee
+ * @param execution_time when was the transaction done, or
+ * when we expect it to be done (if @a wtid was NULL);
+ * #GNUNET_TIME_UNIT_FOREVER_ABS if the /deposit is unknown
+ * to the exchange
+ */
+static void
+handle_wtid_data (void *cls,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct TALER_Amount *coin_contribution,
+ const struct TALER_Amount *coin_fee,
+ struct GNUNET_TIME_Absolute execution_time)
+{
+ struct DepositWtidContext *ctx = cls;
+
+ if (NULL == wtid)
+ {
+ ctx->pending = GNUNET_YES;
+ ctx->execution_time = execution_time;
+ return;
+ }
+ if (GNUNET_SYSERR ==
+ TALER_amount_subtract (&ctx->coin_delta,
+ coin_contribution,
+ coin_fee))
+ {
+ GNUNET_break (0);
+ ctx->pending = GNUNET_SYSERR;
+ return;
+ }
+ ctx->wtid = *wtid;
+ ctx->execution_time = execution_time;
+ ctx->coin_contribution = *coin_contribution;
+ ctx->coin_fee = *coin_fee;
+}
+
+
+/**
+ * Execute a "/track/transaction". Returns the transfer information
+ * associated with the given deposit.
+ *
+ * If it returns a non-error code, the transaction logic MUST
+ * NOT queue a MHD response. IF it returns an hard error, the
+ * transaction logic MUST queue a MHD response and set @a mhd_ret. IF
+ * it returns the soft error code, the function MAY be called again to
+ * retry and MUST not queue a MHD response.
+ *
+ * @param cls closure of type `struct DepositWtidContext *`
+ * @param connection MHD request which triggered the transaction
+ * @param session database session to use
+ * @param[out] mhd_ret set to MHD response status for @a connection,
+ * if transaction failed (!)
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+track_transaction_transaction (void *cls,
+ struct MHD_Connection *connection,
+ struct TALER_EXCHANGEDB_Session *session,
+ int *mhd_ret)
+{
+ struct DepositWtidContext *ctx = cls;
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = TEH_plugin->wire_lookup_deposit_wtid (TEH_plugin->cls,
+ session,
+ &ctx->tps->h_contract_terms,
+ &ctx->tps->h_wire,
+ &ctx->tps->coin_pub,
+ ctx->merchant_pub,
+ &handle_wtid_data,
+ ctx);
+ if (0 > qs)
+ {
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ {
+ GNUNET_break (0);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED,
+ "failed to fetch transaction data");
+ }
+ return qs;
+ }
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_TRACK_TRANSACTION_NOT_FOUND,
+ "transaction unknown");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ return qs;
+}
+
+
+/**
+ * Check the merchant signature, and if it is valid,
+ * return the wire transfer identifier.
+ *
+ * @param connection the MHD connection to handle
+ * @param tps signed request to execute
+ * @param merchant_pub public key from the merchant
+ * @param merchant_sig signature from the merchant (to be checked)
+ * @return MHD result code
+ */
+static int
+check_and_handle_track_transaction_request (struct MHD_Connection *connection,
+ const struct
+ TALER_DepositTrackPS *tps,
+ const struct
+ TALER_MerchantPublicKeyP *
+ merchant_pub,
+ const struct
+ TALER_MerchantSignatureP *
+ merchant_sig)
+{
+ struct DepositWtidContext ctx;
+ int mhd_ret;
+
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION,
+ &tps->purpose,
+ &merchant_sig->eddsa_sig,
+ &merchant_pub->eddsa_pub))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID,
+ "merchant_sig");
+ }
+ ctx.pending = GNUNET_NO;
+ ctx.tps = tps;
+ ctx.merchant_pub = merchant_pub;
+
+ if (GNUNET_OK !=
+ TEH_DB_run_transaction (connection,
+ "handle track transaction",
+ &mhd_ret,
+ &track_transaction_transaction,
+ &ctx))
+ return mhd_ret;
+ if (GNUNET_YES == ctx.pending)
+ return reply_transfer_pending (connection,
+ ctx.execution_time);
+ if (GNUNET_SYSERR == ctx.pending)
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT,
+ "fees are inconsistent");
+ return reply_track_transaction (connection,
+ &tps->h_contract_terms,
+ &tps->h_wire,
+ &tps->coin_pub,
+ &ctx.coin_delta,
+ &ctx.wtid,
+ ctx.execution_time);
+}
+
+
+/**
+ * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB"
+ * request.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param args array of additional options (length: 4, contains:
+ * h_wire, merchant_pub, h_contract_terms and coin_pub)
+ * @return MHD result code
+ */
+int
+TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const char *const args[4])
+{
+ int res;
+ struct TALER_DepositTrackPS tps;
+ struct TALER_MerchantSignatureP merchant_sig;
+
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[0],
+ strlen (args[0]),
+ &tps.h_wire,
+ sizeof (tps.h_wire)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSITS_INVALID_H_WIRE,
+ "wire hash malformed");
+ }
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[1],
+ strlen (args[1]),
+ &tps.merchant,
+ sizeof (tps.merchant)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSITS_INVALID_MERCHANT_PUB,
+ "merchant public key malformed");
+ }
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[2],
+ strlen (args[2]),
+ &tps.h_contract_terms,
+ sizeof (tps.h_contract_terms)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSITS_INVALID_H_CONTRACT_TERMS,
+ "contract terms hash malformed");
+ }
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[3],
+ strlen (args[3]),
+ &tps.coin_pub,
+ sizeof (tps.coin_pub)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSITS_INVALID_COIN_PUB,
+ "coin public key malformed");
+ }
+ res = TALER_MHD_parse_request_arg_data (connection,
+ "merchant_sig",
+ &merchant_sig,
+ sizeof (merchant_sig));
+ if (GNUNET_SYSERR == res)
+ return MHD_NO; /* internal error */
+ if (GNUNET_NO == res)
+ return MHD_YES; /* parse error */
+ tps.purpose.size = htonl (sizeof (struct TALER_DepositTrackPS));
+ tps.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION);
+ return check_and_handle_track_transaction_request (connection,
+ &tps,
+ &tps.merchant,
+ &merchant_sig);
+}
+
+
+/* end of taler-exchange-httpd_deposits_get.c */
diff --git a/src/exchange/taler-exchange-httpd_deposits_get.h b/src/exchange/taler-exchange-httpd_deposits_get.h
@@ -0,0 +1,45 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2017 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_deposits_get.h
+ * @brief Handle wire transfer tracking-related requests
+ * @author Christian Grothoff
+ */
+#ifndef TALER_EXCHANGE_HTTPD_TRACK_TRANSACTION_H
+#define TALER_EXCHANGE_HTTPD_TRACK_TRANSACTION_H
+
+#include <gnunet/gnunet_util_lib.h>
+#include <microhttpd.h>
+#include "taler-exchange-httpd.h"
+
+
+/**
+ * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB"
+ * request.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param args array of additional options (length: 4, contains:
+ * h_wire, merchant_pub, h_contract_terms and coin_pub)
+ * @return MHD result code
+ */
+int
+TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const char *const args[4]);
+
+
+#endif
diff --git a/src/exchange/taler-exchange-httpd_reserve_status.c b/src/exchange/taler-exchange-httpd_reserve_status.c
@@ -1,175 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2020 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
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_reserve_status.c
- * @brief Handle /reserves/$RESERVE_PUB GET requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include "taler_mhd_lib.h"
-#include "taler_json_lib.h"
-#include "taler-exchange-httpd_reserve_status.h"
-#include "taler-exchange-httpd_responses.h"
-#include "taler-exchange-httpd_keystate.h"
-
-
-/**
- * Send reserve status information to client.
- *
- * @param connection connection to the client
- * @param rh reserve history to return
- * @return MHD result code
- */
-static int
-reply_reserve_status_success (struct MHD_Connection *connection,
- 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)
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_RESERVE_STATUS_DB_ERROR,
- "balance calculation failure");
- json_balance = TALER_JSON_from_amount (&balance);
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o}",
- "balance", json_balance,
- "history", json_history);
-}
-
-
-/**
- * Closure for #reserve_status_transaction.
- */
-struct ReserveStatusContext
-{
- /**
- * Public key of the reserve the inquiry is about.
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * History of the reserve, set in the callback.
- */
- struct TALER_EXCHANGEDB_ReserveHistory *rh;
-
-};
-
-
-/**
- * Function implementing /reserve/status transaction.
- * Execute a /reserve/status. Given the public key of a reserve,
- * return the associated transaction history. Runs the
- * transaction logic; IF it returns a non-error code, the transaction
- * logic MUST NOT queue a MHD response. IF it returns an hard error,
- * the transaction logic MUST queue a MHD response and set @a mhd_ret.
- * IF it returns the soft error code, the function MAY be called again
- * to retry and MUST not queue a MHD response.
- *
- * @param cls a `struct ReserveStatusContext *`
- * @param connection MHD request which triggered the transaction
- * @param session database session to use
- * @param[out] mhd_ret set to MHD response status for @a connection,
- * if transaction failed (!); unused
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-reserve_status_transaction (void *cls,
- struct MHD_Connection *connection,
- struct TALER_EXCHANGEDB_Session *session,
- int *mhd_ret)
-{
- struct ReserveStatusContext *rsc = cls;
-
- (void) connection;
- (void) mhd_ret;
- return TEH_plugin->get_reserve_history (TEH_plugin->cls,
- session,
- &rsc->reserve_pub,
- &rsc->rh);
-}
-
-
-/**
- * Handle a GET "/reserves/" request. Parses the
- * given "reserve_pub" in @a args (which should contain the
- * EdDSA public key of a reserve) and then respond with the
- * status of the reserve.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param args array of additional options (length: 1, just the reserve_pub)
- * @return MHD result code
- */
-int
-TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- const char *const args[1])
-{
- struct ReserveStatusContext rsc;
- int mhd_ret;
-
- (void) rh;
- 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 (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_RESERVES_INVALID_RESERVE_PUB,
- "reserve public key malformed");
- }
- rsc.rh = NULL;
- if (GNUNET_OK !=
- TEH_DB_run_transaction (connection,
- "get reserve status",
- &mhd_ret,
- &reserve_status_transaction,
- &rsc))
- return mhd_ret;
-
- /* generate proper response */
- if (NULL == rsc.rh)
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:s, s:I}",
- "hint", "Reserve not found",
- "parameter", "reserve_pub",
- "code",
- (json_int_t)
- TALER_EC_RESERVE_STATUS_UNKNOWN);
- mhd_ret = reply_reserve_status_success (connection,
- rsc.rh);
- TEH_plugin->free_reserve_history (TEH_plugin->cls,
- rsc.rh);
- return mhd_ret;
-}
-
-
-/* end of taler-exchange-httpd_reserve_status.c */
diff --git a/src/exchange/taler-exchange-httpd_reserve_status.h b/src/exchange/taler-exchange-httpd_reserve_status.h
@@ -1,46 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2020 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
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_reserve_status.h
- * @brief Handle /reserves/$RESERVE_PUB GET requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H
-#define TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H
-
-#include <microhttpd.h>
-#include "taler-exchange-httpd.h"
-
-
-/**
- * Handle a GET "/reserves/" request. Parses the
- * given "reserve_pub" in @a args (which should contain the
- * EdDSA public key of a reserve) and then respond with the
- * status of the reserve.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param args array of additional options (length: 1, just the reserve_pub)
- * @return MHD result code
- */
-int
-TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- const char *const args[1]);
-
-#endif
diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
@@ -1,509 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2019 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 Foundation; either version 3,
- or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty
- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General
- Public License along with TALER; see the file COPYING. If not,
- see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_reserve_withdraw.c
- * @brief Handle /reserve/withdraw requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include "taler_json_lib.h"
-#include "taler_mhd_lib.h"
-#include "taler-exchange-httpd_reserve_withdraw.h"
-#include "taler-exchange-httpd_responses.h"
-#include "taler-exchange-httpd_keystate.h"
-
-
-/**
- * Perform RSA signature before checking with the database?
- * Reduces time spent in transaction, but may cause us to
- * waste CPU time if DB check fails.
- */
-#define OPTIMISTIC_SIGN 1
-
-
-/**
- * Send reserve status information to client with the
- * message that we have insufficient funds for the
- * requested /reserve/withdraw operation.
- *
- * @param connection connection to the client
- * @param rh reserve history to return
- * @return MHD result code
- */
-static int
-reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *connection,
- 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)))
- 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);
-
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_CONFLICT,
- "{s:s, s:I, s:o, s:o}",
- "hint", "insufficient funds",
- "code",
- (json_int_t)
- TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
- "balance", json_balance,
- "history", json_history);
-}
-
-
-/**
- * Send blinded coin information to client.
- *
- * @param connection connection to the client
- * @param collectable blinded coin to return
- * @return MHD result code
- */
-static int
-reply_reserve_withdraw_success (struct MHD_Connection *connection,
- const struct
- TALER_EXCHANGEDB_CollectableBlindcoin *
- collectable)
-{
- json_t *sig_json;
-
- sig_json = GNUNET_JSON_from_rsa_signature (collectable->sig.rsa_signature);
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "ev_sig", sig_json);
-}
-
-
-/**
- * Context for #withdraw_transaction.
- */
-struct WithdrawContext
-{
- /**
- * Details about the withdrawal request.
- */
- struct TALER_WithdrawRequestPS wsrd;
-
- /**
- * Value of the coin plus withdraw fee.
- */
- struct TALER_Amount amount_required;
-
- /**
- * Hash of the denomination public key.
- */
- struct GNUNET_HashCode denom_pub_hash;
-
- /**
- * Signature over the request.
- */
- struct TALER_ReserveSignatureP signature;
-
- /**
- * Blinded planchet.
- */
- char *blinded_msg;
-
- /**
- * Key state to use to inspect previous withdrawal values.
- */
- struct TEH_KS_StateHandle *key_state;
-
- /**
- * Number of bytes in @e blinded_msg.
- */
- size_t blinded_msg_len;
-
- /**
- * Details about denomination we are about to withdraw.
- */
- struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
-
- /**
- * Set to the resulting signed coin data to be returned to the client.
- */
- struct TALER_EXCHANGEDB_CollectableBlindcoin collectable;
-
-};
-
-
-/**
- * Function implementing /reserve/withdraw transaction. Runs the
- * transaction logic; IF it returns a non-error code, the transaction
- * logic MUST NOT queue a MHD response. IF it returns an hard error,
- * the transaction logic MUST queue a MHD response and set @a mhd_ret.
- * IF it returns the soft error code, the function MAY be called again
- * to retry and MUST not queue a MHD response.
- *
- * Note that "wc->collectable.sig" may already be set before entering
- * this function, either because OPTIMISTIC_SIGN was used and we signed
- * before entering the transaction, or because this function is run
- * twice (!) by #TEH_DB_run_transaction() and the first time created
- * the signature and then failed to commit. Furthermore, we may get
- * a 2nd correct signature briefly if "get_withdraw_info" suceeds and
- * finds one in the DB. To avoid signing twice, the function may
- * return a valid signature in "wc->collectable.sig" even if it failed.
- * The caller must thus free the signature in either case.
- *
- * @param cls a `struct WithdrawContext *`
- * @param connection MHD request which triggered the transaction
- * @param session database session to use
- * @param[out] mhd_ret set to MHD response status for @a connection,
- * if transaction failed (!)
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-withdraw_transaction (void *cls,
- struct MHD_Connection *connection,
- struct TALER_EXCHANGEDB_Session *session,
- int *mhd_ret)
-{
- struct WithdrawContext *wc = cls;
- struct TALER_EXCHANGEDB_Reserve r;
- enum GNUNET_DB_QueryStatus qs;
- struct TALER_Amount fee_withdraw;
- struct TALER_DenominationSignature denom_sig;
-
-#if OPTIMISTIC_SIGN
- /* store away optimistic signature to protect
- it from being overwritten by get_withdraw_info */
- denom_sig = wc->collectable.sig;
- wc->collectable.sig.rsa_signature = NULL;
-#endif
- qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
- session,
- &wc->wsrd.h_coin_envelope,
- &wc->collectable);
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_WITHDRAW_DB_FETCH_ERROR,
- "failed to fetch withdraw data");
- wc->collectable.sig = denom_sig;
- return qs;
- }
-
- /* Don't sign again if we have already signed the coin */
- if (1 == qs)
- {
-#if OPTIMISTIC_SIGN
- GNUNET_CRYPTO_rsa_signature_free (denom_sig.rsa_signature);
-#endif
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- }
- GNUNET_assert (0 == qs);
- wc->collectable.sig = denom_sig;
-
- /* Check if balance is sufficient */
- r.pub = wc->wsrd.reserve_pub;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Trying to withdraw from reserve: %s\n",
- TALER_B2S (&r.pub));
- qs = TEH_plugin->reserve_get (TEH_plugin->cls,
- session,
- &r);
- if (0 > qs)
- {
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_WITHDRAW_DB_FETCH_ERROR,
- "failed to fetch reserve data");
- return qs;
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- {
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_WITHDRAW_RESERVE_UNKNOWN,
- "reserve_pub");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if (0 < TALER_amount_cmp (&wc->amount_required,
- &r.balance))
- {
- char *amount_required;
- char *r_balance;
- struct TALER_EXCHANGEDB_ReserveHistory *rh;
- /* The reserve does not have the required amount (actual
- * amount + withdraw fee) */
- GNUNET_break_op (0);
- amount_required = TALER_amount_to_string (&wc->amount_required);
- r_balance = TALER_amount_to_string (&r.balance);
- TALER_LOG_WARNING ("Asked %s over a reserve worth %s\n",
- amount_required,
- r_balance);
- GNUNET_free (amount_required);
- GNUNET_free (r_balance);
- qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
- session,
- &wc->wsrd.reserve_pub,
- &rh);
- if (NULL == rh)
- {
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_WITHDRAW_DB_FETCH_ERROR,
- "failed to fetch reserve history");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- *mhd_ret = reply_reserve_withdraw_insufficient_funds (connection,
- rh);
- TEH_plugin->free_reserve_history (TEH_plugin->cls,
- rh);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
-
- /* Balance is good, sign the coin! */
-#if ! OPTIMISTIC_SIGN
- if (NULL == wc->collectable.sig.rsa_signature)
- {
- wc->collectable.sig.rsa_signature
- = GNUNET_CRYPTO_rsa_sign_blinded (wc->dki->denom_priv.rsa_private_key,
- wc->blinded_msg,
- wc->blinded_msg_len);
- if (NULL == wc->collectable.sig.rsa_signature)
- {
- GNUNET_break (0);
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_WITHDRAW_SIGNATURE_FAILED,
- "Failed to create signature");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
-#endif
- TALER_amount_ntoh (&fee_withdraw,
- &wc->dki->issue.properties.fee_withdraw);
- wc->collectable.denom_pub_hash = wc->denom_pub_hash;
- wc->collectable.amount_with_fee = wc->amount_required;
- wc->collectable.withdraw_fee = fee_withdraw;
- wc->collectable.reserve_pub = wc->wsrd.reserve_pub;
- wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope;
- wc->collectable.reserve_sig = wc->signature;
- qs = TEH_plugin->insert_withdraw_info (TEH_plugin->cls,
- session,
- &wc->collectable);
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_WITHDRAW_DB_STORE_ERROR,
- "failed to persist withdraw data");
- return qs;
- }
- return qs;
-}
-
-
-/**
- * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the
- * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which
- * specifies the key/value of the coin to be withdrawn, and checks that the
- * signature "reserve_sig" makes this a valid withdrawal request from the
- * specified reserve. If so, the envelope with the blinded coin "coin_ev" is
- * passed down to execute the withdrawl operation.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param root uploaded JSON data
- * @param args array of additional options (first must be the
- * reserve public key, the second one should be "withdraw")
- * @return MHD result code
- */
-int
-TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- const json_t *root,
- const char *const args[2])
-{
- struct WithdrawContext wc;
- int res;
- int mhd_ret;
- unsigned int hc;
- enum TALER_ErrorCode ec;
- struct TALER_Amount amount;
- struct TALER_Amount fee_withdraw;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_varsize ("coin_ev",
- (void **) &wc.blinded_msg,
- &wc.blinded_msg_len),
- GNUNET_JSON_spec_fixed_auto ("reserve_sig",
- &wc.signature),
- GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
- &wc.denom_pub_hash),
- GNUNET_JSON_spec_end ()
- };
-
- (void) rh;
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (args[0],
- strlen (args[0]),
- &wc.wsrd.reserve_pub,
- sizeof (wc.wsrd.reserve_pub)))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_RESERVES_INVALID_RESERVE_PUB,
- "reserve public key malformed");
- }
-
- res = TALER_MHD_parse_json_data (connection,
- root,
- spec);
- if (GNUNET_OK != res)
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- wc.key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
- if (NULL == wc.key_state)
- {
- TALER_LOG_ERROR ("Lacking keys to operate\n");
- GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
- }
- wc.dki = TEH_KS_denomination_key_lookup_by_hash (wc.key_state,
- &wc.denom_pub_hash,
- TEH_KS_DKU_WITHDRAW,
- &ec,
- &hc);
- if (NULL == wc.dki)
- {
- GNUNET_JSON_parse_free (spec);
- TEH_KS_release (wc.key_state);
- return TALER_MHD_reply_with_error (connection,
- hc,
- ec,
- "could not find denomination key");
- }
- GNUNET_assert (NULL != wc.dki->denom_priv.rsa_private_key);
- TALER_amount_ntoh (&amount,
- &wc.dki->issue.properties.value);
- TALER_amount_ntoh (&fee_withdraw,
- &wc.dki->issue.properties.fee_withdraw);
- if (GNUNET_OK !=
- TALER_amount_add (&wc.amount_required,
- &amount,
- &fee_withdraw))
- {
- GNUNET_JSON_parse_free (spec);
- TEH_KS_release (wc.key_state);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW,
- "amount overflow for value plus withdraw fee");
- }
- TALER_amount_hton (&wc.wsrd.amount_with_fee,
- &wc.amount_required);
- TALER_amount_hton (&wc.wsrd.withdraw_fee,
- &fee_withdraw);
- /* verify signature! */
- wc.wsrd.purpose.size
- = htonl (sizeof (struct TALER_WithdrawRequestPS));
- wc.wsrd.purpose.purpose
- = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
- wc.wsrd.h_denomination_pub
- = wc.denom_pub_hash;
- GNUNET_CRYPTO_hash (wc.blinded_msg,
- wc.blinded_msg_len,
- &wc.wsrd.h_coin_envelope);
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
- &wc.wsrd.purpose,
- &wc.signature.eddsa_signature,
- &wc.wsrd.reserve_pub.eddsa_pub))
- {
- TALER_LOG_WARNING (
- "Client supplied invalid signature for /reserve/withdraw request\n");
- GNUNET_JSON_parse_free (spec);
- TEH_KS_release (wc.key_state);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_FORBIDDEN,
- TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID,
- "reserve_sig");
- }
-
-#if OPTIMISTIC_SIGN
- /* Sign before transaction! */
- wc.collectable.sig.rsa_signature
- = GNUNET_CRYPTO_rsa_sign_blinded (wc.dki->denom_priv.rsa_private_key,
- wc.blinded_msg,
- wc.blinded_msg_len);
- if (NULL == wc.collectable.sig.rsa_signature)
- {
- GNUNET_break (0);
- GNUNET_JSON_parse_free (spec);
- TEH_KS_release (wc.key_state);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_WITHDRAW_SIGNATURE_FAILED,
- "Failed to sign");
- }
-#endif
-
- if (GNUNET_OK !=
- TEH_DB_run_transaction (connection,
- "run reserve withdraw",
- &mhd_ret,
- &withdraw_transaction,
- &wc))
- {
- TEH_KS_release (wc.key_state);
- /* Even if #withdraw_transaction() failed, it may have created a signature
- (or we might have done it optimistically above). */
- if (NULL != wc.collectable.sig.rsa_signature)
- GNUNET_CRYPTO_rsa_signature_free (wc.collectable.sig.rsa_signature);
- GNUNET_JSON_parse_free (spec);
- return mhd_ret;
- }
- TEH_KS_release (wc.key_state);
- GNUNET_JSON_parse_free (spec);
-
- mhd_ret = reply_reserve_withdraw_success (connection,
- &wc.collectable);
- GNUNET_CRYPTO_rsa_signature_free (wc.collectable.sig.rsa_signature);
- return mhd_ret;
-}
-
-
-/* end of taler-exchange-httpd_reserve_withdraw.c */
diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.h b/src/exchange/taler-exchange-httpd_reserve_withdraw.h
@@ -1,51 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2020 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
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_reserve_withdraw.h
- * @brief Handle /reserve/withdraw requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_EXCHANGE_HTTPD_RESERVE_WITHDRAW_H
-#define TALER_EXCHANGE_HTTPD_RESERVE_WITHDRAW_H
-
-#include <microhttpd.h>
-#include "taler-exchange-httpd.h"
-
-
-/**
- * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the
- * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which
- * specifies the key/value of the coin to be withdrawn, and checks that the
- * signature "reserve_sig" makes this a valid withdrawl request from the
- * specified reserve. If so, the envelope with the blinded coin "coin_ev" is
- * passed down to execute the withdrawl operation.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param root uploaded JSON data
- * @param args array of additional options (first must be the
- * reserve public key, the second one should be "withdraw")
- * @return MHD result code
- */
-int
-TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- const json_t *root,
- const char *const args[2]);
-
-#endif
diff --git a/src/exchange/taler-exchange-httpd_reserves_get.c b/src/exchange/taler-exchange-httpd_reserves_get.c
@@ -0,0 +1,175 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2020 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_reserves_get.c
+ * @brief Handle /reserves/$RESERVE_PUB GET requests
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <jansson.h>
+#include "taler_mhd_lib.h"
+#include "taler_json_lib.h"
+#include "taler-exchange-httpd_reserves_get.h"
+#include "taler-exchange-httpd_responses.h"
+#include "taler-exchange-httpd_keystate.h"
+
+
+/**
+ * Send reserve status information to client.
+ *
+ * @param connection connection to the client
+ * @param rh reserve history to return
+ * @return MHD result code
+ */
+static int
+reply_reserve_status_success (struct MHD_Connection *connection,
+ 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)
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_RESERVE_STATUS_DB_ERROR,
+ "balance calculation failure");
+ json_balance = TALER_JSON_from_amount (&balance);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o}",
+ "balance", json_balance,
+ "history", json_history);
+}
+
+
+/**
+ * Closure for #reserve_status_transaction.
+ */
+struct ReserveStatusContext
+{
+ /**
+ * Public key of the reserve the inquiry is about.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * History of the reserve, set in the callback.
+ */
+ struct TALER_EXCHANGEDB_ReserveHistory *rh;
+
+};
+
+
+/**
+ * Function implementing /reserve/status transaction.
+ * Execute a /reserve/status. Given the public key of a reserve,
+ * return the associated transaction history. Runs the
+ * transaction logic; IF it returns a non-error code, the transaction
+ * logic MUST NOT queue a MHD response. IF it returns an hard error,
+ * the transaction logic MUST queue a MHD response and set @a mhd_ret.
+ * IF it returns the soft error code, the function MAY be called again
+ * to retry and MUST not queue a MHD response.
+ *
+ * @param cls a `struct ReserveStatusContext *`
+ * @param connection MHD request which triggered the transaction
+ * @param session database session to use
+ * @param[out] mhd_ret set to MHD response status for @a connection,
+ * if transaction failed (!); unused
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+reserve_status_transaction (void *cls,
+ struct MHD_Connection *connection,
+ struct TALER_EXCHANGEDB_Session *session,
+ int *mhd_ret)
+{
+ struct ReserveStatusContext *rsc = cls;
+
+ (void) connection;
+ (void) mhd_ret;
+ return TEH_plugin->get_reserve_history (TEH_plugin->cls,
+ session,
+ &rsc->reserve_pub,
+ &rsc->rh);
+}
+
+
+/**
+ * Handle a GET "/reserves/" request. Parses the
+ * given "reserve_pub" in @a args (which should contain the
+ * EdDSA public key of a reserve) and then respond with the
+ * status of the reserve.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param args array of additional options (length: 1, just the reserve_pub)
+ * @return MHD result code
+ */
+int
+TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const char *const args[1])
+{
+ struct ReserveStatusContext rsc;
+ int mhd_ret;
+
+ (void) rh;
+ 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 (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_RESERVES_INVALID_RESERVE_PUB,
+ "reserve public key malformed");
+ }
+ rsc.rh = NULL;
+ if (GNUNET_OK !=
+ TEH_DB_run_transaction (connection,
+ "get reserve status",
+ &mhd_ret,
+ &reserve_status_transaction,
+ &rsc))
+ return mhd_ret;
+
+ /* generate proper response */
+ if (NULL == rsc.rh)
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_NOT_FOUND,
+ "{s:s, s:s, s:I}",
+ "hint", "Reserve not found",
+ "parameter", "reserve_pub",
+ "code",
+ (json_int_t)
+ TALER_EC_RESERVE_STATUS_UNKNOWN);
+ mhd_ret = reply_reserve_status_success (connection,
+ rsc.rh);
+ TEH_plugin->free_reserve_history (TEH_plugin->cls,
+ rsc.rh);
+ return mhd_ret;
+}
+
+
+/* end of taler-exchange-httpd_reserves_get.c */
diff --git a/src/exchange/taler-exchange-httpd_reserves_get.h b/src/exchange/taler-exchange-httpd_reserves_get.h
@@ -0,0 +1,46 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2020 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_reserves_get.h
+ * @brief Handle /reserves/$RESERVE_PUB GET requests
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#ifndef TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H
+#define TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H
+
+#include <microhttpd.h>
+#include "taler-exchange-httpd.h"
+
+
+/**
+ * Handle a GET "/reserves/" request. Parses the
+ * given "reserve_pub" in @a args (which should contain the
+ * EdDSA public key of a reserve) and then respond with the
+ * status of the reserve.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param args array of additional options (length: 1, just the reserve_pub)
+ * @return MHD result code
+ */
+int
+TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const char *const args[1]);
+
+#endif
diff --git a/src/exchange/taler-exchange-httpd_track_transaction.c b/src/exchange/taler-exchange-httpd_track_transaction.c
@@ -1,422 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2017 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
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_track_transaction.c
- * @brief Handle wire transfer tracking-related requests
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include <microhttpd.h>
-#include <pthread.h>
-#include "taler_json_lib.h"
-#include "taler_mhd_lib.h"
-#include "taler_signatures.h"
-#include "taler-exchange-httpd_keystate.h"
-#include "taler-exchange-httpd_track_transaction.h"
-#include "taler-exchange-httpd_responses.h"
-
-
-/**
- * A merchant asked for details about a deposit, but
- * we did not execute the deposit yet. Generate a 202 reply.
- *
- * @param connection connection to the client
- * @param planned_exec_time planned execution time
- * @return MHD result code
- */
-static int
-reply_transfer_pending (struct MHD_Connection *connection,
- struct GNUNET_TIME_Absolute planned_exec_time)
-{
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_ACCEPTED,
- "{s:o}",
- "execution_time",
- GNUNET_JSON_from_time_abs (
- planned_exec_time));
-}
-
-
-/**
- * A merchant asked for details about a deposit. Provide
- * them. Generates the 200 reply.
- *
- * @param connection connection to the client
- * @param h_contract_terms hash of the contract
- * @param h_wire hash of wire account details
- * @param coin_pub public key of the coin
- * @param coin_contribution how much did the coin we asked about
- * contribute to the total transfer value? (deposit value minus fee)
- * @param wtid raw wire transfer identifier
- * @param exec_time execution time of the wire transfer
- * @return MHD result code
- */
-static int
-reply_track_transaction (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct GNUNET_HashCode *h_wire,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_Amount *coin_contribution,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- struct GNUNET_TIME_Absolute exec_time)
-{
- struct TALER_ConfirmWirePS cw;
- struct TALER_ExchangePublicKeyP pub;
- struct TALER_ExchangeSignatureP sig;
-
- cw.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE);
- cw.purpose.size = htonl (sizeof (struct TALER_ConfirmWirePS));
- cw.h_wire = *h_wire;
- cw.h_contract_terms = *h_contract_terms;
- cw.wtid = *wtid;
- cw.coin_pub = *coin_pub;
- cw.execution_time = GNUNET_TIME_absolute_hton (exec_time);
- TALER_amount_hton (&cw.coin_contribution,
- coin_contribution);
- if (GNUNET_OK !=
- TEH_KS_sign (&cw.purpose,
- &pub,
- &sig))
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
- }
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o, s:o, s:o, s:o}",
- "wtid", GNUNET_JSON_from_data_auto (
- wtid),
- "execution_time",
- GNUNET_JSON_from_time_abs (exec_time),
- "coin_contribution",
- TALER_JSON_from_amount (
- coin_contribution),
- "exchange_sig",
- GNUNET_JSON_from_data_auto (&sig),
- "exchange_pub",
- GNUNET_JSON_from_data_auto (&pub));
-}
-
-
-/**
- * Closure for #handle_wtid_data.
- */
-struct DepositWtidContext
-{
-
- /**
- * Deposit details.
- */
- const struct TALER_DepositTrackPS *tps;
-
- /**
- * Public key of the merchant.
- */
- const struct TALER_MerchantPublicKeyP *merchant_pub;
-
- /**
- * Set by #handle_wtid data to the wire transfer ID.
- */
- struct TALER_WireTransferIdentifierRawP wtid;
-
- /**
- * Set by #handle_wtid data to the coin's contribution to the wire transfer.
- */
- struct TALER_Amount coin_contribution;
-
- /**
- * Set by #handle_wtid data to the fee charged to the coin.
- */
- struct TALER_Amount coin_fee;
-
- /**
- * Set by #handle_wtid data to the wire transfer execution time.
- */
- struct GNUNET_TIME_Absolute execution_time;
-
- /**
- * Set by #handle_wtid to the coin contribution to the transaction
- * (that is, @e coin_contribution minus @e coin_fee).
- */
- struct TALER_Amount coin_delta;
-
- /**
- * Set to #GNUNET_YES by #handle_wtid if the wire transfer is still pending
- * (and the above were not set).
- * Set to #GNUNET_SYSERR if there was a serious error.
- */
- int pending;
-};
-
-
-/**
- * Function called with the results of the lookup of the
- * wire transfer identifier information.
- *
- * @param cls our context for transmission
- * @param wtid raw wire transfer identifier, NULL
- * if the transaction was not yet done
- * @param coin_contribution how much did the coin we asked about
- * contribute to the total transfer value? (deposit value including fee)
- * @param coin_fee how much did the exchange charge for the deposit fee
- * @param execution_time when was the transaction done, or
- * when we expect it to be done (if @a wtid was NULL);
- * #GNUNET_TIME_UNIT_FOREVER_ABS if the /deposit is unknown
- * to the exchange
- */
-static void
-handle_wtid_data (void *cls,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct TALER_Amount *coin_contribution,
- const struct TALER_Amount *coin_fee,
- struct GNUNET_TIME_Absolute execution_time)
-{
- struct DepositWtidContext *ctx = cls;
-
- if (NULL == wtid)
- {
- ctx->pending = GNUNET_YES;
- ctx->execution_time = execution_time;
- return;
- }
- if (GNUNET_SYSERR ==
- TALER_amount_subtract (&ctx->coin_delta,
- coin_contribution,
- coin_fee))
- {
- GNUNET_break (0);
- ctx->pending = GNUNET_SYSERR;
- return;
- }
- ctx->wtid = *wtid;
- ctx->execution_time = execution_time;
- ctx->coin_contribution = *coin_contribution;
- ctx->coin_fee = *coin_fee;
-}
-
-
-/**
- * Execute a "/track/transaction". Returns the transfer information
- * associated with the given deposit.
- *
- * If it returns a non-error code, the transaction logic MUST
- * NOT queue a MHD response. IF it returns an hard error, the
- * transaction logic MUST queue a MHD response and set @a mhd_ret. IF
- * it returns the soft error code, the function MAY be called again to
- * retry and MUST not queue a MHD response.
- *
- * @param cls closure of type `struct DepositWtidContext *`
- * @param connection MHD request which triggered the transaction
- * @param session database session to use
- * @param[out] mhd_ret set to MHD response status for @a connection,
- * if transaction failed (!)
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-track_transaction_transaction (void *cls,
- struct MHD_Connection *connection,
- struct TALER_EXCHANGEDB_Session *session,
- int *mhd_ret)
-{
- struct DepositWtidContext *ctx = cls;
- enum GNUNET_DB_QueryStatus qs;
-
- qs = TEH_plugin->wire_lookup_deposit_wtid (TEH_plugin->cls,
- session,
- &ctx->tps->h_contract_terms,
- &ctx->tps->h_wire,
- &ctx->tps->coin_pub,
- ctx->merchant_pub,
- &handle_wtid_data,
- ctx);
- if (0 > qs)
- {
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- {
- GNUNET_break (0);
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED,
- "failed to fetch transaction data");
- }
- return qs;
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- {
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_TRACK_TRANSACTION_NOT_FOUND,
- "transaction unknown");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- return qs;
-}
-
-
-/**
- * Check the merchant signature, and if it is valid,
- * return the wire transfer identifier.
- *
- * @param connection the MHD connection to handle
- * @param tps signed request to execute
- * @param merchant_pub public key from the merchant
- * @param merchant_sig signature from the merchant (to be checked)
- * @return MHD result code
- */
-static int
-check_and_handle_track_transaction_request (struct MHD_Connection *connection,
- const struct
- TALER_DepositTrackPS *tps,
- const struct
- TALER_MerchantPublicKeyP *
- merchant_pub,
- const struct
- TALER_MerchantSignatureP *
- merchant_sig)
-{
- struct DepositWtidContext ctx;
- int mhd_ret;
-
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION,
- &tps->purpose,
- &merchant_sig->eddsa_sig,
- &merchant_pub->eddsa_pub))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_FORBIDDEN,
- TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID,
- "merchant_sig");
- }
- ctx.pending = GNUNET_NO;
- ctx.tps = tps;
- ctx.merchant_pub = merchant_pub;
-
- if (GNUNET_OK !=
- TEH_DB_run_transaction (connection,
- "handle track transaction",
- &mhd_ret,
- &track_transaction_transaction,
- &ctx))
- return mhd_ret;
- if (GNUNET_YES == ctx.pending)
- return reply_transfer_pending (connection,
- ctx.execution_time);
- if (GNUNET_SYSERR == ctx.pending)
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT,
- "fees are inconsistent");
- return reply_track_transaction (connection,
- &tps->h_contract_terms,
- &tps->h_wire,
- &tps->coin_pub,
- &ctx.coin_delta,
- &ctx.wtid,
- ctx.execution_time);
-}
-
-
-/**
- * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB"
- * request.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param args array of additional options (length: 4, contains:
- * h_wire, merchant_pub, h_contract_terms and coin_pub)
- * @return MHD result code
- */
-int
-TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- const char *const args[4])
-{
- int res;
- struct TALER_DepositTrackPS tps;
- struct TALER_MerchantSignatureP merchant_sig;
-
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (args[0],
- strlen (args[0]),
- &tps.h_wire,
- sizeof (tps.h_wire)))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_DEPOSITS_INVALID_H_WIRE,
- "wire hash malformed");
- }
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (args[1],
- strlen (args[1]),
- &tps.merchant,
- sizeof (tps.merchant)))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_DEPOSITS_INVALID_MERCHANT_PUB,
- "merchant public key malformed");
- }
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (args[2],
- strlen (args[2]),
- &tps.h_contract_terms,
- sizeof (tps.h_contract_terms)))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_DEPOSITS_INVALID_H_CONTRACT_TERMS,
- "contract terms hash malformed");
- }
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (args[3],
- strlen (args[3]),
- &tps.coin_pub,
- sizeof (tps.coin_pub)))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_DEPOSITS_INVALID_COIN_PUB,
- "coin public key malformed");
- }
- res = TALER_MHD_parse_request_arg_data (connection,
- "merchant_sig",
- &merchant_sig,
- sizeof (merchant_sig));
- if (GNUNET_SYSERR == res)
- return MHD_NO; /* internal error */
- if (GNUNET_NO == res)
- return MHD_YES; /* parse error */
- tps.purpose.size = htonl (sizeof (struct TALER_DepositTrackPS));
- tps.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION);
- return check_and_handle_track_transaction_request (connection,
- &tps,
- &tps.merchant,
- &merchant_sig);
-}
-
-
-/* end of taler-exchange-httpd_track_transaction.c */
diff --git a/src/exchange/taler-exchange-httpd_track_transaction.h b/src/exchange/taler-exchange-httpd_track_transaction.h
@@ -1,45 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2017 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
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_track_transaction.h
- * @brief Handle wire transfer tracking-related requests
- * @author Christian Grothoff
- */
-#ifndef TALER_EXCHANGE_HTTPD_TRACK_TRANSACTION_H
-#define TALER_EXCHANGE_HTTPD_TRACK_TRANSACTION_H
-
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler-exchange-httpd.h"
-
-
-/**
- * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB"
- * request.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param args array of additional options (length: 4, contains:
- * h_wire, merchant_pub, h_contract_terms and coin_pub)
- * @return MHD result code
- */
-int
-TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- const char *const args[4]);
-
-
-#endif
diff --git a/src/exchange/taler-exchange-httpd_track_transfer.c b/src/exchange/taler-exchange-httpd_track_transfer.c
@@ -1,538 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2018 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
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_track_transfer.c
- * @brief Handle wire transfer /track/transfer requests
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include <microhttpd.h>
-#include <pthread.h>
-#include "taler_signatures.h"
-#include "taler-exchange-httpd_keystate.h"
-#include "taler-exchange-httpd_track_transfer.h"
-#include "taler-exchange-httpd_responses.h"
-#include "taler_json_lib.h"
-#include "taler_mhd_lib.h"
-
-
-/**
- * Detail for /wire/deposit response.
- */
-struct TEH_TrackTransferDetail
-{
-
- /**
- * We keep deposit details in a DLL.
- */
- struct TEH_TrackTransferDetail *next;
-
- /**
- * We keep deposit details in a DLL.
- */
- struct TEH_TrackTransferDetail *prev;
-
- /**
- * Hash of the proposal data.
- */
- struct GNUNET_HashCode h_contract_terms;
-
- /**
- * Coin's public key.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Total value of the coin.
- */
- struct TALER_Amount deposit_value;
-
- /**
- * Fees charged by the exchange for the deposit.
- */
- struct TALER_Amount deposit_fee;
-};
-
-
-/**
- * A merchant asked for transaction details about a wire transfer.
- * Provide them. Generates the 200 reply.
- *
- * @param connection connection to the client
- * @param total total amount that was transferred
- * @param merchant_pub public key of the merchant
- * @param h_wire destination account
- * @param wire_fee wire fee that was charged
- * @param exec_time execution time of the wire transfer
- * @param wdd_head linked list with details about the combined deposits
- * @return MHD result code
- */
-static int
-reply_track_transfer_details (struct MHD_Connection *connection,
- const struct TALER_Amount *total,
- const struct
- TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_wire,
- const struct TALER_Amount *wire_fee,
- struct GNUNET_TIME_Absolute exec_time,
- const struct TEH_TrackTransferDetail *wdd_head)
-{
- const struct TEH_TrackTransferDetail *wdd_pos;
- json_t *deposits;
- struct TALER_WireDepositDetailP dd;
- struct GNUNET_HashContext *hash_context;
- struct TALER_WireDepositDataPS wdp;
- struct TALER_ExchangePublicKeyP pub;
- struct TALER_ExchangeSignatureP sig;
-
- GNUNET_TIME_round_abs (&exec_time);
- deposits = json_array ();
- hash_context = GNUNET_CRYPTO_hash_context_start ();
- for (wdd_pos = wdd_head; NULL != wdd_pos; wdd_pos = wdd_pos->next)
- {
- dd.h_contract_terms = wdd_pos->h_contract_terms;
- dd.execution_time = GNUNET_TIME_absolute_hton (exec_time);
- dd.coin_pub = wdd_pos->coin_pub;
- TALER_amount_hton (&dd.deposit_value,
- &wdd_pos->deposit_value);
- TALER_amount_hton (&dd.deposit_fee,
- &wdd_pos->deposit_fee);
- GNUNET_CRYPTO_hash_context_read (hash_context,
- &dd,
- sizeof (struct TALER_WireDepositDetailP));
- GNUNET_assert (0 ==
- json_array_append_new (deposits,
- json_pack ("{s:o, s:o, s:o, s:o}",
- "h_contract_terms",
- GNUNET_JSON_from_data_auto (
- &wdd_pos->
- h_contract_terms),
- "coin_pub",
- GNUNET_JSON_from_data_auto (
- &wdd_pos->coin_pub),
- "deposit_value",
- TALER_JSON_from_amount (
- &wdd_pos->deposit_value),
- "deposit_fee",
- TALER_JSON_from_amount (
- &wdd_pos->deposit_fee))));
- }
- wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT);
- wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS));
- TALER_amount_hton (&wdp.total,
- total);
- TALER_amount_hton (&wdp.wire_fee,
- wire_fee);
- wdp.merchant_pub = *merchant_pub;
- wdp.h_wire = *h_wire;
- GNUNET_CRYPTO_hash_context_finish (hash_context,
- &wdp.h_details);
- if (GNUNET_OK !=
- TEH_KS_sign (&wdp.purpose,
- &pub,
- &sig))
- {
- json_decref (deposits);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
- }
-
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
- "total", TALER_JSON_from_amount (total),
- "wire_fee", TALER_JSON_from_amount (
- wire_fee),
- "merchant_pub",
- GNUNET_JSON_from_data_auto (
- merchant_pub),
- "h_wire", GNUNET_JSON_from_data_auto (
- h_wire),
- "execution_time",
- GNUNET_JSON_from_time_abs (exec_time),
- "deposits", deposits,
- "exchange_sig",
- GNUNET_JSON_from_data_auto (&sig),
- "exchange_pub",
- GNUNET_JSON_from_data_auto (&pub));
-}
-
-
-/**
- * Closure for #handle_transaction_data.
- */
-struct WtidTransactionContext
-{
-
- /**
- * Identifier of the wire transfer to track.
- */
- struct TALER_WireTransferIdentifierRawP wtid;
-
- /**
- * Total amount of the wire transfer, as calculated by
- * summing up the individual amounts. To be rounded down
- * to calculate the real transfer amount at the end.
- * Only valid if @e is_valid is #GNUNET_YES.
- */
- struct TALER_Amount total;
-
- /**
- * Public key of the merchant, only valid if @e is_valid
- * is #GNUNET_YES.
- */
- struct TALER_MerchantPublicKeyP merchant_pub;
-
- /**
- * Which method was used to wire the funds?
- */
- char *wire_method;
-
- /**
- * Hash of the wire details of the merchant (identical for all
- * deposits), only valid if @e is_valid is #GNUNET_YES.
- */
- struct GNUNET_HashCode h_wire;
-
- /**
- * Wire fee applicable at @e exec_time.
- */
- struct TALER_Amount wire_fee;
-
- /**
- * Execution time of the wire transfer
- */
- struct GNUNET_TIME_Absolute exec_time;
-
- /**
- * Head of DLL with details for /wire/deposit response.
- */
- struct TEH_TrackTransferDetail *wdd_head;
-
- /**
- * Head of DLL with details for /wire/deposit response.
- */
- struct TEH_TrackTransferDetail *wdd_tail;
-
- /**
- * JSON array with details about the individual deposits.
- */
- json_t *deposits;
-
- /**
- * Initially #GNUNET_NO, if we found no deposits so far. Set to
- * #GNUNET_YES if we got transaction data, and the database replies
- * remained consistent with respect to @e merchant_pub and @e h_wire
- * (as they should). Set to #GNUNET_SYSERR if we encountered an
- * internal error.
- */
- int is_valid;
-
-};
-
-
-/**
- * Function called with the results of the lookup of the
- * transaction data for the given wire transfer identifier.
- *
- * @param cls our context for transmission
- * @param rowid which row in the DB is the information from (for diagnostics), ignored
- * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls)
- * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls)
- * @param wire where the funds were sent
- * @param exec_time execution time of the wire transfer (should be same for all callbacks with the same @e cls)
- * @param h_contract_terms which proposal was this payment about
- * @param denom_pub denomination public key of the @a coin_pub (ignored)
- * @param coin_pub which public key was this payment about
- * @param deposit_value amount contributed by this coin in total
- * @param deposit_fee deposit fee charged by exchange for this coin
- */
-static void
-handle_transaction_data (void *cls,
- uint64_t rowid,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_wire,
- const json_t *wire,
- struct GNUNET_TIME_Absolute exec_time,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_DenominationPublicKey *denom_pub,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_Amount *deposit_value,
- const struct TALER_Amount *deposit_fee)
-{
- struct WtidTransactionContext *ctx = cls;
- struct TALER_Amount delta;
- struct TEH_TrackTransferDetail *wdd;
- char *wire_method;
-
- (void) rowid;
- (void) denom_pub;
- if (GNUNET_SYSERR == ctx->is_valid)
- return;
- if (NULL == (wire_method = TALER_JSON_wire_to_method (wire)))
- {
- GNUNET_break (0);
- ctx->is_valid = GNUNET_SYSERR;
- return;
- }
- if (GNUNET_NO == ctx->is_valid)
- {
- ctx->merchant_pub = *merchant_pub;
- ctx->h_wire = *h_wire;
- ctx->exec_time = exec_time;
- ctx->wire_method = wire_method;
- ctx->is_valid = GNUNET_YES;
- if (GNUNET_OK !=
- TALER_amount_subtract (&ctx->total,
- deposit_value,
- deposit_fee))
- {
- GNUNET_break (0);
- ctx->is_valid = GNUNET_SYSERR;
- return;
- }
- }
- else
- {
- if ( (0 != GNUNET_memcmp (&ctx->merchant_pub,
- merchant_pub)) ||
- (0 != strcmp (wire_method,
- ctx->wire_method)) ||
- (0 != GNUNET_memcmp (&ctx->h_wire,
- h_wire)) )
- {
- GNUNET_break (0);
- ctx->is_valid = GNUNET_SYSERR;
- GNUNET_free (wire_method);
- return;
- }
- GNUNET_free (wire_method);
- if (GNUNET_OK !=
- TALER_amount_subtract (&delta,
- deposit_value,
- deposit_fee))
- {
- GNUNET_break (0);
- ctx->is_valid = GNUNET_SYSERR;
- return;
- }
- if (GNUNET_OK !=
- TALER_amount_add (&ctx->total,
- &ctx->total,
- &delta))
- {
- GNUNET_break (0);
- ctx->is_valid = GNUNET_SYSERR;
- return;
- }
- }
- wdd = GNUNET_new (struct TEH_TrackTransferDetail);
- wdd->deposit_value = *deposit_value;
- wdd->deposit_fee = *deposit_fee;
- wdd->h_contract_terms = *h_contract_terms;
- wdd->coin_pub = *coin_pub;
- GNUNET_CONTAINER_DLL_insert (ctx->wdd_head,
- ctx->wdd_tail,
- wdd);
-}
-
-
-/**
- * Execute a "/track/transfer". Returns the transaction information
- * associated with the given wire transfer identifier.
- *
- * If it returns a non-error code, the transaction logic MUST
- * NOT queue a MHD response. IF it returns an hard error, the
- * transaction logic MUST queue a MHD response and set @a mhd_ret. IF
- * it returns the soft error code, the function MAY be called again to
- * retry and MUST not queue a MHD response.
- *
- * @param cls closure
- * @param connection MHD request which triggered the transaction
- * @param session database session to use
- * @param[out] mhd_ret set to MHD response status for @a connection,
- * if transaction failed (!)
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-track_transfer_transaction (void *cls,
- struct MHD_Connection *connection,
- struct TALER_EXCHANGEDB_Session *session,
- int *mhd_ret)
-{
- struct WtidTransactionContext *ctx = cls;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_TIME_Absolute wire_fee_start_date;
- struct GNUNET_TIME_Absolute wire_fee_end_date;
- struct TALER_MasterSignatureP wire_fee_master_sig;
- struct TALER_Amount closing_fee;
-
- ctx->is_valid = GNUNET_NO;
- ctx->wdd_head = NULL;
- ctx->wdd_tail = NULL;
- ctx->wire_method = NULL;
- qs = TEH_plugin->lookup_wire_transfer (TEH_plugin->cls,
- session,
- &ctx->wtid,
- &handle_transaction_data,
- ctx);
- if (0 > qs)
- {
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- {
- GNUNET_break (0);
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED,
- "failed to fetch transaction data");
- }
- return qs;
- }
- if (GNUNET_SYSERR == ctx->is_valid)
- {
- GNUNET_break (0);
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT,
- "exchange database internally inconsistent");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if (GNUNET_NO == ctx->is_valid)
- {
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
- "wtid");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- qs = TEH_plugin->get_wire_fee (TEH_plugin->cls,
- session,
- ctx->wire_method,
- ctx->exec_time,
- &wire_fee_start_date,
- &wire_fee_end_date,
- &ctx->wire_fee,
- &closing_fee,
- &wire_fee_master_sig);
- if (0 >= qs)
- {
- if ( (GNUNET_DB_STATUS_HARD_ERROR == qs) ||
- (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS) )
- {
- GNUNET_break (0);
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_TRACK_TRANSFER_WIRE_FEE_NOT_FOUND,
- "did not find wire fee");
- }
- return qs;
- }
- if (GNUNET_OK !=
- TALER_amount_subtract (&ctx->total,
- &ctx->total,
- &ctx->wire_fee))
- {
- GNUNET_break (0);
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_TRACK_TRANSFER_WIRE_FEE_INCONSISTENT,
- "could not subtract wire fee");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-}
-
-
-/**
- * Free data structure reachable from @a ctx, but not @a ctx itself.
- *
- * @param ctx context to free
- */
-static void
-free_ctx (struct WtidTransactionContext *ctx)
-{
- struct TEH_TrackTransferDetail *wdd;
-
- while (NULL != (wdd = ctx->wdd_head))
- {
- GNUNET_CONTAINER_DLL_remove (ctx->wdd_head,
- ctx->wdd_tail,
- wdd);
- GNUNET_free (wdd);
- }
- GNUNET_free_non_null (ctx->wire_method);
-}
-
-
-/**
- * Handle a GET "/transfers/$WTID" request.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param args array of additional options (length: 1, just the wtid)
- * @return MHD result code
- */
-int
-TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- const char *const args[1])
-{
- struct WtidTransactionContext ctx;
- int mhd_ret;
-
- (void) rh;
- memset (&ctx,
- 0,
- sizeof (ctx));
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (args[0],
- strlen (args[0]),
- &ctx.wtid,
- sizeof (ctx.wtid)))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_TRANSFERS_INVALID_WTID,
- "wire transfer identifier malformed");
- }
- if (GNUNET_OK !=
- TEH_DB_run_transaction (connection,
- "run track transfer",
- &mhd_ret,
- &track_transfer_transaction,
- &ctx))
- {
- free_ctx (&ctx);
- return mhd_ret;
- }
- mhd_ret = reply_track_transfer_details (connection,
- &ctx.total,
- &ctx.merchant_pub,
- &ctx.h_wire,
- &ctx.wire_fee,
- ctx.exec_time,
- ctx.wdd_head);
- free_ctx (&ctx);
- return mhd_ret;
-}
-
-
-/* end of taler-exchange-httpd_track_transfer.c */
diff --git a/src/exchange/taler-exchange-httpd_track_transfer.h b/src/exchange/taler-exchange-httpd_track_transfer.h
@@ -1,43 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2017 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
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_track_transfer.h
- * @brief Handle wire transfer tracking-related requests
- * @author Christian Grothoff
- */
-#ifndef TALER_EXCHANGE_HTTPD_TRACK_TRANSFER_H
-#define TALER_EXCHANGE_HTTPD_TRACK_TRANSFER_H
-
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler-exchange-httpd.h"
-
-
-/**
- * Handle a GET "/transfers/$WTID" request.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param args array of additional options (length: 1, just the wtid)
- * @return MHD result code
- */
-int
-TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- const char *const args[1]);
-
-
-#endif
diff --git a/src/exchange/taler-exchange-httpd_transfers_get.c b/src/exchange/taler-exchange-httpd_transfers_get.c
@@ -0,0 +1,538 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2018 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_transfers_get.c
+ * @brief Handle wire transfer /track/transfer requests
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <jansson.h>
+#include <microhttpd.h>
+#include <pthread.h>
+#include "taler_signatures.h"
+#include "taler-exchange-httpd_keystate.h"
+#include "taler-exchange-httpd_transfers_get.h"
+#include "taler-exchange-httpd_responses.h"
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
+
+
+/**
+ * Detail for /wire/deposit response.
+ */
+struct TEH_TrackTransferDetail
+{
+
+ /**
+ * We keep deposit details in a DLL.
+ */
+ struct TEH_TrackTransferDetail *next;
+
+ /**
+ * We keep deposit details in a DLL.
+ */
+ struct TEH_TrackTransferDetail *prev;
+
+ /**
+ * Hash of the proposal data.
+ */
+ struct GNUNET_HashCode h_contract_terms;
+
+ /**
+ * Coin's public key.
+ */
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+
+ /**
+ * Total value of the coin.
+ */
+ struct TALER_Amount deposit_value;
+
+ /**
+ * Fees charged by the exchange for the deposit.
+ */
+ struct TALER_Amount deposit_fee;
+};
+
+
+/**
+ * A merchant asked for transaction details about a wire transfer.
+ * Provide them. Generates the 200 reply.
+ *
+ * @param connection connection to the client
+ * @param total total amount that was transferred
+ * @param merchant_pub public key of the merchant
+ * @param h_wire destination account
+ * @param wire_fee wire fee that was charged
+ * @param exec_time execution time of the wire transfer
+ * @param wdd_head linked list with details about the combined deposits
+ * @return MHD result code
+ */
+static int
+reply_track_transfer_details (struct MHD_Connection *connection,
+ const struct TALER_Amount *total,
+ const struct
+ TALER_MerchantPublicKeyP *merchant_pub,
+ const struct GNUNET_HashCode *h_wire,
+ const struct TALER_Amount *wire_fee,
+ struct GNUNET_TIME_Absolute exec_time,
+ const struct TEH_TrackTransferDetail *wdd_head)
+{
+ const struct TEH_TrackTransferDetail *wdd_pos;
+ json_t *deposits;
+ struct TALER_WireDepositDetailP dd;
+ struct GNUNET_HashContext *hash_context;
+ struct TALER_WireDepositDataPS wdp;
+ struct TALER_ExchangePublicKeyP pub;
+ struct TALER_ExchangeSignatureP sig;
+
+ GNUNET_TIME_round_abs (&exec_time);
+ deposits = json_array ();
+ hash_context = GNUNET_CRYPTO_hash_context_start ();
+ for (wdd_pos = wdd_head; NULL != wdd_pos; wdd_pos = wdd_pos->next)
+ {
+ dd.h_contract_terms = wdd_pos->h_contract_terms;
+ dd.execution_time = GNUNET_TIME_absolute_hton (exec_time);
+ dd.coin_pub = wdd_pos->coin_pub;
+ TALER_amount_hton (&dd.deposit_value,
+ &wdd_pos->deposit_value);
+ TALER_amount_hton (&dd.deposit_fee,
+ &wdd_pos->deposit_fee);
+ GNUNET_CRYPTO_hash_context_read (hash_context,
+ &dd,
+ sizeof (struct TALER_WireDepositDetailP));
+ GNUNET_assert (0 ==
+ json_array_append_new (deposits,
+ json_pack ("{s:o, s:o, s:o, s:o}",
+ "h_contract_terms",
+ GNUNET_JSON_from_data_auto (
+ &wdd_pos->
+ h_contract_terms),
+ "coin_pub",
+ GNUNET_JSON_from_data_auto (
+ &wdd_pos->coin_pub),
+ "deposit_value",
+ TALER_JSON_from_amount (
+ &wdd_pos->deposit_value),
+ "deposit_fee",
+ TALER_JSON_from_amount (
+ &wdd_pos->deposit_fee))));
+ }
+ wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT);
+ wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS));
+ TALER_amount_hton (&wdp.total,
+ total);
+ TALER_amount_hton (&wdp.wire_fee,
+ wire_fee);
+ wdp.merchant_pub = *merchant_pub;
+ wdp.h_wire = *h_wire;
+ GNUNET_CRYPTO_hash_context_finish (hash_context,
+ &wdp.h_details);
+ if (GNUNET_OK !=
+ TEH_KS_sign (&wdp.purpose,
+ &pub,
+ &sig))
+ {
+ json_decref (deposits);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
+ }
+
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
+ "total", TALER_JSON_from_amount (total),
+ "wire_fee", TALER_JSON_from_amount (
+ wire_fee),
+ "merchant_pub",
+ GNUNET_JSON_from_data_auto (
+ merchant_pub),
+ "h_wire", GNUNET_JSON_from_data_auto (
+ h_wire),
+ "execution_time",
+ GNUNET_JSON_from_time_abs (exec_time),
+ "deposits", deposits,
+ "exchange_sig",
+ GNUNET_JSON_from_data_auto (&sig),
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&pub));
+}
+
+
+/**
+ * Closure for #handle_transaction_data.
+ */
+struct WtidTransactionContext
+{
+
+ /**
+ * Identifier of the wire transfer to track.
+ */
+ struct TALER_WireTransferIdentifierRawP wtid;
+
+ /**
+ * Total amount of the wire transfer, as calculated by
+ * summing up the individual amounts. To be rounded down
+ * to calculate the real transfer amount at the end.
+ * Only valid if @e is_valid is #GNUNET_YES.
+ */
+ struct TALER_Amount total;
+
+ /**
+ * Public key of the merchant, only valid if @e is_valid
+ * is #GNUNET_YES.
+ */
+ struct TALER_MerchantPublicKeyP merchant_pub;
+
+ /**
+ * Which method was used to wire the funds?
+ */
+ char *wire_method;
+
+ /**
+ * Hash of the wire details of the merchant (identical for all
+ * deposits), only valid if @e is_valid is #GNUNET_YES.
+ */
+ struct GNUNET_HashCode h_wire;
+
+ /**
+ * Wire fee applicable at @e exec_time.
+ */
+ struct TALER_Amount wire_fee;
+
+ /**
+ * Execution time of the wire transfer
+ */
+ struct GNUNET_TIME_Absolute exec_time;
+
+ /**
+ * Head of DLL with details for /wire/deposit response.
+ */
+ struct TEH_TrackTransferDetail *wdd_head;
+
+ /**
+ * Head of DLL with details for /wire/deposit response.
+ */
+ struct TEH_TrackTransferDetail *wdd_tail;
+
+ /**
+ * JSON array with details about the individual deposits.
+ */
+ json_t *deposits;
+
+ /**
+ * Initially #GNUNET_NO, if we found no deposits so far. Set to
+ * #GNUNET_YES if we got transaction data, and the database replies
+ * remained consistent with respect to @e merchant_pub and @e h_wire
+ * (as they should). Set to #GNUNET_SYSERR if we encountered an
+ * internal error.
+ */
+ int is_valid;
+
+};
+
+
+/**
+ * Function called with the results of the lookup of the
+ * transaction data for the given wire transfer identifier.
+ *
+ * @param cls our context for transmission
+ * @param rowid which row in the DB is the information from (for diagnostics), ignored
+ * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls)
+ * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls)
+ * @param wire where the funds were sent
+ * @param exec_time execution time of the wire transfer (should be same for all callbacks with the same @e cls)
+ * @param h_contract_terms which proposal was this payment about
+ * @param denom_pub denomination public key of the @a coin_pub (ignored)
+ * @param coin_pub which public key was this payment about
+ * @param deposit_value amount contributed by this coin in total
+ * @param deposit_fee deposit fee charged by exchange for this coin
+ */
+static void
+handle_transaction_data (void *cls,
+ uint64_t rowid,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct GNUNET_HashCode *h_wire,
+ const json_t *wire,
+ struct GNUNET_TIME_Absolute exec_time,
+ const struct GNUNET_HashCode *h_contract_terms,
+ const struct TALER_DenominationPublicKey *denom_pub,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_Amount *deposit_value,
+ const struct TALER_Amount *deposit_fee)
+{
+ struct WtidTransactionContext *ctx = cls;
+ struct TALER_Amount delta;
+ struct TEH_TrackTransferDetail *wdd;
+ char *wire_method;
+
+ (void) rowid;
+ (void) denom_pub;
+ if (GNUNET_SYSERR == ctx->is_valid)
+ return;
+ if (NULL == (wire_method = TALER_JSON_wire_to_method (wire)))
+ {
+ GNUNET_break (0);
+ ctx->is_valid = GNUNET_SYSERR;
+ return;
+ }
+ if (GNUNET_NO == ctx->is_valid)
+ {
+ ctx->merchant_pub = *merchant_pub;
+ ctx->h_wire = *h_wire;
+ ctx->exec_time = exec_time;
+ ctx->wire_method = wire_method;
+ ctx->is_valid = GNUNET_YES;
+ if (GNUNET_OK !=
+ TALER_amount_subtract (&ctx->total,
+ deposit_value,
+ deposit_fee))
+ {
+ GNUNET_break (0);
+ ctx->is_valid = GNUNET_SYSERR;
+ return;
+ }
+ }
+ else
+ {
+ if ( (0 != GNUNET_memcmp (&ctx->merchant_pub,
+ merchant_pub)) ||
+ (0 != strcmp (wire_method,
+ ctx->wire_method)) ||
+ (0 != GNUNET_memcmp (&ctx->h_wire,
+ h_wire)) )
+ {
+ GNUNET_break (0);
+ ctx->is_valid = GNUNET_SYSERR;
+ GNUNET_free (wire_method);
+ return;
+ }
+ GNUNET_free (wire_method);
+ if (GNUNET_OK !=
+ TALER_amount_subtract (&delta,
+ deposit_value,
+ deposit_fee))
+ {
+ GNUNET_break (0);
+ ctx->is_valid = GNUNET_SYSERR;
+ return;
+ }
+ if (GNUNET_OK !=
+ TALER_amount_add (&ctx->total,
+ &ctx->total,
+ &delta))
+ {
+ GNUNET_break (0);
+ ctx->is_valid = GNUNET_SYSERR;
+ return;
+ }
+ }
+ wdd = GNUNET_new (struct TEH_TrackTransferDetail);
+ wdd->deposit_value = *deposit_value;
+ wdd->deposit_fee = *deposit_fee;
+ wdd->h_contract_terms = *h_contract_terms;
+ wdd->coin_pub = *coin_pub;
+ GNUNET_CONTAINER_DLL_insert (ctx->wdd_head,
+ ctx->wdd_tail,
+ wdd);
+}
+
+
+/**
+ * Execute a "/track/transfer". Returns the transaction information
+ * associated with the given wire transfer identifier.
+ *
+ * If it returns a non-error code, the transaction logic MUST
+ * NOT queue a MHD response. IF it returns an hard error, the
+ * transaction logic MUST queue a MHD response and set @a mhd_ret. IF
+ * it returns the soft error code, the function MAY be called again to
+ * retry and MUST not queue a MHD response.
+ *
+ * @param cls closure
+ * @param connection MHD request which triggered the transaction
+ * @param session database session to use
+ * @param[out] mhd_ret set to MHD response status for @a connection,
+ * if transaction failed (!)
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+track_transfer_transaction (void *cls,
+ struct MHD_Connection *connection,
+ struct TALER_EXCHANGEDB_Session *session,
+ int *mhd_ret)
+{
+ struct WtidTransactionContext *ctx = cls;
+ enum GNUNET_DB_QueryStatus qs;
+ struct GNUNET_TIME_Absolute wire_fee_start_date;
+ struct GNUNET_TIME_Absolute wire_fee_end_date;
+ struct TALER_MasterSignatureP wire_fee_master_sig;
+ struct TALER_Amount closing_fee;
+
+ ctx->is_valid = GNUNET_NO;
+ ctx->wdd_head = NULL;
+ ctx->wdd_tail = NULL;
+ ctx->wire_method = NULL;
+ qs = TEH_plugin->lookup_wire_transfer (TEH_plugin->cls,
+ session,
+ &ctx->wtid,
+ &handle_transaction_data,
+ ctx);
+ if (0 > qs)
+ {
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ {
+ GNUNET_break (0);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED,
+ "failed to fetch transaction data");
+ }
+ return qs;
+ }
+ if (GNUNET_SYSERR == ctx->is_valid)
+ {
+ GNUNET_break (0);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT,
+ "exchange database internally inconsistent");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ if (GNUNET_NO == ctx->is_valid)
+ {
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
+ "wtid");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ qs = TEH_plugin->get_wire_fee (TEH_plugin->cls,
+ session,
+ ctx->wire_method,
+ ctx->exec_time,
+ &wire_fee_start_date,
+ &wire_fee_end_date,
+ &ctx->wire_fee,
+ &closing_fee,
+ &wire_fee_master_sig);
+ if (0 >= qs)
+ {
+ if ( (GNUNET_DB_STATUS_HARD_ERROR == qs) ||
+ (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS) )
+ {
+ GNUNET_break (0);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSFER_WIRE_FEE_NOT_FOUND,
+ "did not find wire fee");
+ }
+ return qs;
+ }
+ if (GNUNET_OK !=
+ TALER_amount_subtract (&ctx->total,
+ &ctx->total,
+ &ctx->wire_fee))
+ {
+ GNUNET_break (0);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSFER_WIRE_FEE_INCONSISTENT,
+ "could not subtract wire fee");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+}
+
+
+/**
+ * Free data structure reachable from @a ctx, but not @a ctx itself.
+ *
+ * @param ctx context to free
+ */
+static void
+free_ctx (struct WtidTransactionContext *ctx)
+{
+ struct TEH_TrackTransferDetail *wdd;
+
+ while (NULL != (wdd = ctx->wdd_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (ctx->wdd_head,
+ ctx->wdd_tail,
+ wdd);
+ GNUNET_free (wdd);
+ }
+ GNUNET_free_non_null (ctx->wire_method);
+}
+
+
+/**
+ * Handle a GET "/transfers/$WTID" request.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param args array of additional options (length: 1, just the wtid)
+ * @return MHD result code
+ */
+int
+TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const char *const args[1])
+{
+ struct WtidTransactionContext ctx;
+ int mhd_ret;
+
+ (void) rh;
+ memset (&ctx,
+ 0,
+ sizeof (ctx));
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[0],
+ strlen (args[0]),
+ &ctx.wtid,
+ sizeof (ctx.wtid)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_TRANSFERS_INVALID_WTID,
+ "wire transfer identifier malformed");
+ }
+ if (GNUNET_OK !=
+ TEH_DB_run_transaction (connection,
+ "run track transfer",
+ &mhd_ret,
+ &track_transfer_transaction,
+ &ctx))
+ {
+ free_ctx (&ctx);
+ return mhd_ret;
+ }
+ mhd_ret = reply_track_transfer_details (connection,
+ &ctx.total,
+ &ctx.merchant_pub,
+ &ctx.h_wire,
+ &ctx.wire_fee,
+ ctx.exec_time,
+ ctx.wdd_head);
+ free_ctx (&ctx);
+ return mhd_ret;
+}
+
+
+/* end of taler-exchange-httpd_transfers_get.c */
diff --git a/src/exchange/taler-exchange-httpd_transfers_get.h b/src/exchange/taler-exchange-httpd_transfers_get.h
@@ -0,0 +1,43 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2017 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_transfers_get.h
+ * @brief Handle wire transfer tracking-related requests
+ * @author Christian Grothoff
+ */
+#ifndef TALER_EXCHANGE_HTTPD_TRACK_TRANSFER_H
+#define TALER_EXCHANGE_HTTPD_TRACK_TRANSFER_H
+
+#include <gnunet/gnunet_util_lib.h>
+#include <microhttpd.h>
+#include "taler-exchange-httpd.h"
+
+
+/**
+ * Handle a GET "/transfers/$WTID" request.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param args array of additional options (length: 1, just the wtid)
+ * @return MHD result code
+ */
+int
+TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const char *const args[1]);
+
+
+#endif
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -0,0 +1,509 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2019 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 Foundation; either version 3,
+ or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General
+ Public License along with TALER; see the file COPYING. If not,
+ see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_withdraw.c
+ * @brief Handle /reserve/withdraw requests
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <jansson.h>
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
+#include "taler-exchange-httpd_withdraw.h"
+#include "taler-exchange-httpd_responses.h"
+#include "taler-exchange-httpd_keystate.h"
+
+
+/**
+ * Perform RSA signature before checking with the database?
+ * Reduces time spent in transaction, but may cause us to
+ * waste CPU time if DB check fails.
+ */
+#define OPTIMISTIC_SIGN 1
+
+
+/**
+ * Send reserve status information to client with the
+ * message that we have insufficient funds for the
+ * requested /reserve/withdraw operation.
+ *
+ * @param connection connection to the client
+ * @param rh reserve history to return
+ * @return MHD result code
+ */
+static int
+reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *connection,
+ 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)))
+ 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);
+
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_CONFLICT,
+ "{s:s, s:I, s:o, s:o}",
+ "hint", "insufficient funds",
+ "code",
+ (json_int_t)
+ TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
+ "balance", json_balance,
+ "history", json_history);
+}
+
+
+/**
+ * Send blinded coin information to client.
+ *
+ * @param connection connection to the client
+ * @param collectable blinded coin to return
+ * @return MHD result code
+ */
+static int
+reply_reserve_withdraw_success (struct MHD_Connection *connection,
+ const struct
+ TALER_EXCHANGEDB_CollectableBlindcoin *
+ collectable)
+{
+ json_t *sig_json;
+
+ sig_json = GNUNET_JSON_from_rsa_signature (collectable->sig.rsa_signature);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "ev_sig", sig_json);
+}
+
+
+/**
+ * Context for #withdraw_transaction.
+ */
+struct WithdrawContext
+{
+ /**
+ * Details about the withdrawal request.
+ */
+ struct TALER_WithdrawRequestPS wsrd;
+
+ /**
+ * Value of the coin plus withdraw fee.
+ */
+ struct TALER_Amount amount_required;
+
+ /**
+ * Hash of the denomination public key.
+ */
+ struct GNUNET_HashCode denom_pub_hash;
+
+ /**
+ * Signature over the request.
+ */
+ struct TALER_ReserveSignatureP signature;
+
+ /**
+ * Blinded planchet.
+ */
+ char *blinded_msg;
+
+ /**
+ * Key state to use to inspect previous withdrawal values.
+ */
+ struct TEH_KS_StateHandle *key_state;
+
+ /**
+ * Number of bytes in @e blinded_msg.
+ */
+ size_t blinded_msg_len;
+
+ /**
+ * Details about denomination we are about to withdraw.
+ */
+ struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
+
+ /**
+ * Set to the resulting signed coin data to be returned to the client.
+ */
+ struct TALER_EXCHANGEDB_CollectableBlindcoin collectable;
+
+};
+
+
+/**
+ * Function implementing /reserve/withdraw transaction. Runs the
+ * transaction logic; IF it returns a non-error code, the transaction
+ * logic MUST NOT queue a MHD response. IF it returns an hard error,
+ * the transaction logic MUST queue a MHD response and set @a mhd_ret.
+ * IF it returns the soft error code, the function MAY be called again
+ * to retry and MUST not queue a MHD response.
+ *
+ * Note that "wc->collectable.sig" may already be set before entering
+ * this function, either because OPTIMISTIC_SIGN was used and we signed
+ * before entering the transaction, or because this function is run
+ * twice (!) by #TEH_DB_run_transaction() and the first time created
+ * the signature and then failed to commit. Furthermore, we may get
+ * a 2nd correct signature briefly if "get_withdraw_info" suceeds and
+ * finds one in the DB. To avoid signing twice, the function may
+ * return a valid signature in "wc->collectable.sig" even if it failed.
+ * The caller must thus free the signature in either case.
+ *
+ * @param cls a `struct WithdrawContext *`
+ * @param connection MHD request which triggered the transaction
+ * @param session database session to use
+ * @param[out] mhd_ret set to MHD response status for @a connection,
+ * if transaction failed (!)
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+withdraw_transaction (void *cls,
+ struct MHD_Connection *connection,
+ struct TALER_EXCHANGEDB_Session *session,
+ int *mhd_ret)
+{
+ struct WithdrawContext *wc = cls;
+ struct TALER_EXCHANGEDB_Reserve r;
+ enum GNUNET_DB_QueryStatus qs;
+ struct TALER_Amount fee_withdraw;
+ struct TALER_DenominationSignature denom_sig;
+
+#if OPTIMISTIC_SIGN
+ /* store away optimistic signature to protect
+ it from being overwritten by get_withdraw_info */
+ denom_sig = wc->collectable.sig;
+ wc->collectable.sig.rsa_signature = NULL;
+#endif
+ qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
+ session,
+ &wc->wsrd.h_coin_envelope,
+ &wc->collectable);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR,
+ "failed to fetch withdraw data");
+ wc->collectable.sig = denom_sig;
+ return qs;
+ }
+
+ /* Don't sign again if we have already signed the coin */
+ if (1 == qs)
+ {
+#if OPTIMISTIC_SIGN
+ GNUNET_CRYPTO_rsa_signature_free (denom_sig.rsa_signature);
+#endif
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+ }
+ GNUNET_assert (0 == qs);
+ wc->collectable.sig = denom_sig;
+
+ /* Check if balance is sufficient */
+ r.pub = wc->wsrd.reserve_pub;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Trying to withdraw from reserve: %s\n",
+ TALER_B2S (&r.pub));
+ qs = TEH_plugin->reserve_get (TEH_plugin->cls,
+ session,
+ &r);
+ if (0 > qs)
+ {
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR,
+ "failed to fetch reserve data");
+ return qs;
+ }
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_WITHDRAW_RESERVE_UNKNOWN,
+ "reserve_pub");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ if (0 < TALER_amount_cmp (&wc->amount_required,
+ &r.balance))
+ {
+ char *amount_required;
+ char *r_balance;
+ struct TALER_EXCHANGEDB_ReserveHistory *rh;
+ /* The reserve does not have the required amount (actual
+ * amount + withdraw fee) */
+ GNUNET_break_op (0);
+ amount_required = TALER_amount_to_string (&wc->amount_required);
+ r_balance = TALER_amount_to_string (&r.balance);
+ TALER_LOG_WARNING ("Asked %s over a reserve worth %s\n",
+ amount_required,
+ r_balance);
+ GNUNET_free (amount_required);
+ GNUNET_free (r_balance);
+ qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
+ session,
+ &wc->wsrd.reserve_pub,
+ &rh);
+ if (NULL == rh)
+ {
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR,
+ "failed to fetch reserve history");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ *mhd_ret = reply_reserve_withdraw_insufficient_funds (connection,
+ rh);
+ TEH_plugin->free_reserve_history (TEH_plugin->cls,
+ rh);
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+
+ /* Balance is good, sign the coin! */
+#if ! OPTIMISTIC_SIGN
+ if (NULL == wc->collectable.sig.rsa_signature)
+ {
+ wc->collectable.sig.rsa_signature
+ = GNUNET_CRYPTO_rsa_sign_blinded (wc->dki->denom_priv.rsa_private_key,
+ wc->blinded_msg,
+ wc->blinded_msg_len);
+ if (NULL == wc->collectable.sig.rsa_signature)
+ {
+ GNUNET_break (0);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_SIGNATURE_FAILED,
+ "Failed to create signature");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ }
+#endif
+ TALER_amount_ntoh (&fee_withdraw,
+ &wc->dki->issue.properties.fee_withdraw);
+ wc->collectable.denom_pub_hash = wc->denom_pub_hash;
+ wc->collectable.amount_with_fee = wc->amount_required;
+ wc->collectable.withdraw_fee = fee_withdraw;
+ wc->collectable.reserve_pub = wc->wsrd.reserve_pub;
+ wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope;
+ wc->collectable.reserve_sig = wc->signature;
+ qs = TEH_plugin->insert_withdraw_info (TEH_plugin->cls,
+ session,
+ &wc->collectable);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_DB_STORE_ERROR,
+ "failed to persist withdraw data");
+ return qs;
+ }
+ return qs;
+}
+
+
+/**
+ * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the
+ * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which
+ * specifies the key/value of the coin to be withdrawn, and checks that the
+ * signature "reserve_sig" makes this a valid withdrawal request from the
+ * specified reserve. If so, the envelope with the blinded coin "coin_ev" is
+ * passed down to execute the withdrawl operation.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param root uploaded JSON data
+ * @param args array of additional options (first must be the
+ * reserve public key, the second one should be "withdraw")
+ * @return MHD result code
+ */
+int
+TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const json_t *root,
+ const char *const args[2])
+{
+ struct WithdrawContext wc;
+ int res;
+ int mhd_ret;
+ unsigned int hc;
+ enum TALER_ErrorCode ec;
+ struct TALER_Amount amount;
+ struct TALER_Amount fee_withdraw;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_varsize ("coin_ev",
+ (void **) &wc.blinded_msg,
+ &wc.blinded_msg_len),
+ GNUNET_JSON_spec_fixed_auto ("reserve_sig",
+ &wc.signature),
+ GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
+ &wc.denom_pub_hash),
+ GNUNET_JSON_spec_end ()
+ };
+
+ (void) rh;
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[0],
+ strlen (args[0]),
+ &wc.wsrd.reserve_pub,
+ sizeof (wc.wsrd.reserve_pub)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_RESERVES_INVALID_RESERVE_PUB,
+ "reserve public key malformed");
+ }
+
+ res = TALER_MHD_parse_json_data (connection,
+ root,
+ spec);
+ if (GNUNET_OK != res)
+ return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
+ wc.key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
+ if (NULL == wc.key_state)
+ {
+ TALER_LOG_ERROR ("Lacking keys to operate\n");
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
+ }
+ wc.dki = TEH_KS_denomination_key_lookup_by_hash (wc.key_state,
+ &wc.denom_pub_hash,
+ TEH_KS_DKU_WITHDRAW,
+ &ec,
+ &hc);
+ if (NULL == wc.dki)
+ {
+ GNUNET_JSON_parse_free (spec);
+ TEH_KS_release (wc.key_state);
+ return TALER_MHD_reply_with_error (connection,
+ hc,
+ ec,
+ "could not find denomination key");
+ }
+ GNUNET_assert (NULL != wc.dki->denom_priv.rsa_private_key);
+ TALER_amount_ntoh (&amount,
+ &wc.dki->issue.properties.value);
+ TALER_amount_ntoh (&fee_withdraw,
+ &wc.dki->issue.properties.fee_withdraw);
+ if (GNUNET_OK !=
+ TALER_amount_add (&wc.amount_required,
+ &amount,
+ &fee_withdraw))
+ {
+ GNUNET_JSON_parse_free (spec);
+ TEH_KS_release (wc.key_state);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW,
+ "amount overflow for value plus withdraw fee");
+ }
+ TALER_amount_hton (&wc.wsrd.amount_with_fee,
+ &wc.amount_required);
+ TALER_amount_hton (&wc.wsrd.withdraw_fee,
+ &fee_withdraw);
+ /* verify signature! */
+ wc.wsrd.purpose.size
+ = htonl (sizeof (struct TALER_WithdrawRequestPS));
+ wc.wsrd.purpose.purpose
+ = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
+ wc.wsrd.h_denomination_pub
+ = wc.denom_pub_hash;
+ GNUNET_CRYPTO_hash (wc.blinded_msg,
+ wc.blinded_msg_len,
+ &wc.wsrd.h_coin_envelope);
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
+ &wc.wsrd.purpose,
+ &wc.signature.eddsa_signature,
+ &wc.wsrd.reserve_pub.eddsa_pub))
+ {
+ TALER_LOG_WARNING (
+ "Client supplied invalid signature for /reserve/withdraw request\n");
+ GNUNET_JSON_parse_free (spec);
+ TEH_KS_release (wc.key_state);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID,
+ "reserve_sig");
+ }
+
+#if OPTIMISTIC_SIGN
+ /* Sign before transaction! */
+ wc.collectable.sig.rsa_signature
+ = GNUNET_CRYPTO_rsa_sign_blinded (wc.dki->denom_priv.rsa_private_key,
+ wc.blinded_msg,
+ wc.blinded_msg_len);
+ if (NULL == wc.collectable.sig.rsa_signature)
+ {
+ GNUNET_break (0);
+ GNUNET_JSON_parse_free (spec);
+ TEH_KS_release (wc.key_state);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_SIGNATURE_FAILED,
+ "Failed to sign");
+ }
+#endif
+
+ if (GNUNET_OK !=
+ TEH_DB_run_transaction (connection,
+ "run reserve withdraw",
+ &mhd_ret,
+ &withdraw_transaction,
+ &wc))
+ {
+ TEH_KS_release (wc.key_state);
+ /* Even if #withdraw_transaction() failed, it may have created a signature
+ (or we might have done it optimistically above). */
+ if (NULL != wc.collectable.sig.rsa_signature)
+ GNUNET_CRYPTO_rsa_signature_free (wc.collectable.sig.rsa_signature);
+ GNUNET_JSON_parse_free (spec);
+ return mhd_ret;
+ }
+ TEH_KS_release (wc.key_state);
+ GNUNET_JSON_parse_free (spec);
+
+ mhd_ret = reply_reserve_withdraw_success (connection,
+ &wc.collectable);
+ GNUNET_CRYPTO_rsa_signature_free (wc.collectable.sig.rsa_signature);
+ return mhd_ret;
+}
+
+
+/* end of taler-exchange-httpd_withdraw.c */
diff --git a/src/exchange/taler-exchange-httpd_withdraw.h b/src/exchange/taler-exchange-httpd_withdraw.h
@@ -0,0 +1,51 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2020 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_withdraw.h
+ * @brief Handle /reserve/withdraw requests
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#ifndef TALER_EXCHANGE_HTTPD_RESERVE_WITHDRAW_H
+#define TALER_EXCHANGE_HTTPD_RESERVE_WITHDRAW_H
+
+#include <microhttpd.h>
+#include "taler-exchange-httpd.h"
+
+
+/**
+ * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the
+ * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which
+ * specifies the key/value of the coin to be withdrawn, and checks that the
+ * signature "reserve_sig" makes this a valid withdrawl request from the
+ * specified reserve. If so, the envelope with the blinded coin "coin_ev" is
+ * passed down to execute the withdrawl operation.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param root uploaded JSON data
+ * @param args array of additional options (first must be the
+ * reserve public key, the second one should be "withdraw")
+ * @return MHD result code
+ */
+int
+TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const json_t *root,
+ const char *const args[2]);
+
+#endif
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2018 Taler Systems SA
+ Copyright (C) 2014-2020 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
@@ -494,19 +494,6 @@ TALER_EXCHANGE_test_signing_key (const struct TALER_EXCHANGE_Keys *keys,
/**
- * Lookup the given @a pub in @a keys.
- *
- * @param keys the exchange's key set
- * @param pub claimed current online signing key for the exchange
- * @return NULL if @a pub was not found
- */
-const struct TALER_EXCHANGE_SigningPublicKey *
-TALER_EXCHANGE_get_signing_key_details (const struct TALER_EXCHANGE_Keys *keys,
- const struct
- TALER_ExchangePublicKeyP *pub);
-
-
-/**
* Get exchange's base URL.
*
* @param exchange exchange handle.
@@ -574,11 +561,11 @@ TALER_EXCHANGE_get_denomination_key_by_hash (const struct
* @return NULL on error (@a exchange_pub not known)
*/
const struct TALER_EXCHANGE_SigningPublicKey *
-TALER_EXCHANGE_get_exchange_signing_key_info (const struct
- TALER_EXCHANGE_Keys *keys,
- const struct
- TALER_ExchangePublicKeyP *
- exchange_pub);
+TALER_EXCHANGE_get_signing_key_info (const struct
+ TALER_EXCHANGE_Keys *keys,
+ const struct
+ TALER_ExchangePublicKeyP *
+ exchange_pub);
/* ********************* /wire *********************** */
@@ -661,12 +648,12 @@ struct TALER_EXCHANGE_WireAccount
* @param accounts list of wire accounts of the exchange, NULL on error
*/
typedef void
-(*TALER_EXCHANGE_WireResultCallback) (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- unsigned int accounts_len,
- const struct
- TALER_EXCHANGE_WireAccount *accounts);
+(*TALER_EXCHANGE_WireCallback) (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ unsigned int accounts_len,
+ const struct
+ TALER_EXCHANGE_WireAccount *accounts);
/**
@@ -696,7 +683,7 @@ struct TALER_EXCHANGE_WireHandle;
*/
struct TALER_EXCHANGE_WireHandle *
TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange,
- TALER_EXCHANGE_WireResultCallback wire_cb,
+ TALER_EXCHANGE_WireCallback wire_cb,
void *wire_cb_cls);
@@ -833,12 +820,12 @@ struct TALER_EXCHANGE_RefundHandle;
* be forwarded to the customer)
*/
typedef void
-(*TALER_EXCHANGE_RefundResultCallback) (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const struct
- TALER_ExchangePublicKeyP *sign_key,
- const json_t *obj);
+(*TALER_EXCHANGE_RefundCallback) (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const struct
+ TALER_ExchangePublicKeyP *sign_key,
+ const json_t *obj);
/**
@@ -879,7 +866,7 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
uint64_t rtransaction_id,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
- TALER_EXCHANGE_RefundResultCallback cb,
+ TALER_EXCHANGE_RefundCallback cb,
void *cb_cls);
@@ -923,7 +910,7 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange,
uint64_t rtransaction_id,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_MerchantSignatureP *merchant_sig,
- TALER_EXCHANGE_RefundResultCallback cb,
+ TALER_EXCHANGE_RefundCallback cb,
void *cb_cls);
@@ -945,7 +932,7 @@ TALER_EXCHANGE_refund_cancel (struct TALER_EXCHANGE_RefundHandle *refund);
/**
* @brief A /reserve/status Handle
*/
-struct TALER_EXCHANGE_ReserveStatusHandle;
+struct TALER_EXCHANGE_ReservesGetHandle;
/**
@@ -1116,16 +1103,16 @@ struct TALER_EXCHANGE_ReserveHistory
* @param history detailed transaction history, NULL on error
*/
typedef void
-(*TALER_EXCHANGE_ReserveStatusResultCallback) (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const json_t *json,
- const struct
- TALER_Amount *balance,
- unsigned int history_length,
- const struct
- TALER_EXCHANGE_ReserveHistory *
- history);
+(*TALER_EXCHANGE_ReservesGetCallback) (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const json_t *json,
+ const struct
+ TALER_Amount *balance,
+ unsigned int history_length,
+ const struct
+ TALER_EXCHANGE_ReserveHistory *
+ history);
/**
@@ -1144,12 +1131,12 @@ typedef void
* @return a handle for this request; NULL if the inputs are invalid (i.e.
* signatures fail to verify). In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_ReserveStatusHandle *
-TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
- const struct
- TALER_ReservePublicKeyP *reserve_pub,
- TALER_EXCHANGE_ReserveStatusResultCallback cb,
- void *cb_cls);
+struct TALER_EXCHANGE_ReservesGetHandle *
+TALER_EXCHANGE_reserves_get (struct TALER_EXCHANGE_Handle *exchange,
+ const struct
+ TALER_ReservePublicKeyP *reserve_pub,
+ TALER_EXCHANGE_ReservesGetCallback cb,
+ void *cb_cls);
/**
@@ -1159,8 +1146,8 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
* @param rsh the reserve status request handle
*/
void
-TALER_EXCHANGE_reserve_status_cancel (struct
- TALER_EXCHANGE_ReserveStatusHandle *rsh);
+TALER_EXCHANGE_reserves_get_cancel (struct
+ TALER_EXCHANGE_ReservesGetHandle *rsh);
/* ********************* /reserve/withdraw *********************** */
@@ -1169,7 +1156,7 @@ TALER_EXCHANGE_reserve_status_cancel (struct
/**
* @brief A /reserve/withdraw Handle
*/
-struct TALER_EXCHANGE_ReserveWithdrawHandle;
+struct TALER_EXCHANGE_WithdrawHandle;
/**
@@ -1184,13 +1171,13 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle;
* @param full_response full response from the exchange (for logging, in case of errors)
*/
typedef void
-(*TALER_EXCHANGE_ReserveWithdrawResultCallback) (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const struct
- TALER_DenominationSignature *
- sig,
- const json_t *full_response);
+(*TALER_EXCHANGE_WithdrawCallback) (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const struct
+ TALER_DenominationSignature *
+ sig,
+ const json_t *full_response);
/**
@@ -1214,15 +1201,15 @@ typedef void
* if the inputs are invalid (i.e. denomination key not with this exchange).
* In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_ReserveWithdrawHandle *
-TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_EXCHANGE_DenomPublicKey *pk,
- const struct
- TALER_ReservePrivateKeyP *reserve_priv,
- const struct TALER_PlanchetSecretsP *ps,
- TALER_EXCHANGE_ReserveWithdrawResultCallback
- res_cb,
- void *res_cb_cls);
+struct TALER_EXCHANGE_WithdrawHandle *
+TALER_EXCHANGE_withdraw (struct TALER_EXCHANGE_Handle *exchange,
+ const struct TALER_EXCHANGE_DenomPublicKey *pk,
+ const struct
+ TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_PlanchetSecretsP *ps,
+ TALER_EXCHANGE_WithdrawCallback
+ res_cb,
+ void *res_cb_cls);
/**
@@ -1247,18 +1234,18 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
* if the inputs are invalid (i.e. denomination key not with this exchange).
* In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_ReserveWithdrawHandle *
-TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
- const struct
- TALER_EXCHANGE_DenomPublicKey *pk,
- const struct
- TALER_ReserveSignatureP *reserve_sig,
- const struct
- TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_PlanchetSecretsP *ps,
- TALER_EXCHANGE_ReserveWithdrawResultCallback
- res_cb,
- void *res_cb_cls);
+struct TALER_EXCHANGE_WithdrawHandle *
+TALER_EXCHANGE_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
+ const struct
+ TALER_EXCHANGE_DenomPublicKey *pk,
+ const struct
+ TALER_ReserveSignatureP *reserve_sig,
+ const struct
+ TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_PlanchetSecretsP *ps,
+ TALER_EXCHANGE_WithdrawCallback
+ res_cb,
+ void *res_cb_cls);
/**
@@ -1268,9 +1255,9 @@ TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
* @param sign the withdraw sign request handle
*/
void
-TALER_EXCHANGE_reserve_withdraw_cancel (struct
- TALER_EXCHANGE_ReserveWithdrawHandle *
- sign);
+TALER_EXCHANGE_withdraw_cancel (struct
+ TALER_EXCHANGE_WithdrawHandle *
+ sign);
/* ********************* /refresh/melt+reveal ***************************** */
@@ -1551,12 +1538,12 @@ TALER_EXCHANGE_refresh_link_cancel (struct
TALER_EXCHANGE_RefreshLinkHandle *rlh);
-/* ********************* /track/transfer *********************** */
+/* ********************* /transfers/$WTID *********************** */
/**
- * @brief A /track/transfer Handle
+ * @brief A /transfers/$WTID Handle
*/
-struct TALER_EXCHANGE_TrackTransferHandle;
+struct TALER_EXCHANGE_TransfersGetHandle;
/**
@@ -1578,20 +1565,20 @@ struct TALER_EXCHANGE_TrackTransferHandle;
* @param details array with details about the combined transactions
*/
typedef void
-(*TALER_EXCHANGE_TrackTransferCallback)(void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const struct
- TALER_ExchangePublicKeyP *sign_key,
- const json_t *json,
- const struct GNUNET_HashCode *h_wire,
- struct GNUNET_TIME_Absolute
- execution_time,
- const struct TALER_Amount *total_amount,
- const struct TALER_Amount *wire_fee,
- unsigned int details_length,
- const struct
- TALER_TrackTransferDetails *details);
+(*TALER_EXCHANGE_TransfersGetCallback)(void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const struct
+ TALER_ExchangePublicKeyP *sign_key,
+ const json_t *json,
+ const struct GNUNET_HashCode *h_wire,
+ struct GNUNET_TIME_Absolute
+ execution_time,
+ const struct TALER_Amount *total_amount,
+ const struct TALER_Amount *wire_fee,
+ unsigned int details_length,
+ const struct
+ TALER_TrackTransferDetails *details);
/**
@@ -1604,12 +1591,12 @@ typedef void
* @param cb_cls closure for @a cb
* @return handle to cancel operation
*/
-struct TALER_EXCHANGE_TrackTransferHandle *
-TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange,
- const struct
- TALER_WireTransferIdentifierRawP *wtid,
- TALER_EXCHANGE_TrackTransferCallback cb,
- void *cb_cls);
+struct TALER_EXCHANGE_TransfersGetHandle *
+TALER_EXCHANGE_transfers_get (struct TALER_EXCHANGE_Handle *exchange,
+ const struct
+ TALER_WireTransferIdentifierRawP *wtid,
+ TALER_EXCHANGE_TransfersGetCallback cb,
+ void *cb_cls);
/**
@@ -1619,17 +1606,17 @@ TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange,
* @param wdh the wire deposits request handle
*/
void
-TALER_EXCHANGE_track_transfer_cancel (struct
- TALER_EXCHANGE_TrackTransferHandle *wdh);
+TALER_EXCHANGE_transfers_get_cancel (struct
+ TALER_EXCHANGE_TransfersGetHandle *wdh);
-/* ********************* /track/transaction *********************** */
+/* ********************* GET /deposits/ *********************** */
/**
- * @brief A /track/transaction Handle
+ * @brief A /deposits/ GET Handle
*/
-struct TALER_EXCHANGE_TrackTransactionHandle;
+struct TALER_EXCHANGE_DepositGetHandle;
/**
@@ -1647,19 +1634,19 @@ struct TALER_EXCHANGE_TrackTransactionHandle;
* @param coin_contribution contribution to the total amount by this coin (can be NULL)
*/
typedef void
-(*TALER_EXCHANGE_TrackTransactionCallback)(void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const struct
- TALER_ExchangePublicKeyP *sign_key,
- const json_t *json,
- const struct
- TALER_WireTransferIdentifierRawP *
- wtid,
- struct GNUNET_TIME_Absolute
- execution_time,
- const struct
- TALER_Amount *coin_contribution);
+(*TALER_EXCHANGE_DepositGetCallback)(void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const struct
+ TALER_ExchangePublicKeyP *sign_key,
+ const json_t *json,
+ const struct
+ TALER_WireTransferIdentifierRawP *
+ wtid,
+ struct GNUNET_TIME_Absolute
+ execution_time,
+ const struct
+ TALER_Amount *coin_contribution);
/**
@@ -1676,17 +1663,17 @@ typedef void
* @param cb_cls closure for @a cb
* @return handle to abort request
*/
-struct TALER_EXCHANGE_TrackTransactionHandle *
-TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange,
- const struct
- TALER_MerchantPrivateKeyP *merchant_priv,
- const struct GNUNET_HashCode *h_wire,
- const struct
- GNUNET_HashCode *h_contract_terms,
- const struct
- TALER_CoinSpendPublicKeyP *coin_pub,
- TALER_EXCHANGE_TrackTransactionCallback cb,
- void *cb_cls);
+struct TALER_EXCHANGE_DepositGetHandle *
+TALER_EXCHANGE_deposits_get (struct TALER_EXCHANGE_Handle *exchange,
+ const struct
+ TALER_MerchantPrivateKeyP *merchant_priv,
+ const struct GNUNET_HashCode *h_wire,
+ const struct
+ GNUNET_HashCode *h_contract_terms,
+ const struct
+ TALER_CoinSpendPublicKeyP *coin_pub,
+ TALER_EXCHANGE_DepositGetCallback cb,
+ void *cb_cls);
/**
@@ -1696,9 +1683,9 @@ TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange,
* @param dwh the wire deposits request handle
*/
void
-TALER_EXCHANGE_track_transaction_cancel (struct
- TALER_EXCHANGE_TrackTransactionHandle *
- dwh);
+TALER_EXCHANGE_deposits_get_cancel (struct
+ TALER_EXCHANGE_DepositGetHandle *
+ dwh);
/**
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
@@ -382,17 +382,17 @@ TALER_EXCHANGE_verify_coin_history (const struct
* @return NULL on error (@a exchange_pub not known)
*/
const struct TALER_EXCHANGE_SigningPublicKey *
-TALER_EXCHANGE_get_exchange_signing_key_info (const struct
- TALER_EXCHANGE_Keys *keys,
- const struct
- TALER_ExchangePublicKeyP *
- exchange_pub)
+TALER_EXCHANGE_get_signing_key_info (const struct
+ TALER_EXCHANGE_Keys *keys,
+ const struct
+ TALER_ExchangePublicKeyP *
+ exchange_pub)
{
for (unsigned int i = 0; i<keys->num_sign_keys; i++)
{
- const struct TALER_EXCHANGE_SigningPublicKey *spk;
+ const struct TALER_EXCHANGE_SigningPublicKey *spk
+ = &keys->sign_keys[i];
- spk = &keys->sign_keys[i];
if (0 == GNUNET_memcmp (exchange_pub,
&spk->key))
return spk;
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
@@ -146,8 +146,8 @@ auditor_cb (void *cls,
"Will provide deposit confirmation to auditor `%s'\n",
TALER_B2S (auditor_pub));
key_state = TALER_EXCHANGE_get_keys (dh->exchange);
- spk = TALER_EXCHANGE_get_signing_key_details (key_state,
- &dh->exchange_pub);
+ spk = TALER_EXCHANGE_get_signing_key_info (key_state,
+ &dh->exchange_pub);
GNUNET_assert (NULL != spk);
TALER_amount_ntoh (&amount_without_fee,
&dh->depconf.amount_without_fee);
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
@@ -2038,30 +2038,6 @@ TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange)
/**
- * Lookup the given @a pub in @a keys.
- *
- * @param keys the exchange's key set
- * @param pub claimed current online signing key for the exchange
- * @return NULL if @a pub was not found
- */
-const struct TALER_EXCHANGE_SigningPublicKey *
-TALER_EXCHANGE_get_signing_key_details (const struct TALER_EXCHANGE_Keys *keys,
- const struct
- TALER_ExchangePublicKeyP *pub)
-{
- for (unsigned int i = 0; i<keys->num_sign_keys; i++)
- {
- struct TALER_EXCHANGE_SigningPublicKey *spk = &keys->sign_keys[i];
-
- if (0 == GNUNET_memcmp (pub,
- &spk->key))
- return spk;
- }
- return NULL;
-}
-
-
-/**
* Test if the given @a pub is a the current signing key from the exchange
* according to @a keys.
*
diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c
@@ -62,7 +62,7 @@ struct TALER_EXCHANGE_RefundHandle
/**
* Function to call with the result.
*/
- TALER_EXCHANGE_RefundResultCallback cb;
+ TALER_EXCHANGE_RefundCallback cb;
/**
* Closure for @a cb.
@@ -250,7 +250,7 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
uint64_t rtransaction_id,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
- TALER_EXCHANGE_RefundResultCallback cb,
+ TALER_EXCHANGE_RefundCallback cb,
void *cb_cls)
{
struct TALER_RefundRequestPS rr;
@@ -326,7 +326,7 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange,
uint64_t rtransaction_id,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_MerchantSignatureP *merchant_sig,
- TALER_EXCHANGE_RefundResultCallback cb,
+ TALER_EXCHANGE_RefundCallback cb,
void *cb_cls)
{
struct TALER_EXCHANGE_RefundHandle *rh;
diff --git a/src/lib/exchange_api_reserve.c b/src/lib/exchange_api_reserve.c
@@ -37,7 +37,7 @@
/**
* @brief A Withdraw Status Handle
*/
-struct TALER_EXCHANGE_ReserveStatusHandle
+struct TALER_EXCHANGE_ReservesGetHandle
{
/**
@@ -58,7 +58,7 @@ struct TALER_EXCHANGE_ReserveStatusHandle
/**
* Function to call with the result.
*/
- TALER_EXCHANGE_ReserveStatusResultCallback cb;
+ TALER_EXCHANGE_ReservesGetCallback cb;
/**
* Public key of the reserve we are querying.
@@ -495,7 +495,7 @@ free_rhistory (struct TALER_EXCHANGE_ReserveHistory *rhistory,
* @return #GNUNET_OK on success
*/
static int
-handle_reserve_status_ok (struct TALER_EXCHANGE_ReserveStatusHandle *rsh,
+handle_reserve_status_ok (struct TALER_EXCHANGE_ReservesGetHandle *rsh,
const json_t *j)
{
json_t *history;
@@ -575,7 +575,7 @@ handle_reserve_status_ok (struct TALER_EXCHANGE_ReserveStatusHandle *rsh,
* Function called when we're done processing the
* HTTP /reserve/status request.
*
- * @param cls the `struct TALER_EXCHANGE_ReserveStatusHandle`
+ * @param cls the `struct TALER_EXCHANGE_ReservesGetHandle`
* @param response_code HTTP response code, 0 on error
* @param response parsed JSON result, NULL on error
*/
@@ -584,7 +584,7 @@ handle_reserve_status_finished (void *cls,
long response_code,
const void *response)
{
- struct TALER_EXCHANGE_ReserveStatusHandle *rsh = cls;
+ struct TALER_EXCHANGE_ReservesGetHandle *rsh = cls;
const json_t *j = response;
rsh->job = NULL;
@@ -629,7 +629,7 @@ handle_reserve_status_finished (void *cls,
0, NULL);
rsh->cb = NULL;
}
- TALER_EXCHANGE_reserve_status_cancel (rsh);
+ TALER_EXCHANGE_reserves_get_cancel (rsh);
}
@@ -649,14 +649,14 @@ handle_reserve_status_finished (void *cls,
* @return a handle for this request; NULL if the inputs are invalid (i.e.
* signatures fail to verify). In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_ReserveStatusHandle *
-TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
- const struct
- TALER_ReservePublicKeyP *reserve_pub,
- TALER_EXCHANGE_ReserveStatusResultCallback cb,
- void *cb_cls)
+struct TALER_EXCHANGE_ReservesGetHandle *
+TALER_EXCHANGE_reserves_get (struct TALER_EXCHANGE_Handle *exchange,
+ const struct
+ TALER_ReservePublicKeyP *reserve_pub,
+ TALER_EXCHANGE_ReservesGetCallback cb,
+ void *cb_cls)
{
- struct TALER_EXCHANGE_ReserveStatusHandle *rsh;
+ struct TALER_EXCHANGE_ReservesGetHandle *rsh;
struct GNUNET_CURL_Context *ctx;
CURL *eh;
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 16];
@@ -682,7 +682,7 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
"/reserves/%s",
pub_str);
}
- rsh = GNUNET_new (struct TALER_EXCHANGE_ReserveStatusHandle);
+ rsh = GNUNET_new (struct TALER_EXCHANGE_ReservesGetHandle);
rsh->exchange = exchange;
rsh->cb = cb;
rsh->cb_cls = cb_cls;
@@ -707,8 +707,8 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
* @param rsh the reserve status request handle
*/
void
-TALER_EXCHANGE_reserve_status_cancel (struct
- TALER_EXCHANGE_ReserveStatusHandle *rsh)
+TALER_EXCHANGE_reserves_get_cancel (struct
+ TALER_EXCHANGE_ReservesGetHandle *rsh)
{
if (NULL != rsh->job)
{
@@ -725,7 +725,7 @@ TALER_EXCHANGE_reserve_status_cancel (struct
/**
* @brief A Withdraw Sign Handle
*/
-struct TALER_EXCHANGE_ReserveWithdrawHandle
+struct TALER_EXCHANGE_WithdrawHandle
{
/**
@@ -752,7 +752,7 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle
/**
* Function to call with the result.
*/
- TALER_EXCHANGE_ReserveWithdrawResultCallback cb;
+ TALER_EXCHANGE_WithdrawCallback cb;
/**
* Secrets of the planchet.
@@ -796,7 +796,7 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle
* @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
*/
static int
-reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
+reserve_withdraw_ok (struct TALER_EXCHANGE_WithdrawHandle *wsh,
const json_t *json)
{
struct GNUNET_CRYPTO_RsaSignature *blind_sig;
@@ -855,7 +855,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
*/
static int
reserve_withdraw_payment_required (struct
- TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
+ TALER_EXCHANGE_WithdrawHandle *wsh,
const json_t *json)
{
struct TALER_Amount balance;
@@ -956,7 +956,7 @@ reserve_withdraw_payment_required (struct
* Function called when we're done processing the
* HTTP /reserves/$RESERVE_PUB/withdraw request.
*
- * @param cls the `struct TALER_EXCHANGE_ReserveWithdrawHandle`
+ * @param cls the `struct TALER_EXCHANGE_WithdrawHandle`
* @param response_code HTTP response code, 0 on error
* @param response parsed JSON result, NULL on error
*/
@@ -965,7 +965,7 @@ handle_reserve_withdraw_finished (void *cls,
long response_code,
const void *response)
{
- struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh = cls;
+ struct TALER_EXCHANGE_WithdrawHandle *wsh = cls;
const json_t *j = response;
wsh->job = NULL;
@@ -1031,13 +1031,13 @@ handle_reserve_withdraw_finished (void *cls,
j);
wsh->cb = NULL;
}
- TALER_EXCHANGE_reserve_withdraw_cancel (wsh);
+ TALER_EXCHANGE_withdraw_cancel (wsh);
}
/**
- * Helper function for #TALER_EXCHANGE_reserve_withdraw2() and
- * #TALER_EXCHANGE_reserve_withdraw().
+ * Helper function for #TALER_EXCHANGE_withdraw2() and
+ * #TALER_EXCHANGE_withdraw().
*
* @param exchange the exchange handle; the exchange must be ready to operate
* @param pk kind of coin to create
@@ -1052,17 +1052,17 @@ handle_reserve_withdraw_finished (void *cls,
* if the inputs are invalid (i.e. denomination key not with this exchange).
* In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_ReserveWithdrawHandle *
+struct TALER_EXCHANGE_WithdrawHandle *
reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_EXCHANGE_DenomPublicKey *pk,
const struct TALER_ReserveSignatureP *reserve_sig,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_PlanchetSecretsP *ps,
const struct TALER_PlanchetDetail *pd,
- TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
+ TALER_EXCHANGE_WithdrawCallback res_cb,
void *res_cb_cls)
{
- struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
+ struct TALER_EXCHANGE_WithdrawHandle *wsh;
struct GNUNET_CURL_Context *ctx;
json_t *withdraw_obj;
CURL *eh;
@@ -1084,7 +1084,7 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange,
"/reserves/%s/withdraw",
pub_str);
}
- wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveWithdrawHandle);
+ wsh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle);
wsh->exchange = exchange;
wsh->cb = res_cb;
wsh->cb_cls = res_cb_cls;
@@ -1159,21 +1159,21 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange,
* if the inputs are invalid (i.e. denomination key not with this exchange).
* In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_ReserveWithdrawHandle *
-TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_EXCHANGE_DenomPublicKey *pk,
- const struct
- TALER_ReservePrivateKeyP *reserve_priv,
- const struct TALER_PlanchetSecretsP *ps,
- TALER_EXCHANGE_ReserveWithdrawResultCallback
- res_cb,
- void *res_cb_cls)
+struct TALER_EXCHANGE_WithdrawHandle *
+TALER_EXCHANGE_withdraw (struct TALER_EXCHANGE_Handle *exchange,
+ const struct TALER_EXCHANGE_DenomPublicKey *pk,
+ const struct
+ TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_PlanchetSecretsP *ps,
+ TALER_EXCHANGE_WithdrawCallback
+ res_cb,
+ void *res_cb_cls)
{
struct TALER_Amount amount_with_fee;
struct TALER_ReserveSignatureP reserve_sig;
struct TALER_WithdrawRequestPS req;
struct TALER_PlanchetDetail pd;
- struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
+ struct TALER_EXCHANGE_WithdrawHandle *wsh;
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
&req.reserve_pub.eddsa_pub);
@@ -1243,20 +1243,20 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
* if the inputs are invalid (i.e. denomination key not with this exchange).
* In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_ReserveWithdrawHandle *
-TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
- const struct
- TALER_EXCHANGE_DenomPublicKey *pk,
- const struct
- TALER_ReserveSignatureP *reserve_sig,
- const struct
- TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_PlanchetSecretsP *ps,
- TALER_EXCHANGE_ReserveWithdrawResultCallback
- res_cb,
- void *res_cb_cls)
+struct TALER_EXCHANGE_WithdrawHandle *
+TALER_EXCHANGE_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
+ const struct
+ TALER_EXCHANGE_DenomPublicKey *pk,
+ const struct
+ TALER_ReserveSignatureP *reserve_sig,
+ const struct
+ TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_PlanchetSecretsP *ps,
+ TALER_EXCHANGE_WithdrawCallback
+ res_cb,
+ void *res_cb_cls)
{
- struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
+ struct TALER_EXCHANGE_WithdrawHandle *wsh;
struct TALER_PlanchetDetail pd;
if (GNUNET_OK !=
@@ -1287,9 +1287,9 @@ TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
* @param sign the withdraw sign request handle
*/
void
-TALER_EXCHANGE_reserve_withdraw_cancel (struct
- TALER_EXCHANGE_ReserveWithdrawHandle *
- sign)
+TALER_EXCHANGE_withdraw_cancel (struct
+ TALER_EXCHANGE_WithdrawHandle *
+ sign)
{
if (NULL != sign->job)
{
diff --git a/src/lib/exchange_api_track_transaction.c b/src/lib/exchange_api_track_transaction.c
@@ -35,7 +35,7 @@
/**
* @brief A Deposit Wtid Handle
*/
-struct TALER_EXCHANGE_TrackTransactionHandle
+struct TALER_EXCHANGE_DepositGetHandle
{
/**
@@ -62,7 +62,7 @@ struct TALER_EXCHANGE_TrackTransactionHandle
/**
* Function to call with the result.
*/
- TALER_EXCHANGE_TrackTransactionCallback cb;
+ TALER_EXCHANGE_DepositGetCallback cb;
/**
* Closure for @a cb.
@@ -89,7 +89,7 @@ struct TALER_EXCHANGE_TrackTransactionHandle
*/
static int
verify_deposit_wtid_signature_ok (const struct
- TALER_EXCHANGE_TrackTransactionHandle *dwh,
+ TALER_EXCHANGE_DepositGetHandle *dwh,
const json_t *json,
struct TALER_ExchangePublicKeyP *exchange_pub)
{
@@ -134,7 +134,7 @@ verify_deposit_wtid_signature_ok (const struct
* Function called when we're done processing the
* HTTP /track/transaction request.
*
- * @param cls the `struct TALER_EXCHANGE_TrackTransactionHandle`
+ * @param cls the `struct TALER_EXCHANGE_DepositGetHandle`
* @param response_code HTTP response code, 0 on error
* @param response parsed JSON result, NULL on error
*/
@@ -143,7 +143,7 @@ handle_deposit_wtid_finished (void *cls,
long response_code,
const void *response)
{
- struct TALER_EXCHANGE_TrackTransactionHandle *dwh = cls;
+ struct TALER_EXCHANGE_DepositGetHandle *dwh = cls;
const struct TALER_WireTransferIdentifierRawP *wtid = NULL;
struct GNUNET_TIME_Absolute execution_time = GNUNET_TIME_UNIT_FOREVER_ABS;
const struct TALER_Amount *coin_contribution = NULL;
@@ -247,7 +247,7 @@ handle_deposit_wtid_finished (void *cls,
wtid,
execution_time,
coin_contribution);
- TALER_EXCHANGE_track_transaction_cancel (dwh);
+ TALER_EXCHANGE_deposits_get_cancel (dwh);
}
@@ -264,21 +264,21 @@ handle_deposit_wtid_finished (void *cls,
* @param cb_cls closure for @a cb
* @return handle to abort request
*/
-struct TALER_EXCHANGE_TrackTransactionHandle *
-TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange,
- const struct
- TALER_MerchantPrivateKeyP *merchant_priv,
- const struct GNUNET_HashCode *h_wire,
- const struct
- GNUNET_HashCode *h_contract_terms,
- const struct
- TALER_CoinSpendPublicKeyP *coin_pub,
- TALER_EXCHANGE_TrackTransactionCallback cb,
- void *cb_cls)
+struct TALER_EXCHANGE_DepositGetHandle *
+TALER_EXCHANGE_deposits_get (struct TALER_EXCHANGE_Handle *exchange,
+ const struct
+ TALER_MerchantPrivateKeyP *merchant_priv,
+ const struct GNUNET_HashCode *h_wire,
+ const struct
+ GNUNET_HashCode *h_contract_terms,
+ const struct
+ TALER_CoinSpendPublicKeyP *coin_pub,
+ TALER_EXCHANGE_DepositGetCallback cb,
+ void *cb_cls)
{
struct TALER_DepositTrackPS dtp;
struct TALER_MerchantSignatureP merchant_sig;
- struct TALER_EXCHANGE_TrackTransactionHandle *dwh;
+ struct TALER_EXCHANGE_DepositGetHandle *dwh;
struct GNUNET_CURL_Context *ctx;
CURL *eh;
char arg_str[(sizeof (struct TALER_CoinSpendPublicKeyP)
@@ -354,7 +354,7 @@ TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange,
msig_str);
}
- dwh = GNUNET_new (struct TALER_EXCHANGE_TrackTransactionHandle);
+ dwh = GNUNET_new (struct TALER_EXCHANGE_DepositGetHandle);
dwh->exchange = exchange;
dwh->cb = cb;
dwh->cb_cls = cb_cls;
@@ -384,9 +384,9 @@ TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange,
* @param dwh the wire deposits request handle
*/
void
-TALER_EXCHANGE_track_transaction_cancel (struct
- TALER_EXCHANGE_TrackTransactionHandle *
- dwh)
+TALER_EXCHANGE_deposits_get_cancel (struct
+ TALER_EXCHANGE_DepositGetHandle *
+ dwh)
{
if (NULL != dwh->job)
{
diff --git a/src/lib/exchange_api_track_transfer.c b/src/lib/exchange_api_track_transfer.c
@@ -34,7 +34,7 @@
/**
* @brief A /track/transfer Handle
*/
-struct TALER_EXCHANGE_TrackTransferHandle
+struct TALER_EXCHANGE_TransfersGetHandle
{
/**
@@ -55,7 +55,7 @@ struct TALER_EXCHANGE_TrackTransferHandle
/**
* Function to call with the result.
*/
- TALER_EXCHANGE_TrackTransferCallback cb;
+ TALER_EXCHANGE_TransfersGetCallback cb;
/**
* Closure for @a cb.
@@ -81,7 +81,7 @@ struct TALER_EXCHANGE_TrackTransferHandle
*/
static int
check_track_transfer_response_ok (struct
- TALER_EXCHANGE_TrackTransferHandle *wdh,
+ TALER_EXCHANGE_TransfersGetHandle *wdh,
const json_t *json)
{
json_t *details_j;
@@ -241,7 +241,7 @@ check_track_transfer_response_ok (struct
details);
}
GNUNET_JSON_parse_free (spec);
- TALER_EXCHANGE_track_transfer_cancel (wdh);
+ TALER_EXCHANGE_transfers_get_cancel (wdh);
return GNUNET_OK;
}
@@ -250,7 +250,7 @@ check_track_transfer_response_ok (struct
* Function called when we're done processing the
* HTTP /track/transfer request.
*
- * @param cls the `struct TALER_EXCHANGE_TrackTransferHandle`
+ * @param cls the `struct TALER_EXCHANGE_TransfersGetHandle`
* @param response_code HTTP response code, 0 on error
* @param response parsed JSON result, NULL on error
*/
@@ -259,7 +259,7 @@ handle_track_transfer_finished (void *cls,
long response_code,
const void *response)
{
- struct TALER_EXCHANGE_TrackTransferHandle *wdh = cls;
+ struct TALER_EXCHANGE_TransfersGetHandle *wdh = cls;
const json_t *j = response;
wdh->job = NULL;
@@ -311,7 +311,7 @@ handle_track_transfer_finished (void *cls,
NULL,
NULL,
0, NULL);
- TALER_EXCHANGE_track_transfer_cancel (wdh);
+ TALER_EXCHANGE_transfers_get_cancel (wdh);
}
@@ -325,14 +325,14 @@ handle_track_transfer_finished (void *cls,
* @param cb_cls closure for @a cb
* @return handle to cancel operation
*/
-struct TALER_EXCHANGE_TrackTransferHandle *
-TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange,
- const struct
- TALER_WireTransferIdentifierRawP *wtid,
- TALER_EXCHANGE_TrackTransferCallback cb,
- void *cb_cls)
+struct TALER_EXCHANGE_TransfersGetHandle *
+TALER_EXCHANGE_transfers_get (struct TALER_EXCHANGE_Handle *exchange,
+ const struct
+ TALER_WireTransferIdentifierRawP *wtid,
+ TALER_EXCHANGE_TransfersGetCallback cb,
+ void *cb_cls)
{
- struct TALER_EXCHANGE_TrackTransferHandle *wdh;
+ struct TALER_EXCHANGE_TransfersGetHandle *wdh;
struct GNUNET_CURL_Context *ctx;
CURL *eh;
char arg_str[sizeof (struct TALER_WireTransferIdentifierRawP) * 2 + 32];
@@ -344,7 +344,7 @@ TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange,
return NULL;
}
- wdh = GNUNET_new (struct TALER_EXCHANGE_TrackTransferHandle);
+ wdh = GNUNET_new (struct TALER_EXCHANGE_TransfersGetHandle);
wdh->exchange = exchange;
wdh->cb = cb;
wdh->cb_cls = cb_cls;
@@ -384,8 +384,8 @@ TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange,
* @param wdh the wire deposits request handle
*/
void
-TALER_EXCHANGE_track_transfer_cancel (struct
- TALER_EXCHANGE_TrackTransferHandle *wdh)
+TALER_EXCHANGE_transfers_get_cancel (struct
+ TALER_EXCHANGE_TransfersGetHandle *wdh)
{
if (NULL != wdh->job)
{
diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c
@@ -55,7 +55,7 @@ struct TALER_EXCHANGE_WireHandle
/**
* Function to call with the result.
*/
- TALER_EXCHANGE_WireResultCallback cb;
+ TALER_EXCHANGE_WireCallback cb;
/**
* Closure for @a cb.
@@ -388,7 +388,7 @@ handle_wire_finished (void *cls,
*/
struct TALER_EXCHANGE_WireHandle *
TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange,
- TALER_EXCHANGE_WireResultCallback wire_cb,
+ TALER_EXCHANGE_WireCallback wire_cb,
void *wire_cb_cls)
{
struct TALER_EXCHANGE_WireHandle *wh;
diff --git a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c
@@ -227,8 +227,8 @@ deposit_confirmation_run (void *cls,
&exchange_sig));
keys = TALER_EXCHANGE_get_keys (dcs->is->exchange);
GNUNET_assert (NULL != keys);
- spk = TALER_EXCHANGE_get_exchange_signing_key_info (keys,
- exchange_pub);
+ spk = TALER_EXCHANGE_get_signing_key_info (keys,
+ exchange_pub);
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_contract_terms (deposit_cmd,
diff --git a/src/testing/testing_api_cmd_status.c b/src/testing/testing_api_cmd_status.c
@@ -41,7 +41,7 @@ struct StatusState
/**
* Handle to the "reserve status" operation.
*/
- struct TALER_EXCHANGE_ReserveStatusHandle *rsh;
+ struct TALER_EXCHANGE_ReservesGetHandle *rsh;
/**
* Expected reserve balance.
@@ -169,10 +169,10 @@ status_run (void *cls,
TALER_TESTING_interpreter_fail (is);
return;
}
- ss->rsh = TALER_EXCHANGE_reserve_status (is->exchange,
- reserve_pubp,
- &reserve_status_cb,
- ss);
+ ss->rsh = TALER_EXCHANGE_reserves_get (is->exchange,
+ reserve_pubp,
+ &reserve_status_cb,
+ ss);
}
@@ -195,7 +195,7 @@ status_cleanup (void *cls,
"Command %u (%s) did not complete\n",
ss->is->ip,
cmd->label);
- TALER_EXCHANGE_reserve_status_cancel (ss->rsh);
+ TALER_EXCHANGE_reserves_get_cancel (ss->rsh);
ss->rsh = NULL;
}
GNUNET_free (ss);
diff --git a/src/testing/testing_api_cmd_track.c b/src/testing/testing_api_cmd_track.c
@@ -64,7 +64,7 @@ struct TrackTransactionState
/**
* Handle to the "track transaction" pending operation.
*/
- struct TALER_EXCHANGE_TrackTransactionHandle *tth;
+ struct TALER_EXCHANGE_DepositGetHandle *tth;
/**
* Interpreter state.
@@ -124,7 +124,7 @@ struct TrackTransferState
/**
* Handle to a pending "track transfer" operation.
*/
- struct TALER_EXCHANGE_TrackTransferHandle *tth;
+ struct TALER_EXCHANGE_TransfersGetHandle *tth;
/**
* Interpreter state.
@@ -327,13 +327,13 @@ track_transaction_run (void *cls,
return;
}
- tts->tth = TALER_EXCHANGE_track_transaction (is->exchange,
- merchant_priv,
- &h_wire_details,
- &h_contract_terms,
- &coin_pub,
- &deposit_wtid_cb,
- tts);
+ tts->tth = TALER_EXCHANGE_deposits_get (is->exchange,
+ merchant_priv,
+ &h_wire_details,
+ &h_contract_terms,
+ &coin_pub,
+ &deposit_wtid_cb,
+ tts);
GNUNET_assert (NULL != tts->tth);
}
@@ -357,7 +357,7 @@ track_transaction_cleanup (void *cls,
"Command %u (%s) did not complete\n",
tts->is->ip,
cmd->label);
- TALER_EXCHANGE_track_transaction_cancel (tts->tth);
+ TALER_EXCHANGE_deposits_get_cancel (tts->tth);
tts->tth = NULL;
}
GNUNET_free (tts);
@@ -453,7 +453,7 @@ track_transfer_cleanup (void *cls,
"Command %u (%s) did not complete\n",
tts->is->ip,
cmd->label);
- TALER_EXCHANGE_track_transfer_cancel (tts->tth);
+ TALER_EXCHANGE_transfers_get_cancel (tts->tth);
tts->tth = NULL;
}
GNUNET_free (tts);
@@ -709,10 +709,10 @@ track_transfer_run (void *cls,
}
GNUNET_assert (NULL != wtid_ptr);
}
- tts->tth = TALER_EXCHANGE_track_transfer (is->exchange,
- wtid_ptr,
- &track_transfer_cb,
- tts);
+ tts->tth = TALER_EXCHANGE_transfers_get (is->exchange,
+ wtid_ptr,
+ &track_transfer_cb,
+ tts);
GNUNET_assert (NULL != tts->tth);
}
diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c
@@ -80,7 +80,7 @@ struct WithdrawState
/**
* Withdraw handle (while operation is running).
*/
- struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
+ struct TALER_EXCHANGE_WithdrawHandle *wsh;
/**
* Task scheduled to try later.
@@ -280,12 +280,12 @@ withdraw_run (void *cls,
* would free the old one. */
ws->pk = TALER_EXCHANGE_copy_denomination_key (dpk);
}
- ws->wsh = TALER_EXCHANGE_reserve_withdraw (is->exchange,
- ws->pk,
- rp,
- &ws->ps,
- &reserve_withdraw_cb,
- ws);
+ ws->wsh = TALER_EXCHANGE_withdraw (is->exchange,
+ ws->pk,
+ rp,
+ &ws->ps,
+ &reserve_withdraw_cb,
+ ws);
if (NULL == ws->wsh)
{
GNUNET_break (0);
@@ -313,7 +313,7 @@ withdraw_cleanup (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Command %s did not complete\n",
cmd->label);
- TALER_EXCHANGE_reserve_withdraw_cancel (ws->wsh);
+ TALER_EXCHANGE_withdraw_cancel (ws->wsh);
ws->wsh = NULL;
}
if (NULL != ws->retry_task)