aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcello Stanisci <marcello.stanisci@inria.fr>2016-10-19 23:07:17 +0200
committerMarcello Stanisci <marcello.stanisci@inria.fr>2016-10-19 23:07:17 +0200
commit083075153441c3451301d9ed35bfbac2dd8b346e (patch)
treef66875aaa67e3e65840b5511ec4bc2bf661a7aa3
parent9b6717ae3a95c6006d0f9692a8ae0f8d7f6ec60e (diff)
parent8fe6f64db308a8455c62e5139f7c2157faa2804a (diff)
Merge branch 'master' of taler.net:exchange
-rw-r--r--src/exchange-lib/exchange_api_common.c4
-rw-r--r--src/exchange-lib/exchange_api_reserve.c4
-rw-r--r--src/exchange-lib/test_exchange_api.c4
-rw-r--r--src/exchange/taler-exchange-httpd_admin.c2
-rw-r--r--src/exchange/taler-exchange-httpd_db.c179
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c88
-rw-r--r--src/exchange/taler-exchange-httpd_parsing.c12
-rw-r--r--src/exchange/taler-exchange-httpd_refresh.c24
-rw-r--r--src/exchange/taler-exchange-httpd_refund.c7
-rw-r--r--src/exchange/taler-exchange-httpd_reserve.c4
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c104
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h34
-rw-r--r--src/exchange/taler-exchange-httpd_test.c7
-rw-r--r--src/exchange/taler-exchange-httpd_tracking.c11
-rw-r--r--src/include/taler_error_codes.h761
15 files changed, 1074 insertions, 171 deletions
diff --git a/src/exchange-lib/exchange_api_common.c b/src/exchange-lib/exchange_api_common.c
index acf90fce6..e6ab2cbc2 100644
--- a/src/exchange-lib/exchange_api_common.c
+++ b/src/exchange-lib/exchange_api_common.c
@@ -38,8 +38,8 @@
*/
int
TALER_EXCHANGE_verify_coin_history (const char *currency,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- json_t *history,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ json_t *history,
struct TALER_Amount *total)
{
size_t len;
diff --git a/src/exchange-lib/exchange_api_reserve.c b/src/exchange-lib/exchange_api_reserve.c
index 0bff767e6..9de2b268f 100644
--- a/src/exchange-lib/exchange_api_reserve.c
+++ b/src/exchange-lib/exchange_api_reserve.c
@@ -599,7 +599,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
/**
- * We got a 402 PAYMENT REQUIRED response for the /reserve/withdraw operation.
+ * We got a 403 FORBIDDEN response for the /reserve/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.
@@ -723,7 +723,7 @@ handle_reserve_withdraw_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_PAYMENT_REQUIRED:
+ case MHD_HTTP_FORBIDDEN:
/* The exchange says that the reserve has insufficient funds;
check the signatures in the history... */
if (GNUNET_OK !=
diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c
index 29095d87a..80007c66f 100644
--- a/src/exchange-lib/test_exchange_api.c
+++ b/src/exchange-lib/test_exchange_api.c
@@ -1009,7 +1009,7 @@ reserve_withdraw_cb (void *cls,
cmd->details.reserve_withdraw.sig.rsa_signature
= GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
break;
- case MHD_HTTP_PAYMENT_REQUIRED:
+ case MHD_HTTP_FORBIDDEN:
/* nothing to check */
break;
default:
@@ -2737,7 +2737,7 @@ run (void *cls)
/* Try to overdraw funds ... */
{ .oc = OC_WITHDRAW_SIGN,
.label = "withdraw-coin-2",
- .expected_response_code = MHD_HTTP_PAYMENT_REQUIRED,
+ .expected_response_code = MHD_HTTP_FORBIDDEN,
.details.reserve_withdraw.reserve_reference = "create-reserve-1",
.details.reserve_withdraw.amount = "EUR:5" },
diff --git a/src/exchange/taler-exchange-httpd_admin.c b/src/exchange/taler-exchange-httpd_admin.c
index e99448f87..72cdcb7d6 100644
--- a/src/exchange/taler-exchange-httpd_admin.c
+++ b/src/exchange/taler-exchange-httpd_admin.c
@@ -89,6 +89,7 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED,
"sender_account_details");
}
if (0 != strcasecmp (amount.currency,
@@ -100,6 +101,7 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
amount.currency);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED,
"amount:currency");
}
res = TEH_DB_execute_admin_add_incoming (connection,
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index 6b27a22a6..870f7a251 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -53,7 +53,8 @@ transaction_start_label: /* we will use goto for retries */ \
session)) \
{ \
GNUNET_break (0); \
- return TEH_RESPONSE_reply_internal_db_error (connection); \
+ return TEH_RESPONSE_reply_internal_db_error (connection, \
+ TALER_EC_DB_START_FAILED); \
}
/**
@@ -73,8 +74,9 @@ transaction_start_label: /* we will use goto for retries */ \
if (GNUNET_SYSERR == transaction_commit_result) \
{ \
TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
- return TEH_RESPONSE_reply_commit_error (connection); \
- } \
+ return TEH_RESPONSE_reply_commit_error (connection, \
+ TALER_EC_DB_COMMIT_FAILED_HARD); \
+ } \
if (GNUNET_NO == transaction_commit_result) \
{ \
TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
@@ -83,7 +85,8 @@ transaction_start_label: /* we will use goto for retries */ \
TALER_LOG_WARNING ("Transaction commit failed %u times in %s\n", \
transaction_retries, \
__FUNCTION__); \
- return TEH_RESPONSE_reply_commit_error (connection); \
+ return TEH_RESPONSE_reply_commit_error (connection, \
+ TALER_EC_DB_COMMIT_FAILED_ON_RETRY); \
} \
} /* end of scope opened by BEGIN_TRANSACTION */
@@ -197,7 +200,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
if (GNUNET_YES ==
TEH_plugin->have_deposit (TEH_plugin->cls,
@@ -225,8 +229,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
if (NULL == dki)
{
TEH_KS_release (mks);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- "denom_pub");
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN);
}
TALER_amount_ntoh (&value,
&dki->issue.properties.value);
@@ -249,7 +253,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
session);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR);
}
/* Check that cost of all transactions is smaller than
the value of the coin. */
@@ -274,7 +279,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
TALER_LOG_WARNING ("Failed to store /deposit information in database\n");
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DEPOSIT_STORE_DB_ERROR);
}
COMMIT_TRANSACTION(session, connection);
@@ -324,7 +330,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
dep = NULL;
ref = NULL;
@@ -337,7 +344,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_refund_failure (connection,
- MHD_HTTP_NOT_FOUND);
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFUND_COIN_NOT_FOUND);
}
deposit_found = GNUNET_NO;
refund_found = GNUNET_NO;
@@ -411,7 +419,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
session);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- return TEH_RESPONSE_reply_transaction_unknown (connection);
+ return TEH_RESPONSE_reply_transaction_unknown (connection,
+ TALER_EC_REFUND_DEPOSIT_NOT_FOUND);
}
/* handle if conflicting refund found */
if (GNUNET_SYSERR == refund_found)
@@ -449,7 +458,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_refund_failure (connection,
- MHD_HTTP_PRECONDITION_FAILED);
+ MHD_HTTP_PRECONDITION_FAILED,
+ TALER_EC_REFUND_CURRENCY_MISSMATCH);
}
/* check if we already send the money for the /deposit */
@@ -466,6 +476,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFUND_DB_INCONSISTENT,
"database inconsistent");
}
if (GNUNET_YES == done)
@@ -476,7 +487,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return TEH_RESPONSE_reply_refund_failure (connection,
- MHD_HTTP_GONE);
+ MHD_HTTP_GONE,
+ TALER_EC_REFUND_MERCHANT_ALREADY_PAID);
}
/* check refund amount is sufficiently low */
@@ -487,7 +499,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return TEH_RESPONSE_reply_refund_failure (connection,
- MHD_HTTP_PRECONDITION_FAILED);
+ MHD_HTTP_PRECONDITION_FAILED,
+ TALER_EC_REFUND_INSUFFICIENT_FUNDS);
}
/* Check refund fee matches fee of denomination key! */
@@ -504,6 +517,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND,
"denomination key not found");
}
TALER_amount_ntoh (&expect_fee,
@@ -519,6 +533,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFUND_FEE_TOO_LOW,
"refund_fee");
}
if (1 == fee_cmp)
@@ -538,7 +553,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TALER_LOG_WARNING ("Failed to store /refund information in database\n");
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFUND_STORE_DB_ERROR);
}
COMMIT_TRANSACTION(session, connection);
@@ -566,7 +582,8 @@ TEH_DB_execute_reserve_status (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
rh = TEH_plugin->get_reserve_history (TEH_plugin->cls,
session,
@@ -637,6 +654,7 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_WITHDRAW_RESERVE_UNKNOWN,
"reserve_pub");
}
@@ -653,7 +671,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW);
}
/* calculate balance of the reserve */
@@ -673,7 +692,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_AMOUNT_DEPOSITS_OVERFLOW);
}
res |= 1;
break;
@@ -686,7 +706,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
GNUNET_break (0);
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND);
}
TALER_amount_ntoh (&value,
&tdki->issue.properties.value);
@@ -700,7 +721,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW);
}
res |= 2;
break;
@@ -708,9 +730,10 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
}
if (0 == (res & 1))
{
- /* did not encounter any deposit operations, how can we have a reserve? */
+ /* did not encounter any wire transfer operations, how can we have a reserve? */
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER);
}
if (0 == (res & 2))
{
@@ -748,6 +771,7 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_WITHDRAW_SIGNATURE_FAILED,
"Internal error");
}
collectable.sig = *denom_sig;
@@ -765,7 +789,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
GNUNET_break (0);
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_DB_STORE_ERROR);
}
COMMIT_TRANSACTION (session, connection);
@@ -811,7 +836,8 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
res = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
session,
@@ -820,7 +846,8 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
if (GNUNET_SYSERR == res)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR);
}
/* Don't sign again if we have already signed the coin */
@@ -834,6 +861,7 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
}
GNUNET_assert (GNUNET_NO == res);
+ /* FIXME: do we have to do this a second time here? */
key_state = TEH_KS_acquire ();
dki = TEH_KS_denomination_key_lookup (key_state,
denomination_pub,
@@ -843,9 +871,11 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
TEH_KS_release (key_state);
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
- "{s:s}",
+ "{s:s, s:I}",
"error",
- "Denomination not found");
+ "Denomination not found",
+ "code",
+ (json_int_t) TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND);
}
denom_sig.rsa_signature = NULL;
res = execute_reserve_withdraw_transaction (connection,
@@ -901,8 +931,9 @@ refresh_check_melt (struct MHD_Connection *connection,
TEH_KS_DKU_DEPOSIT);
if (NULL == dk)
return (MHD_YES ==
- TEH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub"))
+ TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND,
+ "denomination key no longer available while executing transaction"))
? GNUNET_NO : GNUNET_SYSERR;
dki = &dk->issue;
TALER_amount_ntoh (&coin_value,
@@ -922,7 +953,8 @@ refresh_check_melt (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return (MHD_YES ==
- TEH_RESPONSE_reply_internal_db_error (connection))
+ TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED))
? GNUNET_NO : GNUNET_SYSERR;
}
/* Refuse to refresh when the coin's value is insufficient
@@ -995,7 +1027,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
START_TRANSACTION (session, connection);
res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
@@ -1015,14 +1048,15 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
}
/* store 'global' session data */
refresh_session.num_newcoins = num_new_denoms;
refresh_session.noreveal_index
- = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
- TALER_CNC_KAPPA);
+ = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
+ TALER_CNC_KAPPA);
key_state = TEH_KS_acquire ();
if (GNUNET_OK !=
(res = refresh_check_melt (connection,
@@ -1047,7 +1081,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR);
}
/* store requested new denominations */
@@ -1060,7 +1095,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR);
}
if (GNUNET_OK !=
@@ -1072,7 +1108,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR);
}
if (GNUNET_OK !=
TEH_plugin->insert_refresh_transfer_public_key (TEH_plugin->cls,
@@ -1082,7 +1119,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_STORE_TRANSFER_ERROR);
}
COMMIT_TRANSACTION (session, connection);
@@ -1126,8 +1164,6 @@ check_commitment (struct MHD_Connection *connection,
struct TALER_TransferSecretP transfer_secret;
unsigned int j;
- /* FIXME: instead of consulting DB, reconstruct everything
- from transfer_priv here! */
TALER_link_reveal_transfer_secret (transfer_priv,
&melt->coin.coin_pub,
&transfer_secret);
@@ -1158,8 +1194,10 @@ check_commitment (struct MHD_Connection *connection,
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Blind failed (bad denomination key!?)\n");
- return (MHD_YES == TEH_RESPONSE_reply_internal_error (connection,
- "Blinding error"))
+ return (MHD_YES ==
+ TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFRESH_REVEAL_BLINDING_ERROR,
+ "Blinding error"))
? GNUNET_NO : GNUNET_SYSERR;
}
GNUNET_CRYPTO_hash_context_read (hash_context,
@@ -1274,7 +1312,8 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection,
j);
if (NULL == ev_sigs[j].rsa_signature)
{
- ret = TEH_RESPONSE_reply_internal_db_error (connection);
+ ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_SIGNING_ERROR);
goto cleanup;
}
}
@@ -1323,7 +1362,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
@@ -1332,10 +1372,12 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
&refresh_session);
if (GNUNET_NO == res)
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
"session_hash");
if ( (GNUNET_SYSERR == res) ||
(refresh_session.noreveal_index >= TALER_CNC_KAPPA) )
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR);
denom_pubs = GNUNET_new_array (refresh_session.num_newcoins,
struct TALER_DenominationPublicKey);
if (GNUNET_OK !=
@@ -1349,7 +1391,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_free (denom_pubs);
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
+ return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR))
? GNUNET_NO : GNUNET_SYSERR;
}
@@ -1373,7 +1416,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
+ return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR))
? GNUNET_NO : GNUNET_SYSERR;
}
GNUNET_CRYPTO_hash_context_read (hash_context,
@@ -1410,7 +1454,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
+ return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR))
? GNUNET_NO : GNUNET_SYSERR;
}
for (i=0;i<refresh_session.num_newcoins;i++)
@@ -1463,7 +1508,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR);
}
/* add envelopes to hash_context */
for (j=0;j<refresh_session.num_newcoins;j++)
@@ -1656,7 +1702,8 @@ TEH_DB_execute_refresh_link (struct MHD_Connection *connection,
if (NULL == (ctx.session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
ctx.connection = connection;
ctx.num_sessions = 0;
@@ -1680,6 +1727,7 @@ TEH_DB_execute_refresh_link (struct MHD_Connection *connection,
GNUNET_assert (GNUNET_OK == ctx.status);
if (0 == ctx.num_sessions)
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_REFRESH_LINK_COIN_UNKNOWN,
"coin_pub");
res = TEH_RESPONSE_reply_refresh_link_success (connection,
ctx.num_sessions,
@@ -1720,7 +1768,8 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
ret = TEH_plugin->reserves_in_insert (TEH_plugin->cls,
session,
@@ -1732,7 +1781,8 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
if (GNUNET_SYSERR == ret)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_ADMIN_ADD_INCOMING_DB_STORE);
}
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
@@ -1913,7 +1963,8 @@ TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
ctx.is_valid = GNUNET_NO;
ctx.wdd_head = NULL;
@@ -1926,18 +1977,21 @@ TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
if (GNUNET_SYSERR == ret)
{
GNUNET_break (0);
- ret = TEH_RESPONSE_reply_internal_db_error (connection);
+ ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED);
goto cleanup;
}
if (GNUNET_SYSERR == ctx.is_valid)
{
GNUNET_break (0);
- ret = TEH_RESPONSE_reply_internal_db_error (connection);
+ ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT);
goto cleanup;
}
if (GNUNET_NO == ctx.is_valid)
{
ret = TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
"wtid");
goto cleanup;
}
@@ -2035,7 +2089,8 @@ handle_wtid_data (void *cls,
coin_fee))
{
GNUNET_break (0);
- ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection);
+ ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection,
+ TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT);
}
else
{
@@ -2079,7 +2134,8 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
ctx.connection = connection;
ctx.h_contract = *h_contract;
@@ -2100,17 +2156,20 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection,
{
GNUNET_break (0);
GNUNET_break (GNUNET_SYSERR == ctx.res);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED);
}
if (GNUNET_NO == ret)
{
GNUNET_break (GNUNET_SYSERR == ctx.res);
- return TEH_RESPONSE_reply_transaction_unknown (connection);
+ return TEH_RESPONSE_reply_transaction_unknown (connection,
+ TALER_EC_TRACK_TRANSACTION_NOT_FOUND);
}
if (GNUNET_SYSERR == ctx.res)
{
GNUNET_break (0);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR,
"bug resolving deposit wtid");
}
return ctx.res;
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index a97dd0514..b0ab42e7f 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -48,12 +48,9 @@
*/
static int
verify_and_execute_deposit (struct MHD_Connection *connection,
- const struct TALER_EXCHANGEDB_Deposit *deposit)
+ const struct TALER_EXCHANGEDB_Deposit *deposit)
{
- struct TEH_KS_StateHandle *key_state;
struct TALER_DepositRequestPS dr;
- struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
- struct TALER_Amount fee_deposit;
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
@@ -76,39 +73,9 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
{
TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID,
"coin_sig");
}
- /* check denomination exists and is valid */
- key_state = TEH_KS_acquire ();
- dki = TEH_KS_denomination_key_lookup (key_state,
- &deposit->coin.denom_pub,
- TEH_KS_DKU_DEPOSIT);
- if (NULL == dki)
- {
- TEH_KS_release (key_state);
- TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
- return TEH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub");
- }
- /* check coin signature */
- if (GNUNET_YES !=
- TALER_test_coin_valid (&deposit->coin))
- {
- TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
- TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- "ub_sig");
- }
- TALER_amount_ntoh (&fee_deposit,
- &dki->issue.properties.fee_deposit);
- if (0 < TALER_amount_cmp (&fee_deposit,
- &deposit->amount_with_fee))
- {
- TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_external_error (connection,
- "deposited amount smaller than depositing fee");
- }
- TEH_KS_release (key_state);
return TEH_DB_execute_deposit (connection,
deposit);
@@ -141,12 +108,11 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
json_t *wire;
struct TALER_EXCHANGEDB_Deposit deposit;
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
- struct TEH_KS_StateHandle *ks;
+ struct TEH_KS_StateHandle *key_state;
struct GNUNET_HashCode my_h_wire;
- struct TALER_Amount amount;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("wire", &wire),
- TALER_JSON_spec_amount ("f", &amount),
+ TALER_JSON_spec_amount ("f", &deposit.amount_with_fee),
TALER_JSON_spec_denomination_public_key ("denom_pub", &deposit.coin.denom_pub),
TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub),
@@ -180,11 +146,13 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
if (GNUNET_NO == res)
return MHD_YES; /* failure */
+ deposit.receiver_wire_account = wire;
if (deposit.refund_deadline.abs_value_us > deposit.wire_deadline.abs_value_us)
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
"refund_deadline");
}
@@ -194,6 +162,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT,
"wire");
}
if (GNUNET_OK !=
@@ -203,6 +172,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON,
"wire");
}
if (0 != memcmp (&deposit.h_wire,
@@ -212,32 +182,48 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
/* Client hashed contract differently than we did, reject */
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT,
"H_wire");
}
- ks = TEH_KS_acquire ();
- dki = TEH_KS_denomination_key_lookup (ks,
+
+ /* check denomination exists and is valid */
+ key_state = TEH_KS_acquire ();
+ dki = TEH_KS_denomination_key_lookup (key_state,
&deposit.coin.denom_pub,
TEH_KS_DKU_DEPOSIT);
if (NULL == dki)
{
- TEH_KS_release (ks);
- GNUNET_JSON_parse_free (spec);
+ TEH_KS_release (key_state);
+ TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN,
"denom_pub");
}
TALER_amount_ntoh (&deposit.deposit_fee,
&dki->issue.properties.fee_deposit);
- TEH_KS_release (ks);
- deposit.receiver_wire_account = wire;
- deposit.amount_with_fee = amount;
- if (-1 == TALER_amount_cmp (&deposit.amount_with_fee,
- &deposit.deposit_fee))
+ /* check coin signature */
+ if (GNUNET_YES !=
+ TALER_test_coin_valid (&deposit.coin))
{
- /* Total amount smaller than fee, invalid */
- GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- "f");
+ TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
+ TEH_KS_release (key_state);
+ return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID,
+ "ub_sig");
+ }
+ TALER_amount_ntoh (&deposit.deposit_fee,
+ &dki->issue.properties.fee_deposit);
+ TEH_KS_release (key_state);
+
+ if (0 < TALER_amount_cmp (&deposit.deposit_fee,
+ &deposit.amount_with_fee))
+ {
+ GNUNET_break_op (0);
+ return TEH_RESPONSE_reply_external_error (connection,
+ TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
+ "deposited amount smaller than depositing fee");
}
+
res = verify_and_execute_deposit (connection,
&deposit);
GNUNET_JSON_parse_free (spec);
diff --git a/src/exchange/taler-exchange-httpd_parsing.c b/src/exchange/taler-exchange-httpd_parsing.c
index c7118c462..e9c38eb82 100644
--- a/src/exchange/taler-exchange-httpd_parsing.c
+++ b/src/exchange/taler-exchange-httpd_parsing.c
@@ -79,6 +79,7 @@ TEH_PARSE_post_json (struct MHD_Connection *connection,
case GNUNET_JSON_PR_OUT_OF_MEMORY:
return (MHD_NO ==
TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_PARSER_OUT_OF_MEMORY,
"out of memory"))
? GNUNET_SYSERR : GNUNET_NO;
case GNUNET_JSON_PR_CONTINUE:
@@ -144,7 +145,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
if (NULL == str)
{
return (MHD_NO ==
- TEH_RESPONSE_reply_arg_missing (connection, param_name))
+ TEH_RESPONSE_reply_arg_missing (connection,
+ TALER_EC_PARAMETER_MISSING,
+ param_name))
? GNUNET_SYSERR : GNUNET_NO;
}
if (GNUNET_OK !=
@@ -153,7 +156,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
out_data,
out_size))
return (MHD_NO ==
- TEH_RESPONSE_reply_arg_invalid (connection, param_name))
+ TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_PARAMETER_MALFORMED,
+ param_name))
? GNUNET_SYSERR : GNUNET_NO;
return GNUNET_OK;
}
@@ -193,8 +198,9 @@ TEH_PARSE_json_data (struct MHD_Connection *connection,
ret = (MHD_YES ==
TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s, s:I}",
+ "{s:s, s:I, s:s, s:I}",
"error", "parse error",
+ "code", (json_int_t) TALER_EC_JSON_INVALID_WITH_DETAILS,
"field", error_json_name,
"line", (json_int_t) error_line))
? GNUNET_NO : GNUNET_SYSERR;
diff --git a/src/exchange/taler-exchange-httpd_refresh.c b/src/exchange/taler-exchange-httpd_refresh.c
index 0c500920d..3a8875f44 100644
--- a/src/exchange/taler-exchange-httpd_refresh.c
+++ b/src/exchange/taler-exchange-httpd_refresh.c
@@ -69,7 +69,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
struct TALER_Amount total_melt;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "melt request for session %s\n",
+ "/refresh/melt request for session %s\n",
GNUNET_h2s (session_hash));
GNUNET_assert (GNUNET_OK ==
@@ -86,6 +86,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
GNUNET_break_op (0);
TEH_KS_release (key_state);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND,
"new_denoms");
}
dki = &dk->issue;
@@ -105,6 +106,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
GNUNET_break_op (0);
TEH_KS_release (key_state);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW,
"cost calculation failure");
}
}
@@ -115,8 +117,9 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
if (NULL == dk)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- "denom_pub");
+ return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND,
+ "denom_pub");
}
dki = &dk->issue;
TALER_amount_ntoh (&fee_melt,
@@ -129,6 +132,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
GNUNET_break_op (0);
TEH_KS_release (key_state);
return TEH_RESPONSE_reply_external_error (connection,
+ TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION,
"Melt contribution below melting fee");
}
TEH_KS_release (key_state);
@@ -141,8 +145,9 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
total value of coins being generated to match! */
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error", "value mismatch");
+ "{s:s, s:I}",
+ "error", "value mismatch",
+ "code", (json_int_t) TALER_EC_REFRESH_MELT_FEES_MISSMATCH);
}
return TEH_DB_execute_refresh_melt (connection,
session_hash,
@@ -203,6 +208,7 @@ get_coin_public_info (struct MHD_Connection *connection,
r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL;
return (MHD_YES ==
TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID,
"denom_sig"))
? GNUNET_NO : GNUNET_SYSERR;
}
@@ -237,6 +243,8 @@ verify_coin_public_info (struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
struct TALER_Amount fee_refresh;
+ /* FIXME: we lookup the dki twice during /refresh/melt.
+ This should be avoided. */
key_state = TEH_KS_acquire ();
dki = TEH_KS_denomination_key_lookup (key_state,
&melt_detail->coin_info.denom_pub,
@@ -246,6 +254,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
TEH_KS_release (key_state);
TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND,
"denom_pub");
}
TALER_amount_ntoh (&fee_refresh,
@@ -266,6 +275,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
TEH_KS_release (key_state);
return (MHD_YES ==
TEH_RESPONSE_reply_external_error (connection,
+ TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT,
"melt amount smaller than melting fee"))
? GNUNET_NO : GNUNET_SYSERR;
}
@@ -280,6 +290,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
GNUNET_break_op (0);
if (MHD_YES !=
TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID,
"confirm_sig"))
return GNUNET_SYSERR;
return GNUNET_NO;
@@ -565,6 +576,7 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_MELT_CNC_COIN_ARRAY_SIZE_INVALID,
"coin_evs");
}
if (TALER_CNC_KAPPA != json_array_size (transfer_pubs))
@@ -572,6 +584,7 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_MELT_CNC_TRANSFER_ARRAY_SIZE_INVALID,
"transfer_pubs");
}
res = handle_refresh_melt_json (connection,
@@ -694,6 +707,7 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
GNUNET_JSON_parse_free (spec);
GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID,
"transfer_privs");
}
res = handle_refresh_reveal_json (connection,
diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c
index fdb6f8b76..591bb188d 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -69,14 +69,16 @@ verify_and_execute_refund (struct MHD_Connection *connection,
{
GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH,
"refund_fee");
}
if (-1 == TALER_amount_cmp (&refund->refund_amount,
&refund->refund_fee) )
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- "refund_amount");
+ return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFUND_FEE_ABOVE_AMOUNT,
+ "refund_amount");
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
@@ -86,6 +88,7 @@ verify_and_execute_refund (struct MHD_Connection *connection,
{
TALER_LOG_WARNING ("Invalid signature on /refund request\n");
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID,
"merchant_sig");
}
return TEH_DB_execute_refund (connection,
diff --git a/src/exchange/taler-exchange-httpd_reserve.c b/src/exchange/taler-exchange-httpd_reserve.c
index 7098e99a2..0abe37c5a 100644
--- a/src/exchange/taler-exchange-httpd_reserve.c
+++ b/src/exchange/taler-exchange-httpd_reserve.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014,2015 GNUnet e.V.
+ Copyright (C) 2014, 2015, 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -138,6 +138,7 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
GNUNET_JSON_parse_free (spec);
TEH_KS_release (ks);
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND,
"denom_pub");
}
TALER_amount_ntoh (&amount,
@@ -171,6 +172,7 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
TALER_LOG_WARNING ("Client supplied invalid signature for /reserve/withdraw request\n");
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID,
"reserve_sig");
}
res = TEH_DB_execute_reserve_withdraw (connection,
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index cacd933f1..b31f22e10 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -132,17 +132,20 @@ TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
* Send a response indicating an invalid argument.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "invalid parameter",
+ "code", (json_int_t) ec,
"parameter", param_name);
}
@@ -153,17 +156,20 @@ TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
* denomination key).
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "unknown entity referenced",
+ "code", (json_int_t) ec,
"parameter", param_name);
}
@@ -172,17 +178,20 @@ TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
* Send a response indicating an invalid signature.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_UNAUTHORIZED,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "invalid signature",
+ "code", (json_int_t) ec,
"parameter", param_name);
}
@@ -191,17 +200,20 @@ TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
* Send a response indicating a missing argument.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is missing
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{ s:s, s:s}",
+ "{ s:s, s:I, s:s}",
"error", "missing parameter",
+ "code", (json_int_t) ec,
"parameter", param_name);
}
@@ -210,17 +222,20 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
* Send a response indicating permission denied.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about why access was denied
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_FORBIDDEN,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "permission denied",
+ "code", (json_int_t) ec,
"hint", hint);
}
@@ -229,17 +244,20 @@ TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
* Send a response indicating an internal error.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about the internal error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "internal error",
+ "code", (json_int_t) ec,
"hint", hint);
}
@@ -248,17 +266,20 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
* Send a response indicating an external error.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about the error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "client error",
+ "code", (json_int_t) ec,
"hint", hint);
}
@@ -268,15 +289,18 @@ TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
* transaction (concurrent interference).
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection)
+TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error", "commit failure");
+ "{s:s, s:I}",
+ "error", "commit failure",
+ "code", (json_int_t) ec);
}
@@ -285,12 +309,15 @@ TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection)
* database.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection)
+TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_internal_error (connection,
+ ec,
"Failed to connect to database");
}
@@ -332,9 +359,9 @@ TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error",
- "invalid json");
+ "{s:s, s:I}",
+ "error", "invalid json",
+ "code", (json_int_t) TALER_EC_JSON_INVALID);
}
@@ -556,11 +583,13 @@ TEH_RESPONSE_reply_deposit_insufficient_funds (struct MHD_Connection *connection
history = compile_transaction_history (tl);
if (NULL == history)
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS);
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_FORBIDDEN,
- "{s:s, s:o}",
+ "{s:s, s:I, s:o}",
"error", "insufficient funds",
+ "code", (json_int_t) TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS,
"history", history);
}
@@ -696,8 +725,9 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
- "{s:s, s:o}",
+ "{s:s, s:I, s:o}",
"status", "conflicting refund",
+ "code", (json_int_t) TALER_EC_REFUND_CONFLICT,
"history", compile_transaction_history (tl));
}
@@ -708,17 +738,19 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
*
* @param connection connection to the client
* @param response_code response code to generate
+ * @param ec taler error code to include
* @return MHD result code
*/
int
TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
- unsigned int response_code)
+ unsigned int response_code,
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_json_pack (connection,
response_code,
- "{s:s}",
- "error",
- "no details");
+ "{s:s, s:I}",
+ "status", "refund failure",
+ "code", (json_int_t) ec);
}
@@ -779,6 +811,7 @@ TEH_RESPONSE_reply_reserve_status_success (struct MHD_Connection *connection,
&balance);
if (NULL == json_history)
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_RESERVE_STATUS_DB_ERROR,
"balance calculation failure");
json_balance = TALER_JSON_from_amount (&balance);
return TEH_RESPONSE_reply_json_pack (connection,
@@ -810,12 +843,14 @@ TEH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c
&balance);
if (NULL == json_history)
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
"balance calculation failure");
json_balance = TALER_JSON_from_amount (&balance);
return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_PAYMENT_REQUIRED,
- "{s:s, s:o, s:o}",
+ MHD_HTTP_FORBIDDEN,
+ "{s:s, s:I, s:o, s:o}",
"error", "Insufficient funds",
+ "code", (json_int_t) TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
"balance", json_balance,
"history", json_history);
}
@@ -830,7 +865,7 @@ TEH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c
*/
int
TEH_RESPONSE_reply_reserve_withdraw_success (struct MHD_Connection *connection,
- const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
+ const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
{
json_t *sig_json;
@@ -869,12 +904,15 @@ TEH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *conne
history = compile_transaction_history (tl);
if (NULL == history)
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS);
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_FORBIDDEN,
- "{s:s, s:o, s:o, s:o, s:o, s:o}",
+ "{s:s, s:I, s:o, s:o, s:o, s:o, s:o}",
"error",
- "insufficient funds",
+ "insufficient funds",
+ "code",
+ (json_int_t) TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS,
"coin_pub",
GNUNET_JSON_from_data_auto (coin_pub),
"original_value",
@@ -1011,8 +1049,9 @@ TEH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
}
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
- "{s:s, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:i}",
+ "{s:s, s:I, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:i}",
"error", "commitment violation",
+ "code", (json_int_t) TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION,
"coin_sig", GNUNET_JSON_from_data_auto (&session->melt.coin_sig),
"coin_pub", GNUNET_JSON_from_data_auto (&session->melt.coin.coin_pub),
"melt_amount_with_fee", TALER_JSON_from_amount (&session->melt.amount_with_fee),
@@ -1089,15 +1128,18 @@ TEH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
* 404 reply.
*
* @param connection connection to the client
+ * @param ec Taler error code
* @return MHD result code
*/
int
-TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection)
+TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error", "Deposit unknown");
+ "{s:s, s:I}",
+ "error", "Deposit unknown",
+ "code", (json_int_t) ec);
}
diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h
index 742a95b91..23cae16d7 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -29,6 +29,7 @@
#include <jansson.h>
#include <microhttpd.h>
#include <pthread.h>
+#include "taler_error_codes.h"
#include "taler-exchange-httpd.h"
#include "taler-exchange-httpd_db.h"
@@ -78,11 +79,13 @@ TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
* Send a response indicating an invalid signature.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name);
@@ -90,11 +93,13 @@ TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
* Send a response indicating an invalid argument.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return MHD result code
*/
int
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name);
@@ -104,11 +109,13 @@ TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
* denomination key).
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name);
@@ -116,11 +123,13 @@ TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
* Send a response indicating a missing argument.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is missing
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name);
@@ -128,11 +137,13 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
* Send a response indicating permission denied.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about why access was denied
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint);
@@ -140,11 +151,13 @@ TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
* Send a response indicating an internal error.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about the internal error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint);
@@ -152,11 +165,13 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
* Send a response indicating an external error.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about the error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint);
@@ -165,21 +180,24 @@ TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
* transaction (concurrent interference).
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection);
-
+TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec);
/**
* Send a response indicating a failure to talk to the Exchange's
* database.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection);
+TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec);
/**
@@ -266,11 +284,13 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
*
* @param connection connection to the client
* @param response_code response code to generate
+ * @param ec error code uniquely identifying the error
* @return MHD result code
*/
int
TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
- unsigned int response_code);
+ unsigned int response_code,
+ enum TALER_ErrorCode ec);
/**
@@ -291,10 +311,12 @@ TEH_RESPONSE_reply_refund_success (struct MHD_Connection *connection,
* 404 reply.
*
* @param connection connection to the client
+ * @param ec Taler error code
* @return MHD result code
*/
int
-TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection);
+TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec);
/**
@@ -307,7 +329,7 @@ TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection);
*/
int
TEH_RESPONSE_reply_transfer_pending (struct MHD_Connection *connection,
- struct GNUNET_TIME_Absolute planned_exec_time);
+ struct GNUNET_TIME_Absolute planned_exec_time);
/**
diff --git a/src/exchange/taler-exchange-httpd_test.c b/src/exchange/taler-exchange-httpd_test.c
index 7c3252b10..731da36ce 100644
--- a/src/exchange/taler-exchange-httpd_test.c
+++ b/src/exchange/taler-exchange-httpd_test.c
@@ -295,6 +295,7 @@ TEH_TEST_handler_test_ecdhe (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_ECDH_ERROR,
"Failed to perform ECDH");
}
GNUNET_JSON_parse_free (spec);
@@ -365,6 +366,7 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_TEST_EDDSA_INVALID,
"eddsa_sig");
}
GNUNET_JSON_parse_free (spec);
@@ -377,6 +379,7 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
{
GNUNET_free (pk);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_EDDSA_ERROR,
"Failed to EdDSA-sign");
}
GNUNET_CRYPTO_eddsa_key_get_public (pk,
@@ -419,6 +422,7 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh,
{
GNUNET_break (0);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_RSA_GEN_ERROR,
"Failed to create RSA key");
}
pub = GNUNET_CRYPTO_rsa_private_key_get_public (rsa_pk);
@@ -426,6 +430,7 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh,
{
GNUNET_break (0);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_RSA_PUB_ERROR,
"Failed to get public RSA key");
}
res = TEH_RESPONSE_reply_json_pack (connection,
@@ -489,6 +494,7 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_RSA_GEN_ERROR,
"Failed to create RSA key");
}
sig = GNUNET_CRYPTO_rsa_sign_blinded (rsa_pk,
@@ -499,6 +505,7 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_RSA_SIGN_ERROR,
"Failed to RSA-sign");
}
GNUNET_JSON_parse_free (spec);
diff --git a/src/exchange/taler-exchange-httpd_tracking.c b/src/exchange/taler-exchange-httpd_tracking.c
index f4d106628..e5d1139f1 100644
--- a/src/exchange/taler-exchange-httpd_tracking.c
+++ b/src/exchange/taler-exchange-httpd_tracking.c
@@ -88,14 +88,15 @@ check_and_handle_track_transaction_request (struct MHD_Connection *connection,
{
GNUNET_break_op (0);
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID,
"merchant_sig");
}
return TEH_DB_execute_track_transaction (connection,
- &tps->h_contract,
- &tps->h_wire,
- &tps->coin_pub,
- merchant_pub,
- transaction_id);
+ &tps->h_contract,
+ &tps->h_wire,
+ &tps->coin_pub,
+ merchant_pub,
+ transaction_id);
}
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index bbb300440..3c3ddcfd4 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -35,10 +35,769 @@ enum TALER_ErrorCode
/**
* Special code to indicate no error.
*/
- TALER_EC_NONE = 0
+ TALER_EC_NONE = 0,
+ /* ********** generic error codes ************* */
+
+ /**
+ * The exchange failed to even just initialize its connection to the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DB_SETUP_FAILED = 1001,
+
+ /**
+ * The exchange encountered an error event to just start
+ * the database transaction.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DB_START_FAILED = 1002,
+
+ /**
+ * The exchange encountered an error event to commit
+ * the database transaction (hard, unrecoverable error).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DB_COMMIT_FAILED_HARD = 1003,
+
+ /**
+ * The exchange encountered an error event to commit
+ * the database transaction, even after repeatedly
+ * retrying it there was always a conflicting transaction.
+ * (This indicates a repeated serialization error; should
+ * only happen if some client maliciously tries to create
+ * conflicting concurrent transactions.)
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DB_COMMIT_FAILED_ON_RETRY = 1004,
+
+ /**
+ * The exchange had insufficient memory to parse the request. This
+ * response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_PARSER_OUT_OF_MEMORY = 1005,
+
+ /**
+ * The JSON in the client's request to the exchange was malformed.
+ * (Generic parse error).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_JSON_INVALID = 1006,
+
+ /**
+ * The JSON in the client's request to the exchange was malformed.
+ * Details about the location of the parse error are provided.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_JSON_INVALID_WITH_DETAILS = 1007,
+
+ /**
+ * A required parameter in the request to the exchange was missing.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PARAMETER_MISSING = 1008,
+
+ /**
+ * A parameter in the request to the exchange was malformed.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PARAMETER_MALFORMED = 1009,
+
+ /* ********** request-specific error codes ************* */
+
+ /**
+ * The given reserve does not have sufficient funds to admit the
+ * requested withdraw operation at this time. The response includes
+ * the current "balance" of the reserve as well as the transaction
+ * "history" that lead to this balance. This response is provided
+ * with HTTP status code MHD_HTTP_FORBIDDEN.
+ */
+ TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS = 1100,
+
+ /**
+ * The exchange has no information about the "reserve_pub" that
+ * was given.
+ * This response is provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_WITHDRAW_RESERVE_UNKNOWN = 1101,
+
+ /**
+ * The amount to withdraw together with the fee exceeds the
+ * numeric range for Taler amounts. This is not a client
+ * failure, as the coin value and fees come from the exchange's
+ * configuration.
+ * This response is provided with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW = 1102,
+
+ /**
+ * All of the deposited amounts into this reserve total up to a
+ * value that is too big for the numeric range for Taler amounts.
+ * This is not a client failure, as the transaction history comes
+ * from the exchange's configuration. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_AMOUNT_DEPOSITS_OVERFLOW = 1103,
+
+ /**
+ * For one of the historic withdrawals from this reserve, the
+ * exchange could not find the denomination key.
+ * This is not a client failure, as the transaction history comes
+ * from the exchange's configuration. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND = 1104,
+
+ /**
+ * All of the withdrawals from reserve total up to a
+ * value that is too big for the numeric range for Taler amounts.
+ * This is not a client failure, as the transaction history comes
+ * from the exchange's configuration. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW = 1105,
+
+ /**
+ * The exchange somehow knows about this reserve, but there seem to
+ * have been no wire transfers made. This is not a client failure,
+ * as this is a database consistency issue of the exchange. This
+ * response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER = 1106,
+
+ /**
+ * The exchange failed to create the signature using the
+ * denomination key. This response is provided with HTTP status
+ * code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_SIGNATURE_FAILED = 1107,
+
+ /**
+ * The exchange failed to store the withdraw operation in its
+ * database. This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_DB_STORE_ERROR = 1108,
+
+ /**
+ * The exchange failed to check against historic withdraw data from
+ * database (as part of ensuring the idempotency of the operation).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR = 1109,
+
+ /**
+ * The exchange is not aware of the denomination key
+ * the wallet requested for the withdrawal.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND = 1110,
+
+ /**
+ * The signature of the reserve is not valid. This response is
+ * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID = 1111,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given reserve from the database while generating an insufficient
+ * funds errors.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1112,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given reserve from the database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_RESERVE_STATUS_DB_ERROR = 1150,
+
+
+ /**
+ * The respective coin did not have sufficient residual value
+ * for the /deposit operation (i.e. due to double spending).
+ * The "history" in the respose provides the transaction history
+ * of the coin proving this fact. This response is provided
+ * with HTTP status code MHD_HTTP_FORBIDDEN.
+ */
+ TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS = 1200,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given coin from the database (this does not happen merely because
+ * the coin is seen by the exchange for the first time).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR = 1201,
+
+ /**
+ * The exchange failed to store the /depost information in the
+ * database. This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DEPOSIT_STORE_DB_ERROR = 1202,
+
+ /**
+ * The exchange database is unaware of the denomination key that
+ * signed the coin (however, the exchange process is; this is not
+ * supposed to happen; it can happen if someone decides to purge the
+ * DB behind the back of the exchange process). Hence the deposit
+ * is being refused. This response is provided with HTTP status
+ * code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN = 1203,
+
+ /**
+ * The exchange database is unaware of the denomination key that
+ * signed the coin (however, the exchange process is; this is not
+ * supposed to happen; it can happen if someone decides to purge the
+ * DB behind the back of the exchange process). Hence the deposit
+ * is being refused. This response is provided with HTTP status
+ * code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN = 1204,
+
+ /**
+ * The signature of the coin is not valid. This response is
+ * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID = 1205,
+
+ /**
+ * The signature of the denomination key over the coin is not valid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID = 1206,
+
+ /**
+ * The stated value of the coin after the deposit fee is subtracted
+ * would be negative.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE = 1207,
+
+ /**
+ * The stated refund deadline is after the wire deadline.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE = 1208,
+
+ /**
+ * The exchange does not recognize the validity of or support the
+ * given wire (bank account) address. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT = 1209,
+
+ /**
+ * The exchange failed to canonicalize and hash the given wire format.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON = 1210,
+
+ /**
+ * The hash of the given wire address does not match the hash
+ * specified in the contract.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT = 1211,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given coin from the database while generating an insufficient
+ * funds errors.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1212,
+
+ /**
+ * The respective coin did not have sufficient residual value
+ * for the /refresh/melt operation. The "history" in this
+ * response provdes the "residual_value" of the coin, which may
+ * be less than its "original_value". This response is provided
+ * with HTTP status code MHD_HTTP_FORBIDDEN.
+ */
+ TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS = 1300,
+
+ /**
+ * The exchange is unaware of the denomination key that was
+ * used to sign the melted coin. This response is provided
+ * with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND = 1301,
+
+ /**
+ * The exchange had an internal error reconstructing the
+ * transaction history of the coin that was being melted.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED = 1302,
+
+ /**
+ * The exchange failed to check against historic melt data from
+ * database (as part of ensuring the idempotency of the operation).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_FETCH_ERROR = 1303,
+
+ /**
+ * The exchange failed to store session data in the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR = 1304,
+
+ /**
+ * The exchange failed to store refresh order data in the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR = 1305,
+
+ /**
+ * The exchange failed to store commit data in the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_STORE_COMMIT_ERROR = 1306,
+
+ /**
+ * The exchange failed to store transfer keys in the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_STORE_TRANSFER_ERROR = 1307,
+
+ /**
+ * The exchange is unaware of the denomination key that was
+ * requested for one of the fresh coins. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND = 1308,
+
+ /**
+ * The exchange encountered a numeric overflow totaling up
+ * the cost for the refresh operation. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW = 1309,
+
+ /**
+ * During the transaction phase, the exchange could suddenly
+ * no longer find the denomination key that was
+ * used to sign the melted coin. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND = 1310,
+
+ /**
+ * The exchange encountered melt fees exceeding the melted
+ * coin's contribution. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION = 1311,
+
+ /**
+ * The exchange's cost calculation does not add up to the
+ * melt fees specified in the request. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_FEES_MISSMATCH = 1312,
+
+ /**
+ * The denomination key signature on the melted coin is invalid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID = 1313,
+
+ /**
+ * The exchange's cost calculation shows that the melt amount
+ * is below the costs of the transaction. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT = 1314,
+
+ /**
+ * The signature made with the coin to be melted is invalid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID = 1315,
+
+ /**
+ * The size of the cut-and-choose dimension of the
+ * blinded coins request does not match #TALER_CNC_KAPPA.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_CNC_COIN_ARRAY_SIZE_INVALID = 1316,
+
+ /**
+ * The size of the cut-and-choose dimension of the
+ * transfer keys request does not match #TALER_CNC_KAPPA.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1317,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given coin from the database while generating an insufficient
+ * funds errors.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1318,
+
+ /**
+ * The provided transfer keys do not match up with the
+ * original commitment. Information about the original
+ * commitment is included in the response. This response is
+ * provided with HTTP status code MHD_HTTP_CONFLICT.
+ */
+ TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION = 1350,
+
+ /**
+ * Failed to blind the envelope to reconstruct the blinded
+ * coins for revealation checks.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_BLINDING_ERROR = 1351,
+
+ /**
+ * Failed to produce the blinded signatures over the coins
+ * to be returned.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_SIGNING_ERROR = 1352,
+
+ /**
+ * The exchange is unaware of the refresh sessino specified in
+ * the request.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN = 1353,
+
+ /**
+ * The exchange failed to retrieve valid session data from the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR = 1354,
+
+ /**
+ * The exchange failed to retrieve order data from the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR = 1355,
+
+ /**
+ * The exchange failed to retrieve transfer keys from the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR = 1356,
+
+ /**
+ * The exchange failed to retrieve commitment data from the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR = 1357,
+
+ /**
+ * The size of the cut-and-choose dimension of the
+ * private transfer keys request does not match #TALER_CNC_KAPPA - 1.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1358,
+
+
+ /**
+ * The coin specified in the link request is unknown to the exchange.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_REFRESH_LINK_COIN_UNKNOWN = 1400,
+
+
+ /**
+ * The exchange knows literally nothing about the coin we were asked
+ * to refund. But without a transaction history, we cannot issue a
+ * refund. This is kind-of OK, the owner should just refresh it
+ * directly without executing the refund. This response is provided
+ * with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_REFUND_COIN_NOT_FOUND = 1500,
+
+ /**
+ * We could not process the refund request as the coin's transaction
+ * history does not permit the requested refund at this time. The
+ * "history" in the response proves this. This response is provided
+ * with HTTP status code MHD_HTTP_CONFLICT.
+ */
+ TALER_EC_REFUND_CONFLICT = 1501,
+
+ /**
+ * The exchange knows about the coin we were asked to refund, but
+ * not about the specific /deposit operation. Hence, we cannot
+ * issue a refund (as we do not know if this merchant public key is
+ * authorized to do a refund). This response is provided with HTTP
+ * status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_REFUND_DEPOSIT_NOT_FOUND = 1503,
+ /**
+ * The currency specified for the refund is different from
+ * the currency of the coin. This response is provided with HTTP
+ * status code MHD_HTTP_PRECONDITION_FAILED.
+ */
+ TALER_EC_REFUND_CURRENCY_MISSMATCH = 1504,
+
+ /**
+ * When we tried to check if we already paid out the coin, the
+ * exchange's database suddenly disagreed with data it previously
+ * provided (internal inconsistency).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFUND_DB_INCONSISTENT = 1505,
+ /**
+ * The exchange can no longer refund the customer/coin as the
+ * money was already transferred (paid out) to the merchant.
+ * (It should be past the refund deadline.)
+ * This response is provided with HTTP status code
+ * MHD_HTTP_GONE.
+ */
+ TALER_EC_REFUND_MERCHANT_ALREADY_PAID = 1506,
+
+ /**
+ * The amount the exchange was asked to refund exceeds
+ * (with fees) the total amount of the deposit (including fees).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_PRECONDITION_FAILED.
+ */
+ TALER_EC_REFUND_INSUFFICIENT_FUNDS = 1507,
+
+ /**
+ * The exchange failed to recover information about the
+ * denomination key of the refunded coin (even though it
+ * recognizes the key). Hence it could not check the fee
+ * strucutre.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND = 1508,
+
+ /**
+ * The refund fee specified for the request is lower than
+ * the refund fee charged by the exchange for the given
+ * denomination key of the refunded coin.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFUND_FEE_TOO_LOW = 1509,
+
+ /**
+ * The exchange failed to store the refund information to
+ * its database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFUND_STORE_DB_ERROR = 1510,
+
+ /**
+ * The refund fee is specified in a different currency
+ * than the refund amount.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH = 1511,
+
+ /**
+ * The refunded amount is smaller than the refund fee,
+ * which would result in a negative refund.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFUND_FEE_ABOVE_AMOUNT = 1512,
+
+ /**
+ * The signature of the merchant is invalid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID = 1513,
+
+
+ /**
+ * The wire format specified in the "sender_account_details"
+ * is not understood or not supported by this exchange.
+ * Returned with an HTTP status code of MHD_HTTP_NOT_FOUND.
+ * (As we did not find an interpretation of the wire format.)
+ */
+ TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED = 1600,
+
+ /**
+ * The currency specified in the "amount" parameter is not
+ * supported by this exhange. Returned with an HTTP status
+ * code of MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED = 1601,
+
+ /**
+ * The exchange failed to store information about the incoming
+ * transfer in its database. This response is provided with HTTP
+ * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_ADMIN_ADD_INCOMING_DB_STORE = 1602,
+
+ /**
+ * The exchange encountered an error (that is not about not finding
+ * the wire transfer) trying to lookup a wire transfer identifier
+ * in the database. This response is provided with HTTP
+ * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED = 1700,
+
+ /**
+ * The exchange found internally inconsistent data when resolving a
+ * wire transfer identifier in the database. This response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT = 1701,
+
+ /**
+ * The exchange did not find information about the specified
+ * wire transfer identifier in the database. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND = 1702,
+
+
+ /**
+ * The exchange found internally inconsistent fee data when
+ * resolving a transaction in the database. This
+ * response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT = 1800,
+
+ /**
+ * The exchange encountered an error (that is not about not finding
+ * the transaction) trying to lookup a transaction
+ * in the database. This response is provided with HTTP
+ * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED = 1801,
+
+ /**
+ * The exchange did not find information about the specified
+ * transaction in the database. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_TRACK_TRANSACTION_NOT_FOUND = 1802,
+
+ /**
+ * The exchange failed to identify the wire transfer of the
+ * transaction (or information about the plan that it was supposed
+ * to still happen in the future). This response is provided with
+ * HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR = 1803,
+
+ /**
+ * The signature of the merchant is invalid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID = 1804,
+
+
+ /* ********** /test API error codes ************* */
+
+ /**
+ * The exchange failed to compute ECDH. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_ECDH_ERROR = 4000,
+
+ /**
+ * The EdDSA test signature is invalid. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_TEST_EDDSA_INVALID = 4001,
+
+ /**
+ * The exchange failed to compute the EdDSA test signature. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_EDDSA_ERROR = 4002,
+
+ /**
+ * The exchange failed to generate an RSA key. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_RSA_GEN_ERROR = 4003,
+
+ /**
+ * The exchange failed to compute the public RSA key. This response
+ * is provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_RSA_PUB_ERROR = 4004,
+
+ /**
+ * The exchange failed to compute the RSA signature. This response
+ * is provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_RSA_SIGN_ERROR = 4005,
+
+
+ /**
+ * End of error code range.
+ */
+ TALER_EC_END = 9999
+
};