From 12cff1b4439ab5dcc26fcf79e19518ae1bdce069 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 18 Sep 2023 18:59:53 +0200 Subject: remove coin and reserve histories from exchange replies --- src/lib/Makefile.am | 1 - src/lib/exchange_api_batch_deposit.c | 39 +-- src/lib/exchange_api_common.c | 210 ++------------ src/lib/exchange_api_common.h | 2 - src/lib/exchange_api_melt.c | 16 -- src/lib/exchange_api_purse_create_with_deposit.c | 105 +------ src/lib/exchange_api_purse_deposit.c | 111 +------- src/lib/exchange_api_recoup.c | 14 - src/lib/exchange_api_recoup_refresh.c | 33 +-- src/lib/exchange_api_refund.c | 314 --------------------- src/lib/exchange_api_reserves_history.c | 65 ++--- src/lib/exchange_api_reserves_open.c | 28 +- src/lib/exchange_api_reserves_status.c | 336 ----------------------- src/lib/exchange_api_withdraw2.c | 109 -------- 14 files changed, 55 insertions(+), 1328 deletions(-) delete mode 100644 src/lib/exchange_api_reserves_status.c (limited to 'src/lib') diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 6ff8e2371..ff5d3b801 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -73,7 +73,6 @@ libtalerexchange_la_SOURCES = \ exchange_api_reserves_get_attestable.c \ exchange_api_reserves_history.c \ exchange_api_reserves_open.c \ - exchange_api_reserves_status.c \ exchange_api_stefan.c \ exchange_api_transfers_get.c \ exchange_api_withdraw.c \ diff --git a/src/lib/exchange_api_batch_deposit.c b/src/lib/exchange_api_batch_deposit.c index 3aea22b64..273b25e85 100644 --- a/src/lib/exchange_api_batch_deposit.c +++ b/src/lib/exchange_api_batch_deposit.c @@ -464,14 +464,11 @@ handle_deposit_finished (void *cls, break; case MHD_HTTP_CONFLICT: { - struct TALER_CoinSpendPublicKeyP coin_pub; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("coin_pub", - &coin_pub), + &dr->details.conflict.coin_pub), GNUNET_JSON_spec_end () }; - const struct TALER_EXCHANGE_DenomPublicKey *dki; - bool found = false; if (GNUNET_OK != GNUNET_JSON_parse (j, @@ -483,40 +480,6 @@ handle_deposit_finished (void *cls, dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - for (unsigned int i = 0; inum_cdds; i++) - { - if (0 != - GNUNET_memcmp (&coin_pub, - &dh->cdds[i].coin_pub)) - continue; - dki = TALER_EXCHANGE_get_denomination_key_by_hash (dh->keys, - &dh->cdds[i]. - h_denom_pub); - GNUNET_assert (NULL != dki); - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_conflict_ ( - dh->keys, - j, - dki, - &dh->cdds[i].coin_pub, - &dh->cdds[i].coin_sig, - &dh->cdds[i].amount)) - { - GNUNET_break_op (0); - dr->hr.http_status = 0; - dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - found = true; - break; - } - if (! found) - { - GNUNET_break_op (0); - dr->hr.http_status = 0; - dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } dr->hr.ec = TALER_JSON_get_error_code (j); dr->hr.hint = TALER_JSON_get_error_hint (j); } diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index 609a2f7ef..3ad880171 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -478,59 +478,6 @@ parse_merge (struct TALER_EXCHANGE_ReserveHistoryEntry *rh, } -/** - * Parse "history" reserve history entry. - * - * @param[in,out] rh entry to parse - * @param uc our context - * @param transaction the transaction to parse - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_history (struct TALER_EXCHANGE_ReserveHistoryEntry *rh, - struct HistoryParseContext *uc, - const json_t *transaction) -{ - struct GNUNET_JSON_Specification history_spec[] = { - GNUNET_JSON_spec_fixed_auto ("reserve_sig", - &rh->details.history_details.reserve_sig), - GNUNET_JSON_spec_timestamp ("request_timestamp", - &rh->details.history_details.request_timestamp), - GNUNET_JSON_spec_end () - }; - - rh->type = TALER_EXCHANGE_RTT_HISTORY; - if (GNUNET_OK != - GNUNET_JSON_parse (transaction, - history_spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_wallet_reserve_history_verify ( - rh->details.history_details.request_timestamp, - &rh->amount, - uc->reserve_pub, - &rh->details.history_details.reserve_sig)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (0 > - TALER_amount_add (uc->total_out, - uc->total_out, - &rh->amount)) - { - /* overflow in history already!? inconceivable! Bad exchange! */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - /** * Parse "open" reserve open entry. * @@ -666,7 +613,6 @@ TALER_EXCHANGE_parse_reserve_history ( { "RECOUP", &parse_recoup }, { "MERGE", &parse_merge }, { "CLOSING", &parse_closing }, - { "HISTORY", &parse_history }, { "OPEN", &parse_open }, { "CLOSE", &parse_close }, { NULL, NULL } @@ -771,8 +717,6 @@ TALER_EXCHANGE_free_reserve_history ( break; case TALER_EXCHANGE_RTT_CLOSING: break; - case TALER_EXCHANGE_RTT_HISTORY: - break; case TALER_EXCHANGE_RTT_MERGE: break; case TALER_EXCHANGE_RTT_OPEN: @@ -1867,66 +1811,6 @@ TALER_EXCHANGE_check_purse_econtract_conflict_ ( } -enum GNUNET_GenericReturnValue -TALER_EXCHANGE_check_coin_amount_conflict_ ( - const struct TALER_EXCHANGE_Keys *keys, - const json_t *proof, - struct TALER_CoinSpendPublicKeyP *coin_pub, - struct TALER_Amount *remaining) -{ - const json_t *history; - struct TALER_Amount total; - struct TALER_DenominationHashP h_denom_pub; - const struct TALER_EXCHANGE_DenomPublicKey *dki; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("coin_pub", - coin_pub), - GNUNET_JSON_spec_fixed_auto ("h_denom_pub", - &h_denom_pub), - GNUNET_JSON_spec_array_const ("history", - &history), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (proof, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - dki = TALER_EXCHANGE_get_denomination_key_by_hash ( - keys, - &h_denom_pub); - if (NULL == dki) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_EXCHANGE_verify_coin_history (dki, - coin_pub, - history, - &total)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (0 > - TALER_amount_subtract (remaining, - &dki->value, - &total)) - { - /* Strange 'proof': coin was double-spent - before our transaction?! */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - /** * Verify that @a coin_sig does NOT appear in * the history of @a proof and thus whatever transaction @@ -1937,6 +1821,7 @@ TALER_EXCHANGE_check_coin_amount_conflict_ ( * @param coin_sig signature that must not be in @a proof * @return #GNUNET_OK if @a coin_sig is not in @a proof */ +// FIXME: move to exchange_api_coin_history.c! enum GNUNET_GenericReturnValue TALER_EXCHANGE_check_coin_signature_conflict_ ( const json_t *proof, @@ -2011,13 +1896,25 @@ TALER_EXCHANGE_check_coin_denomination_conflict_ ( } +/** + * Check that the provided @a proof indeeds indicates + * a conflict for @a coin_pub. + * + * @param keys exchange keys + * @param proof provided conflict proof + * @param dk denomination of @a coin_pub that the client + * used + * @param coin_pub public key of the coin + * @param required balance required on the coin for the operation + * @return #GNUNET_OK if @a proof holds + */ +// FIXME: move to exchange_api_coin_history.c! enum GNUNET_GenericReturnValue TALER_EXCHANGE_check_coin_conflict_ ( const struct TALER_EXCHANGE_Keys *keys, const json_t *proof, const struct TALER_EXCHANGE_DenomPublicKey *dk, const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_Amount *required) { enum TALER_ErrorCode ec; @@ -2026,81 +1923,12 @@ TALER_EXCHANGE_check_coin_conflict_ ( switch (ec) { case TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS: - { - struct TALER_Amount left; - struct TALER_CoinSpendPublicKeyP pcoin_pub; - - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_amount_conflict_ ( - keys, - proof, - &pcoin_pub, - &left)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (0 != - GNUNET_memcmp (&pcoin_pub, - coin_pub)) - { - /* conflict is for a different coin! */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (-1 != - TALER_amount_cmp (&left, - required)) - { - /* Balance was sufficient after all; recoup MAY have still been possible */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_signature_conflict_ ( - proof, - coin_sig)) - { - /* Not a conflicting transaction: ours is included! */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - break; - } + /* Nothing to check anymore here, proof needs to be + checked in the GET /coins/$COIN_PUB handler */ + break; case TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY: - { - struct TALER_Amount left; - struct TALER_CoinSpendPublicKeyP pcoin_pub; - - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_amount_conflict_ ( - keys, - proof, - &pcoin_pub, - &left)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (0 != - GNUNET_memcmp (&pcoin_pub, - coin_pub)) - { - /* conflict is for a different coin! */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_denomination_conflict_ ( - proof, - &dk->h_key)) - { - /* Eh, same denomination, hence no conflict */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - break; - } + // FIXME: write check! + break; default: GNUNET_break_op (0); return GNUNET_SYSERR; diff --git a/src/lib/exchange_api_common.h b/src/lib/exchange_api_common.h index 1b9ddce34..0fcaac3f3 100644 --- a/src/lib/exchange_api_common.h +++ b/src/lib/exchange_api_common.h @@ -170,7 +170,6 @@ TALER_EXCHANGE_check_coin_signature_conflict_ ( * @param dk denomination of @a coin_pub that the client * used * @param coin_pub public key of the coin - * @param coin_sig signature over operation that conflicted * @param required balance required on the coin for the operation * @return #GNUNET_OK if @a proof holds */ @@ -180,7 +179,6 @@ TALER_EXCHANGE_check_coin_conflict_ ( const json_t *proof, const struct TALER_EXCHANGE_DenomPublicKey *dk, const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_Amount *required); diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index 7fbd2114c..ba4241dab 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -218,10 +218,8 @@ handle_melt_finished (void *cls, .hr.reply = j, .hr.http_status = (unsigned int) response_code }; - const struct TALER_EXCHANGE_Keys *keys; mh->job = NULL; - keys = mh->keys; switch (response_code) { case 0: @@ -254,20 +252,6 @@ handle_melt_finished (void *cls, case MHD_HTTP_CONFLICT: mr.hr.ec = TALER_JSON_get_error_code (j); mr.hr.hint = TALER_JSON_get_error_hint (j); - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_conflict_ ( - keys, - j, - mh->dki, - &mh->coin_pub, - &mh->coin_sig, - &mh->md.melted_coin.melt_amount_with_fee)) - { - GNUNET_break_op (0); - mr.hr.http_status = 0; - mr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } break; case MHD_HTTP_FORBIDDEN: /* Nothing really to verify, exchange says one of the signatures is diff --git a/src/lib/exchange_api_purse_create_with_deposit.c b/src/lib/exchange_api_purse_create_with_deposit.c index 13874678a..c64beedec 100644 --- a/src/lib/exchange_api_purse_create_with_deposit.c +++ b/src/lib/exchange_api_purse_create_with_deposit.c @@ -277,107 +277,12 @@ handle_purse_create_deposit_finished (void *cls, } break; case TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS: - { - struct TALER_Amount left; - struct TALER_CoinSpendPublicKeyP pcoin_pub; - bool found = false; - - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_amount_conflict_ ( - keys, - j, - &pcoin_pub, - &left)) - { - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - for (unsigned int i = 0; inum_deposits; i++) - { - struct Deposit *deposit = &pch->deposits[i]; - - if (0 != GNUNET_memcmp (&pcoin_pub, - &deposit->coin_pub)) - continue; - if (-1 != - TALER_amount_cmp (&left, - &deposit->contribution)) - { - /* Balance was sufficient after all; operation MAY have still been possible */ - GNUNET_break_op (0); - continue; - } - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_signature_conflict_ ( - j, - &deposit->coin_sig)) - { - GNUNET_break_op (0); - continue; - } - found = true; - break; - } - if (! found) - { - /* conflict is for a different coin! */ - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - break; - } + /* Nothing to check anymore here, proof needs to be + checked in the GET /coins/$COIN_PUB handler */ + break; case TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY: - { - struct TALER_Amount left; - struct TALER_CoinSpendPublicKeyP pcoin_pub; - bool found = false; - - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_amount_conflict_ ( - keys, - j, - &pcoin_pub, - &left)) - { - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - for (unsigned int i = 0; inum_deposits; i++) - { - struct Deposit *deposit = &pch->deposits[i]; - - if (0 != - GNUNET_memcmp (&pcoin_pub, - &deposit->coin_pub)) - continue; - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_denomination_conflict_ ( - j, - &deposit->h_denom_pub)) - { - /* Eh, same denomination, hence no conflict */ - GNUNET_break_op (0); - continue; - } - found = true; - } - if (! found) - { - /* conflict is for a different coin! */ - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - /* meta data conflict is real! */ - break; - } + // FIXME: write check (add to exchange_api_common! */ + break; case TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA: { struct TALER_CoinSpendPublicKeyP coin_pub; diff --git a/src/lib/exchange_api_purse_deposit.c b/src/lib/exchange_api_purse_deposit.c index 7bb3b9517..7db2f34c7 100644 --- a/src/lib/exchange_api_purse_deposit.c +++ b/src/lib/exchange_api_purse_deposit.c @@ -297,114 +297,11 @@ handle_purse_deposit_finished (void *cls, break; } case TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS: - { - struct TALER_CoinSpendPublicKeyP coin_pub; - struct TALER_Amount remaining; - bool found = false; - const struct Coin *my_coin; - - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_amount_conflict_ ( - keys, - j, - &coin_pub, - &remaining)) - { - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - for (unsigned int i = 0; inum_deposits; i++) - { - if (0 == GNUNET_memcmp (&coin_pub, - &pch->coins[i].coin_pub)) - { - found = true; - my_coin = &pch->coins[i]; - break; - } - } - if (! found) - { - /* proof is about a coin we did not even deposit */ - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - if (1 == TALER_amount_cmp (&remaining, - &my_coin->contribution)) - { - /* transaction should have still fit */ - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_signature_conflict_ ( - j, - &my_coin->coin_sig)) - { - /* THIS transaction must not be in the conflicting history */ - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - /* everything OK, proof of double-spending was provided */ - break; - } + /* Nothing to check anymore here, proof needs to be + checked in the GET /coins/$COIN_PUB handler */ + break; case TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY: - { - struct TALER_CoinSpendPublicKeyP coin_pub; - struct TALER_Amount remaining; - bool found = false; - const struct Coin *my_coin; - - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_amount_conflict_ ( - keys, - j, - &coin_pub, - &remaining)) - { - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - for (unsigned int i = 0; inum_deposits; i++) - { - if (0 == GNUNET_memcmp (&coin_pub, - &pch->coins[i].coin_pub)) - { - found = true; - my_coin = &pch->coins[i]; - break; - } - } - if (! found) - { - /* proof is about a coin we did not even deposit */ - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_denomination_conflict_ ( - j, - &my_coin->h_denom_pub)) - { - /* no conflicting denomination detected */ - GNUNET_break_op (0); - dr.hr.http_status = 0; - dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - /* everything OK, proof of conflicting denomination was provided */ - break; - } + break; default: GNUNET_break_op (0); dr.hr.http_status = 0; diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c index e7daff165..cfd265f04 100644 --- a/src/lib/exchange_api_recoup.c +++ b/src/lib/exchange_api_recoup.c @@ -183,20 +183,6 @@ handle_recoup_finished (void *cls, rr.hr.http_status = 0; break; } - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_conflict_ ( - ph->keys, - j, - &ph->pk, - &ph->coin_pub, - &ph->coin_sig, - &min_key)) - { - GNUNET_break (0); - rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - rr.hr.http_status = 0; - break; - } break; } case MHD_HTTP_FORBIDDEN: diff --git a/src/lib/exchange_api_recoup_refresh.c b/src/lib/exchange_api_recoup_refresh.c index f5745deb0..0bcd44dec 100644 --- a/src/lib/exchange_api_recoup_refresh.c +++ b/src/lib/exchange_api_recoup_refresh.c @@ -183,36 +183,9 @@ handle_recoup_refresh_finished (void *cls, rrr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_CONFLICT: - { - struct TALER_Amount min_key; - - rrr.hr.ec = TALER_JSON_get_error_code (j); - rrr.hr.hint = TALER_JSON_get_error_hint (j); - if (GNUNET_OK != - TALER_EXCHANGE_get_min_denomination_ (ph->keys, - &min_key)) - { - GNUNET_break (0); - rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - rrr.hr.http_status = 0; - break; - } - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_conflict_ ( - ph->keys, - j, - &ph->pk, - &ph->coin_pub, - &ph->coin_sig, - &min_key)) - { - GNUNET_break (0); - rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - rrr.hr.http_status = 0; - break; - } - break; - } + rrr.hr.ec = TALER_JSON_get_error_code (j); + rrr.hr.hint = TALER_JSON_get_error_hint (j); + break; case MHD_HTTP_GONE: /* Kind of normal: the money was already sent to the merchant (it was too late for the refund). */ diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 3f12f28d6..7401bfe4f 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -157,307 +157,6 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh, } -/** - * Verify that the information in the "409 Conflict" response - * from the exchange is valid and indeed shows that the refund - * amount requested is too high. - * - * @param[in,out] rh refund handle (refund fee added) - * @param json json reply with the coin transaction history - * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not - */ -static enum GNUNET_GenericReturnValue -verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, - const json_t *json) -{ - const json_t *history; - struct TALER_DenominationHashP h_denom_pub; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("history", - &history), - GNUNET_JSON_spec_fixed_auto ("h_denom_pub", - &h_denom_pub), - GNUNET_JSON_spec_end () - }; - size_t len; - struct TALER_Amount dtotal; - bool have_deposit; - struct TALER_Amount rtotal; - bool have_refund; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - len = json_array_size (history); - if (0 == len) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - have_deposit = false; - have_refund = false; - for (size_t off = 0; offcoin_pub, - &sig)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if ( (0 != GNUNET_memcmp (&rh->h_contract_terms, - &h_contract_terms)) || - (0 != GNUNET_memcmp (&rh->merchant, - &merchant_pub)) ) - { - /* deposit information is about a different merchant/contract */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (have_deposit) - { - /* this cannot really happen, but we conservatively support it anyway */ - if (GNUNET_YES != - TALER_amount_cmp_currency (&amount, - &dtotal)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - GNUNET_break (0 <= - TALER_amount_add (&dtotal, - &dtotal, - &amount)); - } - else - { - dtotal = amount; - have_deposit = true; - } - } - else if (0 == strcasecmp (type, - "REFUND")) - { - struct TALER_MerchantSignatureP sig; - struct TALER_Amount refund_fee; - struct TALER_Amount sig_amount; - struct TALER_PrivateContractHashP h_contract_terms; - uint64_t rtransaction_id; - struct TALER_MerchantPublicKeyP merchant_pub; - struct GNUNET_JSON_Specification ispec[] = { - TALER_JSON_spec_amount_any ("refund_fee", - &refund_fee), - GNUNET_JSON_spec_fixed_auto ("merchant_sig", - &sig), - GNUNET_JSON_spec_fixed_auto ("h_contract_terms", - &h_contract_terms), - GNUNET_JSON_spec_fixed_auto ("merchant_pub", - &merchant_pub), - GNUNET_JSON_spec_uint64 ("rtransaction_id", - &rtransaction_id), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (transaction, - ispec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (0 > - TALER_amount_add (&sig_amount, - &refund_fee, - &amount)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_merchant_refund_verify (&rh->coin_pub, - &h_contract_terms, - rtransaction_id, - &sig_amount, - &merchant_pub, - &sig)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if ( (0 != GNUNET_memcmp (&rh->h_contract_terms, - &h_contract_terms)) || - (0 != GNUNET_memcmp (&rh->merchant, - &merchant_pub)) ) - { - /* refund is about a different merchant/contract */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (rtransaction_id == rh->rtransaction_id) - { - /* Eh, this shows either a dependency failure or idempotency, - but must not happen in a conflict reply. Fail! */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - if (have_refund) - { - if (GNUNET_YES != - TALER_amount_cmp_currency (&amount, - &rtotal)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - GNUNET_break (0 <= - TALER_amount_add (&rtotal, - &rtotal, - &amount)); - } - else - { - rtotal = amount; - have_refund = true; - } - } - else - { - /* unexpected type, new version on server? */ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected type `%s' in response for exchange refund\n", - type); - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - - if (have_refund) - { - if (0 > - TALER_amount_add (&rtotal, - &rtotal, - &rh->refund_amount)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - else - { - rtotal = rh->refund_amount; - have_refund = true; - } - if (! have_deposit) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (-1 != TALER_amount_cmp (&dtotal, - &rtotal)) - { - /* rtotal <= dtotal is fine, no conflict! */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - /* dtotal < rtotal: that's a conflict! */ - return GNUNET_OK; -} - - /** * Verify that the information on the "412 Dependency Failed" response * from the exchange is valid and indeed shows that there is a refund @@ -615,19 +314,6 @@ handle_refund_finished (void *cls, break; case MHD_HTTP_CONFLICT: /* Requested total refunds exceed deposited amount */ - if (GNUNET_OK != - verify_conflict_history_ok (rh, - j)) - { - GNUNET_break (0); - json_dumpf (j, - stderr, - JSON_INDENT (2)); - rr.hr.http_status = 0; - rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE; - rr.hr.hint = "conflict information provided by exchange is invalid"; - break; - } rr.hr.ec = TALER_JSON_get_error_code (j); rr.hr.hint = TALER_JSON_get_error_hint (j); break; diff --git a/src/lib/exchange_api_reserves_history.c b/src/lib/exchange_api_reserves_history.c index d4366eb37..c92fad5e8 100644 --- a/src/lib/exchange_api_reserves_history.c +++ b/src/lib/exchange_api_reserves_history.c @@ -64,25 +64,15 @@ struct TALER_EXCHANGE_ReservesHistoryHandle */ TALER_EXCHANGE_ReservesHistoryCallback cb; - /** - * Closure for @a cb. - */ - void *cb_cls; - /** * Public key of the reserve we are querying. */ struct TALER_ReservePublicKeyP reserve_pub; /** - * Our signature. - */ - struct TALER_ReserveSignatureP reserve_sig; - - /** - * When did we make the request. + * Closure for @a cb. */ - struct GNUNET_TIME_Timestamp ts; + void *cb_cls; }; @@ -103,9 +93,7 @@ handle_reserves_history_ok (struct TALER_EXCHANGE_ReservesHistoryHandle *rsh, unsigned int len; struct TALER_EXCHANGE_ReserveHistory rs = { .hr.reply = j, - .hr.http_status = MHD_HTTP_OK, - .ts = rsh->ts, - .reserve_sig = &rsh->reserve_sig + .hr.http_status = MHD_HTTP_OK }; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount_any ("balance", @@ -143,6 +131,7 @@ handle_reserves_history_ok (struct TALER_EXCHANGE_ReservesHistoryHandle *rsh, GNUNET_break_op (0); TALER_EXCHANGE_free_reserve_history (len, rhistory); + GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } if (NULL != rsh->cb) @@ -191,7 +180,6 @@ handle_reserves_history_finished (void *cls, handle_reserves_history_ok (rsh, j)) { - GNUNET_break_op (0); rs.hr.http_status = 0; rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; } @@ -216,11 +204,6 @@ handle_reserves_history_finished (void *cls, rs.hr.ec = TALER_JSON_get_error_code (j); rs.hr.hint = TALER_JSON_get_error_hint (j); break; - case MHD_HTTP_CONFLICT: - /* Insufficient balance to inquire for reserve history */ - rs.hr.ec = TALER_JSON_get_error_code (j); - rs.hr.hint = TALER_JSON_get_error_hint (j); - break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ @@ -254,18 +237,18 @@ TALER_EXCHANGE_reserves_history ( const char *url, struct TALER_EXCHANGE_Keys *keys, const struct TALER_ReservePrivateKeyP *reserve_priv, + uint64_t start_off, TALER_EXCHANGE_ReservesHistoryCallback cb, void *cb_cls) { struct TALER_EXCHANGE_ReservesHistoryHandle *rsh; CURL *eh; - char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32]; - const struct TALER_EXCHANGE_GlobalFee *gf; + char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 64]; + struct TALER_ReserveSignatureP reserve_sig; rsh = GNUNET_new (struct TALER_EXCHANGE_ReservesHistoryHandle); rsh->cb = cb; rsh->cb_cls = cb_cls; - rsh->ts = GNUNET_TIME_timestamp_get (); GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv, &rsh->reserve_pub.eddsa_pub); { @@ -278,10 +261,17 @@ TALER_EXCHANGE_reserves_history ( pub_str, sizeof (pub_str)); *end = '\0'; - GNUNET_snprintf (arg_str, - sizeof (arg_str), - "reserves/%s/history", - pub_str); + if (0 != start_off) + GNUNET_snprintf (arg_str, + sizeof (arg_str), + "reserves/%s/history?start=%llu", + pub_str, + (unsigned long long) start_off); + else + GNUNET_snprintf (arg_str, + sizeof (arg_str), + "reserves/%s/history", + pub_str); } rsh->url = TALER_url_join (url, arg_str, @@ -299,26 +289,13 @@ TALER_EXCHANGE_reserves_history ( GNUNET_free (rsh); return NULL; } - gf = TALER_EXCHANGE_get_global_fee (keys, - rsh->ts); - if (NULL == gf) - { - GNUNET_break_op (0); - curl_easy_cleanup (eh); - GNUNET_free (rsh->url); - GNUNET_free (rsh); - return NULL; - } - TALER_wallet_reserve_history_sign (rsh->ts, - &gf->fees.history, + TALER_wallet_reserve_history_sign (start_off, reserve_priv, - &rsh->reserve_sig); + &reserve_sig); { json_t *history_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_timestamp ("request_timestamp", - rsh->ts), GNUNET_JSON_pack_data_auto ("reserve_sig", - &rsh->reserve_sig)); + &reserve_sig)); if (GNUNET_OK != TALER_curl_easy_post (&rsh->post_ctx, diff --git a/src/lib/exchange_api_reserves_open.c b/src/lib/exchange_api_reserves_open.c index 536efdb10..36e435685 100644 --- a/src/lib/exchange_api_reserves_open.c +++ b/src/lib/exchange_api_reserves_open.c @@ -322,11 +322,9 @@ handle_reserves_open_finished (void *cls, case MHD_HTTP_CONFLICT: { const struct CoinData *cd = NULL; - struct TALER_CoinSpendPublicKeyP coin_pub; - const struct TALER_EXCHANGE_DenomPublicKey *dk; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("coin_pub", - &coin_pub), + &rs.details.conflict.coin_pub), GNUNET_JSON_spec_end () }; @@ -345,7 +343,7 @@ handle_reserves_open_finished (void *cls, { const struct CoinData *cdi = &roh->coins[i]; - if (0 == GNUNET_memcmp (&coin_pub, + if (0 == GNUNET_memcmp (&rs.details.conflict.coin_pub, &cdi->coin_pub)) { cd = cdi; @@ -359,28 +357,6 @@ handle_reserves_open_finished (void *cls, rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - dk = TALER_EXCHANGE_get_denomination_key_by_hash (roh->keys, - &cd->h_denom_pub); - if (NULL == dk) - { - GNUNET_break_op (0); - rs.hr.http_status = 0; - rs.hr.ec = TALER_EC_GENERIC_CLIENT_INTERNAL_ERROR; - break; - } - if (GNUNET_OK != - TALER_EXCHANGE_check_coin_conflict_ (roh->keys, - j, - dk, - &coin_pub, - &cd->coin_sig, - &cd->contribution)) - { - GNUNET_break_op (0); - rs.hr.http_status = 0; - rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } rs.hr.ec = TALER_JSON_get_error_code (j); rs.hr.hint = TALER_JSON_get_error_hint (j); break; diff --git a/src/lib/exchange_api_reserves_status.c b/src/lib/exchange_api_reserves_status.c deleted file mode 100644 index 2ea64e8aa..000000000 --- a/src/lib/exchange_api_reserves_status.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see - -*/ -/** - * @file lib/exchange_api_reserves_status.c - * @brief Implementation of the POST /reserves/$RESERVE_PUB/status requests - * @author Christian Grothoff - */ -#include "platform.h" -#include -#include /* just for HTTP status codes */ -#include -#include -#include -#include "taler_exchange_service.h" -#include "taler_json_lib.h" -#include "exchange_api_handle.h" -#include "taler_signatures.h" -#include "exchange_api_curl_defaults.h" - - -/** - * @brief A /reserves/$RID/status Handle - */ -struct TALER_EXCHANGE_ReservesStatusHandle -{ - - /** - * The keys of the exchange this request handle will use - */ - struct TALER_EXCHANGE_Keys *keys; - - /** - * The url for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Context for #TEH_curl_easy_post(). Keeps the data that must - * persist for Curl to make the upload. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Function to call with the result. - */ - TALER_EXCHANGE_ReservesStatusCallback cb; - - /** - * Public key of the reserve we are querying. - */ - struct TALER_ReservePublicKeyP reserve_pub; - - /** - * Closure for @a cb. - */ - void *cb_cls; - -}; - - -/** - * We received an #MHD_HTTP_OK status code. Handle the JSON - * response. - * - * @param rsh handle of the request - * @param j JSON response - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -handle_reserves_status_ok (struct TALER_EXCHANGE_ReservesStatusHandle *rsh, - const json_t *j) -{ - const json_t *history; - unsigned int len; - struct TALER_EXCHANGE_ReserveStatus rs = { - .hr.reply = j, - .hr.http_status = MHD_HTTP_OK - }; - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount_any ("balance", - &rs.details.ok.balance), - GNUNET_JSON_spec_array_const ("history", - &history), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (j, - spec, - NULL, - NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - len = json_array_size (history); - { - struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory; - - rhistory = GNUNET_new_array (len, - struct TALER_EXCHANGE_ReserveHistoryEntry); - if (GNUNET_OK != - TALER_EXCHANGE_parse_reserve_history (rsh->keys, - history, - &rsh->reserve_pub, - rs.details.ok.balance.currency, - &rs.details.ok.total_in, - &rs.details.ok.total_out, - len, - rhistory)) - { - GNUNET_break_op (0); - TALER_EXCHANGE_free_reserve_history (len, - rhistory); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; - } - if (NULL != rsh->cb) - { - rs.details.ok.history = rhistory; - rs.details.ok.history_len = len; - rsh->cb (rsh->cb_cls, - &rs); - rsh->cb = NULL; - } - TALER_EXCHANGE_free_reserve_history (len, - rhistory); - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP /reserves/$RID/status request. - * - * @param cls the `struct TALER_EXCHANGE_ReservesStatusHandle` - * @param response_code HTTP response code, 0 on error - * @param response parsed JSON result, NULL on error - */ -static void -handle_reserves_status_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_EXCHANGE_ReservesStatusHandle *rsh = cls; - const json_t *j = response; - struct TALER_EXCHANGE_ReserveStatus rs = { - .hr.reply = j, - .hr.http_status = (unsigned int) response_code - }; - - rsh->job = NULL; - switch (response_code) - { - case 0: - rs.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - if (GNUNET_OK != - handle_reserves_status_ok (rsh, - j)) - { - rs.hr.http_status = 0; - rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - } - break; - case MHD_HTTP_BAD_REQUEST: - /* This should never happen, either us or the exchange is buggy - (or API version conflict); just pass JSON reply to the application */ - GNUNET_break (0); - rs.hr.ec = TALER_JSON_get_error_code (j); - rs.hr.hint = TALER_JSON_get_error_hint (j); - break; - case MHD_HTTP_FORBIDDEN: - /* This should never happen, either us or the exchange is buggy - (or API version conflict); just pass JSON reply to the application */ - GNUNET_break (0); - rs.hr.ec = TALER_JSON_get_error_code (j); - rs.hr.hint = TALER_JSON_get_error_hint (j); - break; - case MHD_HTTP_NOT_FOUND: - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the application */ - rs.hr.ec = TALER_JSON_get_error_code (j); - rs.hr.hint = TALER_JSON_get_error_hint (j); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - /* Server had an internal issue; we should retry, but this API - leaves this to the application */ - rs.hr.ec = TALER_JSON_get_error_code (j); - rs.hr.hint = TALER_JSON_get_error_hint (j); - break; - default: - /* unexpected response code */ - GNUNET_break_op (0); - rs.hr.ec = TALER_JSON_get_error_code (j); - rs.hr.hint = TALER_JSON_get_error_hint (j); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for reserves status\n", - (unsigned int) response_code, - (int) rs.hr.ec); - break; - } - if (NULL != rsh->cb) - { - rsh->cb (rsh->cb_cls, - &rs); - rsh->cb = NULL; - } - TALER_EXCHANGE_reserves_status_cancel (rsh); -} - - -struct TALER_EXCHANGE_ReservesStatusHandle * -TALER_EXCHANGE_reserves_status ( - struct GNUNET_CURL_Context *ctx, - const char *url, - struct TALER_EXCHANGE_Keys *keys, - const struct TALER_ReservePrivateKeyP *reserve_priv, - TALER_EXCHANGE_ReservesStatusCallback cb, - void *cb_cls) -{ - struct TALER_EXCHANGE_ReservesStatusHandle *rsh; - CURL *eh; - char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32]; - struct TALER_ReserveSignatureP reserve_sig; - struct GNUNET_TIME_Timestamp ts - = GNUNET_TIME_timestamp_get (); - - rsh = GNUNET_new (struct TALER_EXCHANGE_ReservesStatusHandle); - rsh->cb = cb; - rsh->cb_cls = cb_cls; - GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv, - &rsh->reserve_pub.eddsa_pub); - { - char pub_str[sizeof (struct TALER_ReservePublicKeyP) * 2]; - char *end; - - end = GNUNET_STRINGS_data_to_string ( - &rsh->reserve_pub, - sizeof (rsh->reserve_pub), - pub_str, - sizeof (pub_str)); - *end = '\0'; - GNUNET_snprintf (arg_str, - sizeof (arg_str), - "reserves/%s/status", - pub_str); - } - rsh->url = TALER_url_join (url, - arg_str, - NULL); - if (NULL == rsh->url) - { - GNUNET_free (rsh); - return NULL; - } - eh = TALER_EXCHANGE_curl_easy_get_ (rsh->url); - if (NULL == eh) - { - GNUNET_break (0); - GNUNET_free (rsh->url); - GNUNET_free (rsh); - return NULL; - } - TALER_wallet_reserve_status_sign (ts, - reserve_priv, - &reserve_sig); - { - json_t *status_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_timestamp ("request_timestamp", - ts), - GNUNET_JSON_pack_data_auto ("reserve_sig", - &reserve_sig)); - - if (GNUNET_OK != - TALER_curl_easy_post (&rsh->post_ctx, - eh, - status_obj)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (status_obj); - GNUNET_free (rsh->url); - GNUNET_free (rsh); - return NULL; - } - json_decref (status_obj); - } - rsh->keys = TALER_EXCHANGE_keys_incref (keys); - rsh->job = GNUNET_CURL_job_add2 (ctx, - eh, - rsh->post_ctx.headers, - &handle_reserves_status_finished, - rsh); - return rsh; -} - - -void -TALER_EXCHANGE_reserves_status_cancel ( - struct TALER_EXCHANGE_ReservesStatusHandle *rsh) -{ - if (NULL != rsh->job) - { - GNUNET_CURL_job_cancel (rsh->job); - rsh->job = NULL; - } - TALER_curl_easy_post_finished (&rsh->post_ctx); - GNUNET_free (rsh->url); - TALER_EXCHANGE_keys_decref (rsh->keys); - GNUNET_free (rsh); -} - - -/* end of exchange_api_reserves_status.c */ diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c index 6de7adccb..53a5934d8 100644 --- a/src/lib/exchange_api_withdraw2.c +++ b/src/lib/exchange_api_withdraw2.c @@ -128,101 +128,6 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh, } -/** - * We got a 409 CONFLICT response for the /reserves/$RESERVE_PUB/withdraw operation. - * Check the signatures on the withdraw transactions in the provided - * history and that the balances add up. We don't do anything directly - * with the information, as the JSON will be returned to the application. - * However, our job is ensuring that the exchange followed the protocol, and - * this in particular means checking all of the signatures in the history. - * - * @param wh operation handle - * @param json reply from the exchange - * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors - */ -static enum GNUNET_GenericReturnValue -reserve_withdraw_payment_required ( - struct TALER_EXCHANGE_Withdraw2Handle *wh, - const json_t *json) -{ - struct TALER_Amount balance; - struct TALER_Amount total_in_from_history; - struct TALER_Amount total_out_from_history; - json_t *history; - size_t len; - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount_any ("balance", - &balance), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - history = json_object_get (json, - "history"); - if (NULL == history) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - /* go over transaction history and compute - total incoming and outgoing amounts */ - len = json_array_size (history); - { - struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory; - - /* Use heap allocation as "len" may be very big and thus this may - not fit on the stack. Use "GNUNET_malloc_large" as a malicious - exchange may theoretically try to crash us by giving a history - that does not fit into our memory. */ - rhistory = GNUNET_malloc_large ( - sizeof (struct TALER_EXCHANGE_ReserveHistoryEntry) - * len); - if (NULL == rhistory) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - - if (GNUNET_OK != - TALER_EXCHANGE_parse_reserve_history (wh->keys, - history, - &wh->reserve_pub, - balance.currency, - &total_in_from_history, - &total_out_from_history, - len, - rhistory)) - { - GNUNET_break_op (0); - TALER_EXCHANGE_free_reserve_history (len, - rhistory); - return GNUNET_SYSERR; - } - TALER_EXCHANGE_free_reserve_history (len, - rhistory); - } - - /* Check that funds were really insufficient */ - if (0 >= TALER_amount_cmp (&wh->requested_amount, - &balance)) - { - /* Requested amount is smaller or equal to reported balance, - so this should not have failed. */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - /** * Function called when we're done processing the * HTTP /reserves/$RESERVE_PUB/withdraw request. @@ -287,20 +192,6 @@ handle_reserve_withdraw_finished (void *cls, case MHD_HTTP_CONFLICT: w2r.hr.ec = TALER_JSON_get_error_code (j); w2r.hr.hint = TALER_JSON_get_error_hint (j); - - if (TALER_EC_EXCHANGE_RESERVES_AGE_RESTRICTION_REQUIRED == w2r.hr.ec) - break; - - /* The exchange says that the reserve has insufficient funds; - check the signatures in the history... */ - if (GNUNET_OK != - reserve_withdraw_payment_required (wh, - j)) - { - GNUNET_break_op (0); - w2r.hr.http_status = 0; - w2r.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - } break; case MHD_HTTP_GONE: /* could happen if denomination was revoked */ -- cgit v1.2.3