diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_db.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_db.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 5660074ee..6fec3fee4 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -19,9 +19,12 @@ * @author Christian Grothoff */ #include "platform.h" +#include <gnunet/gnunet_db_lib.h> #include <pthread.h> #include <jansson.h> #include <gnunet/gnunet_json_lib.h> +#include "taler_error_codes.h" +#include "taler_exchangedb_plugin.h" #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler_exchangedb_lib.h" @@ -37,14 +40,14 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin, { enum TALER_EXCHANGEDB_CoinKnownStatus cks; struct TALER_DenominationHashP h_denom_pub; - struct TALER_AgeCommitmentHash age_hash; + struct TALER_AgeCommitmentHash h_age_commitment = {{{0}}}; /* make sure coin is 'known' in database */ cks = TEH_plugin->ensure_coin_known (TEH_plugin->cls, coin, known_coin_id, &h_denom_pub, - &age_hash); + &h_age_commitment); switch (cks) { case TALER_EXCHANGEDB_CKS_ADDED: @@ -61,22 +64,50 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin, NULL); return GNUNET_DB_STATUS_HARD_ERROR; case TALER_EXCHANGEDB_CKS_DENOM_CONFLICT: - /* FIXME: insufficient_funds != denom conflict! See issue #7267, need new - * strategy for evidence gathering */ - *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds ( - connection, - TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY, - &h_denom_pub, - &coin->coin_pub); - return GNUNET_DB_STATUS_HARD_ERROR; - case TALER_EXCHANGEDB_CKS_AGE_CONFLICT: - /* FIXME: insufficient_funds != Age conflict! See issue #7267, need new - * strategy for evidence gathering */ - *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds ( + /* The exchange has a seen this coin before, but with a different denomination. + * Get the corresponding signature and sent it to the client as proof */ + { + struct + { + struct TALER_DenominationPublicKey pub; + struct TALER_DenominationSignature sig; + } prev_denom = {0}; + + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + TEH_plugin->get_signature_for_known_coin (TEH_plugin->cls, + &coin->coin_pub, + &prev_denom.pub, + &prev_denom.sig)) + { + /* There _should_ have been a result, because + * we ended here due to a conflict! */ + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + NULL); + return GNUNET_DB_STATUS_HARD_ERROR; + } + + *mhd_ret = TEH_RESPONSE_reply_coin_denomination_conflict ( + connection, + TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY, + &coin->coin_pub, + &prev_denom.pub, + &prev_denom.sig); + + return GNUNET_DB_STATUS_HARD_ERROR; + } + case TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NULL: + case TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NON_NULL: + case TALER_EXCHANGEDB_CKS_AGE_CONFLICT_VALUE_DIFFERS: + *mhd_ret = TEH_RESPONSE_reply_coin_age_commitment_conflict ( connection, TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH, + cks, &h_denom_pub, - &coin->coin_pub); + &coin->coin_pub, + &h_age_commitment); return GNUNET_DB_STATUS_HARD_ERROR; } GNUNET_assert (0); |