summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-09-18 18:59:53 +0200
committerChristian Grothoff <christian@grothoff.org>2023-09-18 18:59:53 +0200
commit12cff1b4439ab5dcc26fcf79e19518ae1bdce069 (patch)
treeb2ba500293a986475a66cde99a8bdb28e84368aa /src/lib
parent612828b7ef2299769a5b525a0fbf031858edc4f4 (diff)
downloadexchange-12cff1b4439ab5dcc26fcf79e19518ae1bdce069.tar.gz
exchange-12cff1b4439ab5dcc26fcf79e19518ae1bdce069.tar.bz2
exchange-12cff1b4439ab5dcc26fcf79e19518ae1bdce069.zip
remove coin and reserve histories from exchange replies
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Makefile.am1
-rw-r--r--src/lib/exchange_api_batch_deposit.c39
-rw-r--r--src/lib/exchange_api_common.c210
-rw-r--r--src/lib/exchange_api_common.h2
-rw-r--r--src/lib/exchange_api_melt.c16
-rw-r--r--src/lib/exchange_api_purse_create_with_deposit.c105
-rw-r--r--src/lib/exchange_api_purse_deposit.c111
-rw-r--r--src/lib/exchange_api_recoup.c14
-rw-r--r--src/lib/exchange_api_recoup_refresh.c33
-rw-r--r--src/lib/exchange_api_refund.c314
-rw-r--r--src/lib/exchange_api_reserves_history.c65
-rw-r--r--src/lib/exchange_api_reserves_open.c28
-rw-r--r--src/lib/exchange_api_reserves_status.c336
-rw-r--r--src/lib/exchange_api_withdraw2.c109
14 files changed, 55 insertions, 1328 deletions
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; i<dh->num_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
@@ -479,59 +479,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.
*
* @param[in,out] rh entry to parse
@@ -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; i<pch->num_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; i<pch->num_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; i<pch->num_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; i<pch->num_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
@@ -158,307 +158,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; off<len; off++)
- {
- json_t *transaction;
- struct TALER_Amount amount;
- const char *type;
- struct GNUNET_JSON_Specification spec_glob[] = {
- TALER_JSON_spec_amount_any ("amount",
- &amount),
- GNUNET_JSON_spec_string ("type",
- &type),
- GNUNET_JSON_spec_end ()
- };
-
- transaction = json_array_get (history,
- off);
- if (GNUNET_OK !=
- GNUNET_JSON_parse (transaction,
- spec_glob,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if (0 == strcasecmp (type,
- "DEPOSIT"))
- {
- struct TALER_Amount deposit_fee;
- struct TALER_MerchantWireHashP h_wire;
- struct TALER_PrivateContractHashP h_contract_terms;
- struct TALER_AgeCommitmentHash h_age_commitment;
- bool no_hac;
- struct TALER_ExtensionPolicyHashP h_policy;
- bool no_h_policy;
- struct GNUNET_HashCode wallet_data_hash;
- bool no_wallet_data_hash;
- struct GNUNET_TIME_Timestamp wallet_timestamp;
- struct TALER_MerchantPublicKeyP merchant_pub;
- struct GNUNET_TIME_Timestamp refund_deadline;
- struct TALER_CoinSpendSignatureP sig;
- struct GNUNET_JSON_Specification ispec[] = {
- GNUNET_JSON_spec_fixed_auto ("coin_sig",
- &sig),
- GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
- &h_contract_terms),
- GNUNET_JSON_spec_fixed_auto ("h_wire",
- &h_wire),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
- &h_age_commitment),
- &no_hac),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_fixed_auto ("h_policy",
- &h_policy),
- &no_h_policy),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_fixed_auto ("wallet_data_hash",
- &wallet_data_hash),
- &no_wallet_data_hash),
- GNUNET_JSON_spec_timestamp ("timestamp",
- &wallet_timestamp),
- GNUNET_JSON_spec_timestamp ("refund_deadline",
- &refund_deadline),
- TALER_JSON_spec_amount_any ("deposit_fee",
- &deposit_fee),
- GNUNET_JSON_spec_fixed_auto ("merchant_pub",
- &merchant_pub),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (transaction,
- ispec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- TALER_wallet_deposit_verify (&amount,
- &deposit_fee,
- &h_wire,
- &h_contract_terms,
- no_wallet_data_hash ? NULL :
- &wallet_data_hash,
- no_hac ? NULL : &h_age_commitment,
- no_h_policy ? NULL: &h_policy,
- &h_denom_pub,
- wallet_timestamp,
- &merchant_pub,
- refund_deadline,
- &rh->coin_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
* transaction ID reuse going on.
@@ -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
@@ -65,24 +65,14 @@ 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
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_reserves_status.c
- * @brief Implementation of the POST /reserves/$RESERVE_PUB/status requests
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#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
@@ -129,101 +129,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 */