gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-exchange] 03/07: refactor /track logic towards new s


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] 03/07: refactor /track logic towards new structure
Date: Mon, 19 Jun 2017 21:18:01 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

commit beea8eb383a4292b976c6c5d7356e6863e1adcbe
Author: Christian Grothoff <address@hidden>
AuthorDate: Mon Jun 19 18:06:51 2017 +0200

    refactor /track logic towards new structure
---
 src/exchange/taler-exchange-httpd_db.c             | 413 ---------------------
 src/exchange/taler-exchange-httpd_db.h             |  55 ---
 src/exchange/taler-exchange-httpd_responses.c      | 131 -------
 src/exchange/taler-exchange-httpd_responses.h      |  84 -----
 .../taler-exchange-httpd_track_transaction.c       | 204 ++++++++++
 src/exchange/taler-exchange-httpd_track_transfer.c | 379 +++++++++++++++++++
 6 files changed, 583 insertions(+), 683 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_db.c 
b/src/exchange/taler-exchange-httpd_db.c
index bfe2112..bed2a7f 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -1209,417 +1209,4 @@ TEH_DB_execute_admin_add_incoming (struct 
MHD_Connection *connection,
 }
 
 
-/**
- * Closure for #handle_transaction_data.
- */
-struct WtidTransactionContext
-{
-
-  /**
-   * 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;
-
-  /**
-   * 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)
- * @param merchant_pub public key of the merchant (should be same for all 
callbacks with the same @e cls)
- * @param wire_method which wire plugin was used
- * @param h_wire hash of wire transfer details of the merchant (should be same 
for all callbacks with the same @e cls)
- * @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 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 char *wire_method,
-                         const struct GNUNET_HashCode *h_wire,
-                         struct GNUNET_TIME_Absolute exec_time,
-                         const struct GNUNET_HashCode *h_contract_terms,
-                         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;
-
-  if (GNUNET_SYSERR == ctx->is_valid)
-    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 = GNUNET_strdup (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 != memcmp (&ctx->merchant_pub,
-                       merchant_pub,
-                       sizeof (struct TALER_MerchantPublicKeyP))) ||
-         (0 != strcmp (wire_method,
-                       ctx->wire_method)) ||
-         (0 != memcmp (&ctx->h_wire,
-                       h_wire,
-                       sizeof (struct GNUNET_HashCode))) )
-    {
-      GNUNET_break (0);
-      ctx->is_valid = GNUNET_SYSERR;
-      return;
-    }
-    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.
- *
- * @param connection the MHD connection to handle
- * @param wtid wire transfer identifier to resolve
- * @return MHD result code
- */
-int
-TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
-                               const struct TALER_WireTransferIdentifierRawP 
*wtid)
-{
-  int ret;
-  struct WtidTransactionContext ctx;
-  struct TALER_EXCHANGEDB_Session *session;
-  struct TEH_TrackTransferDetail *wdd;
-  struct GNUNET_TIME_Absolute wire_fee_start_date;
-  struct GNUNET_TIME_Absolute wire_fee_end_date;
-  struct TALER_Amount wire_fee;
-  struct TALER_MasterSignatureP wire_fee_master_sig;
-
-  if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
-  {
-    GNUNET_break (0);
-    return TEH_RESPONSE_reply_internal_db_error (connection,
-                                                TALER_EC_DB_SETUP_FAILED);
-  }
-  ctx.is_valid = GNUNET_NO;
-  ctx.wdd_head = NULL;
-  ctx.wdd_tail = NULL;
-  ctx.wire_method = NULL;
-  ret = TEH_plugin->lookup_wire_transfer (TEH_plugin->cls,
-                                          session,
-                                          wtid,
-                                          &handle_transaction_data,
-                                          &ctx);
-  if (GNUNET_SYSERR == ret)
-  {
-    GNUNET_break (0);
-    ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                               
TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED);
-    goto cleanup;
-  }
-  if (GNUNET_SYSERR == ctx.is_valid)
-  {
-    GNUNET_break (0);
-    ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                               
TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT);
-    goto cleanup;
-  }
-  if (GNUNET_NO == ctx.is_valid)
-  {
-    ret = TEH_RESPONSE_reply_arg_unknown (connection,
-                                         
TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
-                                          "wtid");
-    goto cleanup;
-  }
-  if (GNUNET_OK !=
-      TEH_plugin->get_wire_fee (TEH_plugin->cls,
-                                session,
-                                ctx.wire_method,
-                                ctx.exec_time,
-                                &wire_fee_start_date,
-                                &wire_fee_end_date,
-                                &wire_fee,
-                                &wire_fee_master_sig))
-  {
-    GNUNET_break (0);
-    ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                               
TALER_EC_TRACK_TRANSFER_WIRE_FEE_NOT_FOUND);
-    goto cleanup;
-  }
-  if (GNUNET_OK !=
-      TALER_amount_subtract (&ctx.total,
-                             &ctx.total,
-                             &wire_fee))
-  {
-    GNUNET_break (0);
-    ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                               
TALER_EC_TRACK_TRANSFER_WIRE_FEE_INCONSISTENT);
-    goto cleanup;
-  }
-  ret = TEH_RESPONSE_reply_track_transfer_details (connection,
-                                                   &ctx.total,
-                                                   &ctx.merchant_pub,
-                                                   &ctx.h_wire,
-                                                   &wire_fee,
-                                                   ctx.exec_time,
-                                                   ctx.wdd_head);
- cleanup:
-  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);
-  return ret;
-}
-
-
-/**
- * Closure for #handle_wtid_data.
- */
-struct DepositWtidContext
-{
-
-  /**
-   * Where should we send the reply?
-   */
-  struct MHD_Connection *connection;
-
-  /**
-   * Hash of the proposal data we are looking up.
-   */
-  struct GNUNET_HashCode h_contract_terms;
-
-  /**
-   * Hash of the wire transfer details we are looking up.
-   */
-  struct GNUNET_HashCode h_wire;
-
-  /**
-   * Public key we are looking up.
-   */
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-
-  /**
-   * MHD result code to return.
-   */
-  int res;
-};
-
-
-/**
- * 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;
-  struct TALER_Amount coin_delta;
-
-  if (NULL == wtid)
-  {
-    ctx->res = TEH_RESPONSE_reply_transfer_pending (ctx->connection,
-                                                    execution_time);
-  }
-  else
-  {
-    if (GNUNET_SYSERR ==
-        TALER_amount_subtract (&coin_delta,
-                               coin_contribution,
-                               coin_fee))
-    {
-      GNUNET_break (0);
-      ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection,
-                                                      
TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT);
-    }
-    else
-    {
-      ctx->res = TEH_RESPONSE_reply_track_transaction (ctx->connection,
-                                                       &ctx->h_contract_terms,
-                                                       &ctx->h_wire,
-                                                       &ctx->coin_pub,
-                                                       &coin_delta,
-                                                       wtid,
-                                                       execution_time);
-    }
-  }
-}
-
-
-/**
- * Execute a "/track/transaction".  Returns the transfer information
- * associated with the given deposit.
- *
- * @param connection the MHD connection to handle
- * @param h_contract_terms hash of the proposal data
- * @param h_wire hash of the wire details
- * @param coin_pub public key of the coin to link
- * @param merchant_pub public key of the merchant
- * @return MHD result code
- */
-int
-TEH_DB_execute_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_MerchantPublicKeyP 
*merchant_pub)
-{
-  int ret;
-  struct DepositWtidContext ctx;
-  struct TALER_EXCHANGEDB_Session *session;
-
-  if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
-  {
-    GNUNET_break (0);
-    return TEH_RESPONSE_reply_internal_db_error (connection,
-                                                TALER_EC_DB_SETUP_FAILED);
-  }
-  ctx.connection = connection;
-  ctx.h_contract_terms = *h_contract_terms;
-  ctx.h_wire = *h_wire;
-  ctx.coin_pub = *coin_pub;
-  ctx.res = GNUNET_SYSERR;
-  ret = TEH_plugin->wire_lookup_deposit_wtid (TEH_plugin->cls,
-                                              session,
-                                             h_contract_terms,
-                                             h_wire,
-                                             coin_pub,
-                                             merchant_pub,
-                                             &handle_wtid_data,
-                                             &ctx);
-  if (GNUNET_SYSERR == ret)
-  {
-    GNUNET_break (0);
-    GNUNET_break (GNUNET_SYSERR == ctx.res);
-    return TEH_RESPONSE_reply_internal_db_error (connection,
-                                                
TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED);
-  }
-  if (GNUNET_NO == ret)
-  {
-    GNUNET_break (GNUNET_SYSERR == ctx.res);
-    return TEH_RESPONSE_reply_transaction_unknown (connection,
-                                                  
TALER_EC_TRACK_TRANSACTION_NOT_FOUND);
-  }
-  if (GNUNET_SYSERR == ctx.res)
-  {
-    GNUNET_break (0);
-    return TEH_RESPONSE_reply_internal_error (connection,
-                                             
TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR,
-                                              "bug resolving deposit wtid");
-  }
-  return ctx.res;
-}
-
-
 /* end of taler-exchange-httpd_db.c */
