summaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_db.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd_db.c')
-rw-r--r--src/exchange/taler-exchange-httpd_db.c61
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 6f0fc41c9..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 0007267, 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 0007267, 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);