LCOV - code coverage report
Current view: top level - lib - exchange_api_deposit.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 0 202 0.0 %
Date: 2022-08-25 06:15:09 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    This file is part of TALER
       3             :    Copyright (C) 2014-2021 Taler Systems SA
       4             : 
       5             :    TALER is free software; you can redistribute it and/or modify it under the
       6             :    terms of the GNU General Public License as published by the Free Software
       7             :    Foundation; either version 3, or (at your option) any later version.
       8             : 
       9             :    TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10             :    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11             :    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12             : 
      13             :    You should have received a copy of the GNU General Public License along with
      14             :    TALER; see the file COPYING.  If not, see
      15             :    <http://www.gnu.org/licenses/>
      16             :  */
      17             : /**
      18             :  * @file lib/exchange_api_deposit.c
      19             :  * @brief Implementation of the /deposit request of the exchange's HTTP API
      20             :  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
      21             :  * @author Christian Grothoff
      22             :  */
      23             : #include "platform.h"
      24             : #include <jansson.h>
      25             : #include <microhttpd.h> /* just for HTTP status codes */
      26             : #include <gnunet/gnunet_util_lib.h>
      27             : #include <gnunet/gnunet_json_lib.h>
      28             : #include <gnunet/gnunet_curl_lib.h>
      29             : #include "taler_json_lib.h"
      30             : #include "taler_auditor_service.h"
      31             : #include "taler_exchange_service.h"
      32             : #include "exchange_api_common.h"
      33             : #include "exchange_api_handle.h"
      34             : #include "taler_signatures.h"
      35             : #include "exchange_api_curl_defaults.h"
      36             : 
      37             : 
      38             : /**
      39             :  * 1:#AUDITOR_CHANCE is the probability that we report deposits
      40             :  * to the auditor.
      41             :  *
      42             :  * 20==5% of going to auditor. This is possibly still too high, but set
      43             :  * deliberately this high for testing
      44             :  */
      45             : #define AUDITOR_CHANCE 20
      46             : 
      47             : /**
      48             :  * @brief A Deposit Handle
      49             :  */
      50             : struct TALER_EXCHANGE_DepositHandle
      51             : {
      52             : 
      53             :   /**
      54             :    * The connection to exchange this request handle will use
      55             :    */
      56             :   struct TALER_EXCHANGE_Handle *exchange;
      57             : 
      58             :   /**
      59             :    * The url for this request.
      60             :    */
      61             :   char *url;
      62             : 
      63             :   /**
      64             :    * Context for #TEH_curl_easy_post(). Keeps the data that must
      65             :    * persist for Curl to make the upload.
      66             :    */
      67             :   struct TALER_CURL_PostContext ctx;
      68             : 
      69             :   /**
      70             :    * Handle for the request.
      71             :    */
      72             :   struct GNUNET_CURL_Job *job;
      73             : 
      74             :   /**
      75             :    * Function to call with the result.
      76             :    */
      77             :   TALER_EXCHANGE_DepositResultCallback cb;
      78             : 
      79             :   /**
      80             :    * Closure for @a cb.
      81             :    */
      82             :   void *cb_cls;
      83             : 
      84             :   /**
      85             :    * Details about the contract.
      86             :    */
      87             :   struct TALER_EXCHANGE_DepositContractDetail dcd;
      88             : 
      89             :   /**
      90             :    * Details about the coin.
      91             :    */
      92             :   struct TALER_EXCHANGE_CoinDepositDetail cdd;
      93             : 
      94             :   /**
      95             :    * Hash of the merchant's wire details.
      96             :    */
      97             :   struct TALER_MerchantWireHashP h_wire;
      98             : 
      99             :   /**
     100             :    * Hash over the extensions, or all zero.
     101             :    */
     102             :   struct TALER_ExtensionContractHashP h_extensions;
     103             : 
     104             :   /**
     105             :    * Time when this confirmation was generated / when the exchange received
     106             :    * the deposit request.
     107             :    */
     108             :   struct GNUNET_TIME_Timestamp exchange_timestamp;
     109             : 
     110             :   /**
     111             :    * Exchange signature, set for #auditor_cb.
     112             :    */
     113             :   struct TALER_ExchangeSignatureP exchange_sig;
     114             : 
     115             :   /**
     116             :    * Exchange signing public key, set for #auditor_cb.
     117             :    */
     118             :   struct TALER_ExchangePublicKeyP exchange_pub;
     119             : 
     120             :   /**
     121             :    * Chance that we will inform the auditor about the deposit
     122             :    * is 1:n, where the value of this field is "n".
     123             :    */
     124             :   unsigned int auditor_chance;
     125             : 
     126             : };
     127             : 
     128             : 
     129             : /**
     130             :  * Function called for each auditor to give us a chance to possibly
     131             :  * launch a deposit confirmation interaction.
     132             :  *
     133             :  * @param cls closure
     134             :  * @param ah handle to the auditor
     135             :  * @param auditor_pub public key of the auditor
     136             :  * @return NULL if no deposit confirmation interaction was launched
     137             :  */
     138             : static struct TEAH_AuditorInteractionEntry *
     139           0 : auditor_cb (void *cls,
     140             :             struct TALER_AUDITOR_Handle *ah,
     141             :             const struct TALER_AuditorPublicKeyP *auditor_pub)
     142             : {
     143           0 :   struct TALER_EXCHANGE_DepositHandle *dh = cls;
     144             :   const struct TALER_EXCHANGE_Keys *key_state;
     145             :   const struct TALER_EXCHANGE_SigningPublicKey *spk;
     146             :   struct TEAH_AuditorInteractionEntry *aie;
     147             :   struct TALER_Amount amount_without_fee;
     148             :   const struct TALER_EXCHANGE_DenomPublicKey *dki;
     149             : 
     150           0 :   if (0 !=
     151           0 :       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
     152             :                                 dh->auditor_chance))
     153             :   {
     154           0 :     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     155             :                 "Not providing deposit confirmation to auditor\n");
     156           0 :     return NULL;
     157             :   }
     158           0 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     159             :               "Will provide deposit confirmation to auditor `%s'\n",
     160             :               TALER_B2S (auditor_pub));
     161           0 :   key_state = TALER_EXCHANGE_get_keys (dh->exchange);
     162           0 :   dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
     163           0 :                                                      &dh->cdd.h_denom_pub);
     164           0 :   GNUNET_assert (NULL != dki);
     165           0 :   spk = TALER_EXCHANGE_get_signing_key_info (key_state,
     166           0 :                                              &dh->exchange_pub);
     167           0 :   if (NULL == spk)
     168             :   {
     169           0 :     GNUNET_break_op (0);
     170           0 :     return NULL;
     171             :   }
     172           0 :   GNUNET_assert (0 <=
     173             :                  TALER_amount_subtract (&amount_without_fee,
     174             :                                         &dh->cdd.amount,
     175             :                                         &dki->fees.deposit));
     176           0 :   aie = GNUNET_new (struct TEAH_AuditorInteractionEntry);
     177           0 :   aie->dch = TALER_AUDITOR_deposit_confirmation (
     178             :     ah,
     179           0 :     &dh->h_wire,
     180           0 :     &dh->h_extensions,
     181           0 :     &dh->dcd.h_contract_terms,
     182             :     dh->exchange_timestamp,
     183             :     dh->dcd.wire_deadline,
     184             :     dh->dcd.refund_deadline,
     185             :     &amount_without_fee,
     186           0 :     &dh->cdd.coin_pub,
     187           0 :     &dh->dcd.merchant_pub,
     188           0 :     &dh->exchange_pub,
     189           0 :     &dh->exchange_sig,
     190             :     &key_state->master_pub,
     191             :     spk->valid_from,
     192             :     spk->valid_until,
     193             :     spk->valid_legal,
     194             :     &spk->master_sig,
     195             :     &TEAH_acc_confirmation_cb,
     196             :     aie);
     197           0 :   return aie;
     198             : }
     199             : 
     200             : 
     201             : /**
     202             :  * Function called when we're done processing the
     203             :  * HTTP /deposit request.
     204             :  *
     205             :  * @param cls the `struct TALER_EXCHANGE_DepositHandle`
     206             :  * @param response_code HTTP response code, 0 on error
     207             :  * @param response parsed JSON result, NULL on error
     208             :  */
     209             : static void
     210           0 : handle_deposit_finished (void *cls,
     211             :                          long response_code,
     212             :                          const void *response)
     213             : {
     214           0 :   struct TALER_EXCHANGE_DepositHandle *dh = cls;
     215           0 :   const json_t *j = response;
     216           0 :   struct TALER_EXCHANGE_DepositResult dr = {
     217             :     .hr.reply = j,
     218           0 :     .hr.http_status = (unsigned int) response_code
     219             :   };
     220             :   const struct TALER_EXCHANGE_Keys *keys;
     221             : 
     222           0 :   dh->job = NULL;
     223           0 :   keys = TALER_EXCHANGE_get_keys (dh->exchange);
     224           0 :   switch (response_code)
     225             :   {
     226           0 :   case 0:
     227           0 :     dr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     228           0 :     break;
     229           0 :   case MHD_HTTP_OK:
     230             :     {
     231             :       const struct TALER_EXCHANGE_Keys *key_state;
     232             :       struct GNUNET_JSON_Specification spec[] = {
     233           0 :         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
     234             :                                      &dh->exchange_sig),
     235           0 :         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
     236             :                                      &dh->exchange_pub),
     237           0 :         GNUNET_JSON_spec_mark_optional (
     238             :           GNUNET_JSON_spec_string ("transaction_base_url",
     239             :                                    &dr.details.success.transaction_base_url),
     240             :           NULL),
     241           0 :         GNUNET_JSON_spec_timestamp ("exchange_timestamp",
     242             :                                     &dh->exchange_timestamp),
     243           0 :         GNUNET_JSON_spec_end ()
     244             :       };
     245             :       struct TALER_Amount amount_without_fee;
     246             :       const struct TALER_EXCHANGE_DenomPublicKey *dki;
     247             : 
     248           0 :       if (GNUNET_OK !=
     249           0 :           GNUNET_JSON_parse (j,
     250             :                              spec,
     251             :                              NULL, NULL))
     252             :       {
     253           0 :         GNUNET_break_op (0);
     254           0 :         dr.hr.http_status = 0;
     255           0 :         dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
     256           0 :         break;
     257             :       }
     258           0 :       key_state = TALER_EXCHANGE_get_keys (dh->exchange);
     259           0 :       dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
     260           0 :                                                          &dh->cdd.h_denom_pub);
     261           0 :       GNUNET_assert (NULL != dki);
     262           0 :       if (GNUNET_OK !=
     263           0 :           TALER_EXCHANGE_test_signing_key (key_state,
     264           0 :                                            &dh->exchange_pub))
     265             :       {
     266           0 :         GNUNET_break_op (0);
     267           0 :         dr.hr.http_status = 0;
     268           0 :         dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
     269           0 :         break;
     270             :       }
     271           0 :       GNUNET_assert (0 <=
     272             :                      TALER_amount_subtract (&amount_without_fee,
     273             :                                             &dh->cdd.amount,
     274             :                                             &dki->fees.deposit));
     275             : 
     276           0 :       if (GNUNET_OK !=
     277           0 :           TALER_exchange_online_deposit_confirmation_verify (
     278           0 :             &dh->dcd.h_contract_terms,
     279           0 :             &dh->h_wire,
     280           0 :             &dh->h_extensions,
     281             :             dh->exchange_timestamp,
     282             :             dh->dcd.wire_deadline,
     283             :             dh->dcd.refund_deadline,
     284             :             &amount_without_fee,
     285           0 :             &dh->cdd.coin_pub,
     286           0 :             &dh->dcd.merchant_pub,
     287           0 :             &dh->exchange_pub,
     288           0 :             &dh->exchange_sig))
     289             :       {
     290           0 :         GNUNET_break_op (0);
     291           0 :         dr.hr.http_status = 0;
     292           0 :         dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
     293           0 :         break;
     294             :       }
     295             : 
     296           0 :       TEAH_get_auditors_for_dc (dh->exchange,
     297             :                                 &auditor_cb,
     298             :                                 dh);
     299             :     }
     300           0 :     dr.details.success.exchange_sig = &dh->exchange_sig;
     301           0 :     dr.details.success.exchange_pub = &dh->exchange_pub;
     302           0 :     dr.details.success.deposit_timestamp = dh->exchange_timestamp;
     303           0 :     break;
     304           0 :   case MHD_HTTP_BAD_REQUEST:
     305             :     /* This should never happen, either us or the exchange is buggy
     306             :        (or API version conflict); just pass JSON reply to the application */
     307           0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     308           0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     309           0 :     break;
     310           0 :   case MHD_HTTP_FORBIDDEN:
     311           0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     312           0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     313             :     /* Nothing really to verify, exchange says one of the signatures is
     314             :        invalid; as we checked them, this should never happen, we
     315             :        should pass the JSON reply to the application */
     316           0 :     break;
     317           0 :   case MHD_HTTP_NOT_FOUND:
     318           0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     319           0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     320             :     /* Nothing really to verify, this should never
     321             :        happen, we should pass the JSON reply to the application */
     322           0 :     break;
     323           0 :   case MHD_HTTP_CONFLICT:
     324             :     {
     325             :       const struct TALER_EXCHANGE_Keys *key_state;
     326             :       const struct TALER_EXCHANGE_DenomPublicKey *dki;
     327             : 
     328           0 :       key_state = TALER_EXCHANGE_get_keys (dh->exchange);
     329           0 :       dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
     330           0 :                                                          &dh->cdd.h_denom_pub);
     331           0 :       GNUNET_assert (NULL != dki);
     332           0 :       dr.hr.ec = TALER_JSON_get_error_code (j);
     333           0 :       dr.hr.hint = TALER_JSON_get_error_hint (j);
     334           0 :       if (GNUNET_OK !=
     335           0 :           TALER_EXCHANGE_check_coin_conflict_ (
     336             :             keys,
     337             :             j,
     338             :             dki,
     339           0 :             &dh->cdd.coin_pub,
     340           0 :             &dh->cdd.coin_sig,
     341           0 :             &dh->cdd.amount))
     342             :       {
     343           0 :         GNUNET_break_op (0);
     344           0 :         dr.hr.http_status = 0;
     345           0 :         dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
     346           0 :         break;
     347             :       }
     348             :     }
     349           0 :     break;
     350           0 :   case MHD_HTTP_GONE:
     351             :     /* could happen if denomination was revoked */
     352             :     /* Note: one might want to check /keys for revocation
     353             :        signature here, alas tricky in case our /keys
     354             :        is outdated => left to clients */
     355           0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     356           0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     357           0 :     break;
     358           0 :   case MHD_HTTP_INTERNAL_SERVER_ERROR:
     359           0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     360           0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     361             :     /* Server had an internal issue; we should retry, but this API
     362             :        leaves this to the application */
     363           0 :     break;
     364           0 :   default:
     365             :     /* unexpected response code */
     366           0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     367           0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     368           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     369             :                 "Unexpected response code %u/%d for exchange deposit\n",
     370             :                 (unsigned int) response_code,
     371             :                 dr.hr.ec);
     372           0 :     GNUNET_break_op (0);
     373           0 :     break;
     374             :   }
     375           0 :   dh->cb (dh->cb_cls,
     376             :           &dr);
     377           0 :   TALER_EXCHANGE_deposit_cancel (dh);
     378           0 : }
     379             : 
     380             : 
     381             : struct TALER_EXCHANGE_DepositHandle *
     382           0 : TALER_EXCHANGE_deposit (
     383             :   struct TALER_EXCHANGE_Handle *exchange,
     384             :   const struct TALER_EXCHANGE_DepositContractDetail *dcd,
     385             :   const struct TALER_EXCHANGE_CoinDepositDetail *cdd,
     386             :   TALER_EXCHANGE_DepositResultCallback cb,
     387             :   void *cb_cls,
     388             :   enum TALER_ErrorCode *ec)
     389             : {
     390             :   const struct TALER_EXCHANGE_Keys *key_state;
     391             :   struct TALER_EXCHANGE_DepositHandle *dh;
     392             :   struct GNUNET_CURL_Context *ctx;
     393             :   json_t *deposit_obj;
     394             :   CURL *eh;
     395             :   const struct TALER_EXCHANGE_DenomPublicKey *dki;
     396             :   struct TALER_Amount amount_without_fee;
     397             :   char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
     398             : 
     399           0 :   GNUNET_assert (GNUNET_YES ==
     400             :                  TEAH_handle_is_ready (exchange));
     401           0 :   if (GNUNET_TIME_timestamp_cmp (dcd->refund_deadline,
     402             :                                  >,
     403             :                                  dcd->wire_deadline))
     404             :   {
     405           0 :     GNUNET_break_op (0);
     406           0 :     *ec = TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE;
     407           0 :     return NULL;
     408             :   }
     409             :   {
     410             :     char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
     411             :     char *end;
     412             : 
     413           0 :     end = GNUNET_STRINGS_data_to_string (
     414           0 :       &cdd->coin_pub,
     415             :       sizeof (struct TALER_CoinSpendPublicKeyP),
     416             :       pub_str,
     417             :       sizeof (pub_str));
     418           0 :     *end = '\0';
     419           0 :     GNUNET_snprintf (arg_str,
     420             :                      sizeof (arg_str),
     421             :                      "/coins/%s/deposit",
     422             :                      pub_str);
     423             :   }
     424           0 :   key_state = TALER_EXCHANGE_get_keys (exchange);
     425           0 :   dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
     426             :                                                      &cdd->h_denom_pub);
     427           0 :   if (NULL == dki)
     428             :   {
     429           0 :     *ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
     430           0 :     GNUNET_break_op (0);
     431           0 :     return NULL;
     432             :   }
     433           0 :   if (0 >
     434           0 :       TALER_amount_subtract (&amount_without_fee,
     435             :                              &cdd->amount,
     436             :                              &dki->fees.deposit))
     437             :   {
     438           0 :     *ec = TALER_EC_EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT;
     439           0 :     GNUNET_break_op (0);
     440           0 :     return NULL;
     441             :   }
     442           0 :   dh = GNUNET_new (struct TALER_EXCHANGE_DepositHandle);
     443           0 :   dh->auditor_chance = AUDITOR_CHANCE;
     444           0 :   dh->exchange = exchange;
     445           0 :   dh->cb = cb;
     446           0 :   dh->cb_cls = cb_cls;
     447           0 :   dh->cdd = *cdd;
     448           0 :   dh->dcd = *dcd;
     449           0 :   if (NULL != dcd->extension_details)
     450           0 :     TALER_deposit_extension_hash (dcd->extension_details,
     451             :                                   &dh->h_extensions);
     452           0 :   TALER_merchant_wire_signature_hash (dcd->merchant_payto_uri,
     453             :                                       &dcd->wire_salt,
     454             :                                       &dh->h_wire);
     455           0 :   if (GNUNET_OK !=
     456           0 :       TALER_EXCHANGE_verify_deposit_signature_ (dcd,
     457           0 :                                                 &dh->h_extensions,
     458           0 :                                                 &dh->h_wire,
     459             :                                                 cdd,
     460             :                                                 dki))
     461             :   {
     462           0 :     *ec = TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID;
     463           0 :     GNUNET_break_op (0);
     464           0 :     GNUNET_free (dh);
     465           0 :     return NULL;
     466             :   }
     467           0 :   dh->url = TEAH_path_to_url (exchange,
     468             :                               arg_str);
     469           0 :   if (NULL == dh->url)
     470             :   {
     471           0 :     GNUNET_break (0);
     472           0 :     *ec = TALER_EC_GENERIC_ALLOCATION_FAILURE;
     473           0 :     GNUNET_free (dh->url);
     474           0 :     GNUNET_free (dh);
     475           0 :     return NULL;
     476             :   }
     477             : 
     478           0 :   deposit_obj = GNUNET_JSON_PACK (
     479             :     TALER_JSON_pack_amount ("contribution",
     480             :                             &cdd->amount),
     481             :     GNUNET_JSON_pack_string ("merchant_payto_uri",
     482             :                              dcd->merchant_payto_uri),
     483             :     GNUNET_JSON_pack_data_auto ("wire_salt",
     484             :                                 &dcd->wire_salt),
     485             :     GNUNET_JSON_pack_data_auto ("h_contract_terms",
     486             :                                 &dcd->h_contract_terms),
     487             :     GNUNET_JSON_pack_allow_null (
     488             :       GNUNET_JSON_pack_data_auto ("h_age_commitment",
     489             :                                   &cdd->h_age_commitment)),
     490             :     GNUNET_JSON_pack_data_auto ("denom_pub_hash",
     491             :                                 &cdd->h_denom_pub),
     492             :     TALER_JSON_pack_denom_sig ("ub_sig",
     493             :                                &cdd->denom_sig),
     494             :     GNUNET_JSON_pack_timestamp ("timestamp",
     495             :                                 dcd->timestamp),
     496             :     GNUNET_JSON_pack_data_auto ("merchant_pub",
     497             :                                 &dcd->merchant_pub),
     498             :     GNUNET_JSON_pack_allow_null (
     499             :       GNUNET_JSON_pack_timestamp ("refund_deadline",
     500             :                                   dcd->refund_deadline)),
     501             :     GNUNET_JSON_pack_timestamp ("wire_transfer_deadline",
     502             :                                 dcd->wire_deadline),
     503             :     GNUNET_JSON_pack_data_auto ("coin_sig",
     504             :                                 &cdd->coin_sig));
     505           0 :   GNUNET_assert (NULL != deposit_obj);
     506           0 :   eh = TALER_EXCHANGE_curl_easy_get_ (dh->url);
     507           0 :   if ( (NULL == eh) ||
     508             :        (GNUNET_OK !=
     509           0 :         TALER_curl_easy_post (&dh->ctx,
     510             :                               eh,
     511             :                               deposit_obj)) )
     512             :   {
     513           0 :     *ec = TALER_EC_GENERIC_CURL_ALLOCATION_FAILURE;
     514           0 :     GNUNET_break (0);
     515           0 :     if (NULL != eh)
     516           0 :       curl_easy_cleanup (eh);
     517           0 :     json_decref (deposit_obj);
     518           0 :     GNUNET_free (dh->url);
     519           0 :     GNUNET_free (dh);
     520           0 :     return NULL;
     521             :   }
     522           0 :   json_decref (deposit_obj);
     523           0 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     524             :               "URL for deposit: `%s'\n",
     525             :               dh->url);
     526           0 :   ctx = TEAH_handle_to_context (exchange);
     527           0 :   dh->job = GNUNET_CURL_job_add2 (ctx,
     528             :                                   eh,
     529           0 :                                   dh->ctx.headers,
     530             :                                   &handle_deposit_finished,
     531             :                                   dh);
     532           0 :   return dh;
     533             : }
     534             : 
     535             : 
     536             : void
     537           0 : TALER_EXCHANGE_deposit_force_dc (struct TALER_EXCHANGE_DepositHandle *deposit)
     538             : {
     539           0 :   deposit->auditor_chance = 1;
     540           0 : }
     541             : 
     542             : 
     543             : void
     544           0 : TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit)
     545             : {
     546           0 :   if (NULL != deposit->job)
     547             :   {
     548           0 :     GNUNET_CURL_job_cancel (deposit->job);
     549           0 :     deposit->job = NULL;
     550             :   }
     551           0 :   GNUNET_free (deposit->url);
     552           0 :   TALER_curl_easy_post_finished (&deposit->ctx);
     553           0 :   GNUNET_free (deposit);
     554           0 : }
     555             : 
     556             : 
     557             : /* end of exchange_api_deposit.c */

Generated by: LCOV version 1.14