diff --git a/src/exchange/taler-exchange-httpd_db.h 
b/src/exchange/taler-exchange-httpd_db.h
index 5e2a27a..662f034 100644
--- a/src/exchange/taler-exchange-httpd_db.h
+++ b/src/exchange/taler-exchange-httpd_db.h
@@ -197,60 +197,5 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection 
*connection,
                                    const json_t *transfer_details);
 
 
-/**
- * Execute a "/track/transfer".  Returns the transaction information
- * associated with the given wire transfer identifier.
- *
- * @param connection the MHD connection to handle
- * @param wtid wire transfer identifier to resolve
- * @return MHD result code
- */
-int
-TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
-                               const struct TALER_WireTransferIdentifierRawP 
*wtid);
-
-
-/**
- * Execute a "/track/transaction".  Returns the transfer information
- * associated with the given deposit.
- *
- * @param connection the MHD connection to handle
- * @param h_contract_terms hash of the contract
- * @param h_wire hash of the wire details
- * @param coin_pub public key of the coin to link
- * @param merchant_pub public key of the merchant
- * @return MHD result code
- */
-int
-TEH_DB_execute_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_MerchantPublicKeyP 
*merchant_pub);
-
-
-/**
- * Execute a "/payback".  The validity of the coin and signature have
- * already been checked.  The database must now check that the coin is
- * not (double) spent, and execute the transaction (record details,
- * generate success or failure response).
- *
- * @param connection the MHD connection to handle
- * @param coin information about the coin
- * @param value how much are coins of the @a coin's denomination worth?
- * @param h_blind blinded coin to use for the lookup
- * @param coin_blind blinding factor used (for later verification by the 
auditor)
- * @param coin_sig signature of the coin
- * @return MHD result code
- */
-int
-TEH_DB_execute_payback (struct MHD_Connection *connection,
-                        const struct TALER_CoinPublicInfo *coin,
-                        const struct TALER_Amount *value,
-                        const struct GNUNET_HashCode *h_blind,
-                        const struct TALER_DenominationBlindingKeyP 
*coin_blind,
-                        const struct TALER_CoinSpendSignatureP *coin_sig);
-
-
 #endif
 /* TALER_EXCHANGE_HTTPD_DB_H */
diff --git a/src/exchange/taler-exchange-httpd_responses.c 
b/src/exchange/taler-exchange-httpd_responses.c
index 7dab61e..286572f 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -1163,135 +1163,4 @@ TEH_RESPONSE_reply_transfer_pending (struct 
MHD_Connection *connection,
 }
 
 
-/**
- * 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
- */
-int
-TEH_RESPONSE_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);
-  TEH_KS_sign (&cw.purpose,
-               &pub,
-               &sig);
-  return TEH_RESPONSE_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));
-}
-
-
-/**
- * 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
- */
-int
-TEH_RESPONSE_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);
-  TEH_KS_sign (&wdp.purpose,
-               &pub,
-               &sig);
-  return TEH_RESPONSE_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));
-}
-
-
-
 /* end of taler-exchange-httpd_responses.c */
diff --git a/src/exchange/taler-exchange-httpd_responses.h 
b/src/exchange/taler-exchange-httpd_responses.h
index 8a51d8d..5a52be3 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -301,90 +301,6 @@ TEH_RESPONSE_reply_transfer_pending (struct MHD_Connection 
*connection,
 
 
 /**
- * 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 proposal data
- * @param h_wire hash of wire account details
- * @param coin_pub public key of the coin
- * @param coin_contribution contribution of this coin to the total amount 
transferred
- * @param wtid raw wire transfer identifier
- * @param exec_time execution time of the wire transfer
- * @return MHD result code
- */
-int
-TEH_RESPONSE_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);
-
-
-/**
- * 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
- */
-int
-TEH_RESPONSE_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);
-
-
-/**
  * Send a confirmation response to a "/refresh/melt" request.
  *
  * @param connection the connection to send the response to
diff --git a/src/exchange/taler-exchange-httpd_track_transaction.c 
b/src/exchange/taler-exchange-httpd_track_transaction.c
index 9b2aaec..b617021 100644
--- a/src/exchange/taler-exchange-httpd_track_transaction.c
+++ b/src/exchange/taler-exchange-httpd_track_transaction.c
@@ -25,11 +25,215 @@
 #include <pthread.h>
 #include "taler_signatures.h"
 #include "taler-exchange-httpd_parsing.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.  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
+ */
+int
+TEH_RESPONSE_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);
+  TEH_KS_sign (&cw.purpose,
+               &pub,
+               &sig);
+  return TEH_RESPONSE_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
+{
+
+  /**
+   * Where should we send the reply?
+   */
+  struct MHD_Connection *connection;
+
+  /**
+   * Hash of the proposal data we are looking up.
+   */
+  struct GNUNET_HashCode h_contract_terms;
+
+  /**
+   * Hash of the wire transfer details we are looking up.
+   */
+  struct GNUNET_HashCode h_wire;
+
+  /**
+   * Public key we are looking up.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * MHD result code to return.
+   */
+  int res;
+};
+
+
+/**
+ * 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;
+  struct TALER_Amount coin_delta;
+
+  if (NULL == wtid)
+  {
+    ctx->res = TEH_RESPONSE_reply_transfer_pending (ctx->connection,
+                                                    execution_time);
+  }
+  else
+  {
+    if (GNUNET_SYSERR ==
+        TALER_amount_subtract (&coin_delta,
+                               coin_contribution,
+                               coin_fee))
+    {
+      GNUNET_break (0);
+      ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection,
+                                                      
TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT);
+    }
+    else
+    {
+      ctx->res = TEH_RESPONSE_reply_track_transaction (ctx->connection,
+                                                       &ctx->h_contract_terms,
+                                                       &ctx->h_wire,
+                                                       &ctx->coin_pub,
+                                                       &coin_delta,
+                                                       wtid,
+                                                       execution_time);
+    }
+  }
+}
+
+
+/**
+ * Execute a "/track/transaction".  Returns the transfer information
+ * associated with the given deposit.
+ *
+ * @param connection the MHD connection to handle
+ * @param h_contract_terms hash of the proposal data
+ * @param h_wire hash of the wire details
+ * @param coin_pub public key of the coin to link
+ * @param merchant_pub public key of the merchant
+ * @return MHD result code
+ */
+int
+TEH_DB_execute_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_MerchantPublicKeyP 
*merchant_pub)
+{
+  int ret;
+  struct DepositWtidContext ctx;
+  struct TALER_EXCHANGEDB_Session *session;
+
+  if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
+  {
+    GNUNET_break (0);
+    return TEH_RESPONSE_reply_internal_db_error (connection,
+                                                TALER_EC_DB_SETUP_FAILED);
+  }
+  ctx.connection = connection;
+  ctx.h_contract_terms = *h_contract_terms;
+  ctx.h_wire = *h_wire;
+  ctx.coin_pub = *coin_pub;
+  ctx.res = GNUNET_SYSERR;
+  ret = TEH_plugin->wire_lookup_deposit_wtid (TEH_plugin->cls,
+                                              session,
+                                             h_contract_terms,
+                                             h_wire,
+                                             coin_pub,
+                                             merchant_pub,
+                                             &handle_wtid_data,
+                                             &ctx);
+  if (GNUNET_SYSERR == ret)
+  {
+    GNUNET_break (0);
+    GNUNET_break (GNUNET_SYSERR == ctx.res);
+    return TEH_RESPONSE_reply_internal_db_error (connection,
+                                                
TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED);
+  }
+  if (GNUNET_NO == ret)
+  {
+    GNUNET_break (GNUNET_SYSERR == ctx.res);
+    return TEH_RESPONSE_reply_transaction_unknown (connection,
+                                                  
TALER_EC_TRACK_TRANSACTION_NOT_FOUND);
+  }
+  if (GNUNET_SYSERR == ctx.res)
+  {
+    GNUNET_break (0);
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                             
TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR,
+                                              "bug resolving deposit wtid");
+  }
+  return ctx.res;
+}
+
+
+/**
  * Check the merchant signature, and if it is valid,
  * return the wire transfer identifier.
  *
diff --git a/src/exchange/taler-exchange-httpd_track_transfer.c 
b/src/exchange/taler-exchange-httpd_track_transfer.c
index f54df28..1b9dd9f 100644
--- a/src/exchange/taler-exchange-httpd_track_transfer.c
+++ b/src/exchange/taler-exchange-httpd_track_transfer.c
@@ -25,11 +25,390 @@
 #include <pthread.h>
 #include "taler_signatures.h"
 #include "taler-exchange-httpd_parsing.h"
+#include "taler-exchange-httpd_keystate.h"
 #include "taler-exchange-httpd_track_transfer.h"
 #include "taler-exchange-httpd_responses.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
+ */
+int
+TEH_RESPONSE_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);
+  TEH_KS_sign (&wdp.purpose,
+               &pub,
+               &sig);
+  return TEH_RESPONSE_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
+{
+
+  /**
+   * 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;
+
+  /**
+   * 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)
+ * @param merchant_pub public key of the merchant (should be same for all 
callbacks with the same @e cls)
+ * @param wire_method which wire plugin was used
+ * @param h_wire hash of wire transfer details of the merchant (should be same 
for all callbacks with the same @e cls)
+ * @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 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 char *wire_method,
+                         const struct GNUNET_HashCode *h_wire,
+                         struct GNUNET_TIME_Absolute exec_time,
+                         const struct GNUNET_HashCode *h_contract_terms,
+                         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;
+
+  if (GNUNET_SYSERR == ctx->is_valid)
+    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 = GNUNET_strdup (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 != memcmp (&ctx->merchant_pub,
+                       merchant_pub,
+                       sizeof (struct TALER_MerchantPublicKeyP))) ||
+         (0 != strcmp (wire_method,
+                       ctx->wire_method)) ||
+         (0 != memcmp (&ctx->h_wire,
+                       h_wire,
+                       sizeof (struct GNUNET_HashCode))) )
+    {
+      GNUNET_break (0);
+      ctx->is_valid = GNUNET_SYSERR;
+      return;
+    }
+    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.
+ *
+ * @param connection the MHD connection to handle
+ * @param wtid wire transfer identifier to resolve
+ * @return MHD result code
+ */
+int
+TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
+                               const struct TALER_WireTransferIdentifierRawP 
*wtid)
+{
+  int ret;
+  struct WtidTransactionContext ctx;
+  struct TALER_EXCHANGEDB_Session *session;
+  struct TEH_TrackTransferDetail *wdd;
+  struct GNUNET_TIME_Absolute wire_fee_start_date;
+  struct GNUNET_TIME_Absolute wire_fee_end_date;
+  struct TALER_Amount wire_fee;
+  struct TALER_MasterSignatureP wire_fee_master_sig;
+
+  if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
+  {
+    GNUNET_break (0);
+    return TEH_RESPONSE_reply_internal_db_error (connection,
+                                                TALER_EC_DB_SETUP_FAILED);
+  }
+  ctx.is_valid = GNUNET_NO;
+  ctx.wdd_head = NULL;
+  ctx.wdd_tail = NULL;
+  ctx.wire_method = NULL;
+  ret = TEH_plugin->lookup_wire_transfer (TEH_plugin->cls,
+                                          session,
+                                          wtid,
+                                          &handle_transaction_data,
+                                          &ctx);
+  if (GNUNET_SYSERR == ret)
+  {
+    GNUNET_break (0);
+    ret = TEH_RESPONSE_reply_internal_db_error (connection,
+                                               
TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED);
+    goto cleanup;
+  }
+  if (GNUNET_SYSERR == ctx.is_valid)
+  {
+    GNUNET_break (0);
+    ret = TEH_RESPONSE_reply_internal_db_error (connection,
+                                               
TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT);
+    goto cleanup;
+  }
+  if (GNUNET_NO == ctx.is_valid)
+  {
+    ret = TEH_RESPONSE_reply_arg_unknown (connection,
+                                         
TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
+                                          "wtid");
+    goto cleanup;
+  }
+  if (GNUNET_OK !=
+      TEH_plugin->get_wire_fee (TEH_plugin->cls,
+                                session,
+                                ctx.wire_method,
+                                ctx.exec_time,
+                                &wire_fee_start_date,
+                                &wire_fee_end_date,
+                                &wire_fee,
+                                &wire_fee_master_sig))
+  {
+    GNUNET_break (0);
+    ret = TEH_RESPONSE_reply_internal_db_error (connection,
+                                               
TALER_EC_TRACK_TRANSFER_WIRE_FEE_NOT_FOUND);
+    goto cleanup;
+  }
+  if (GNUNET_OK !=
+      TALER_amount_subtract (&ctx.total,
+                             &ctx.total,
+                             &wire_fee))
+  {
+    GNUNET_break (0);
+    ret = TEH_RESPONSE_reply_internal_db_error (connection,
+                                               
TALER_EC_TRACK_TRANSFER_WIRE_FEE_INCONSISTENT);
+    goto cleanup;
+  }
+  ret = TEH_RESPONSE_reply_track_transfer_details (connection,
+                                                   &ctx.total,
+                                                   &ctx.merchant_pub,
+                                                   &ctx.h_wire,
+                                                   &wire_fee,
+                                                   ctx.exec_time,
+                                                   ctx.wdd_head);
+ cleanup:
+  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);
+  return ret;
+}
+
+
+/**
  * Handle a "/track/transfer" request.
  *
  * @param rh context of the handler

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]