summaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-06-23 14:13:54 +0200
committerChristian Grothoff <christian@grothoff.org>2017-06-23 14:13:54 +0200
commitff8633910d90d7c5299016bce7a8ea49e12510a7 (patch)
tree77030f63722592396c226433ad00cdd410f0a105 /src/exchange
parentd4884c0c605db10934f7bb378072a21ecb523d12 (diff)
downloadexchange-ff8633910d90d7c5299016bce7a8ea49e12510a7.tar.gz
exchange-ff8633910d90d7c5299016bce7a8ea49e12510a7.tar.bz2
exchange-ff8633910d90d7c5299016bce7a8ea49e12510a7.zip
adapt /admin/add/incoming to #5010
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/taler-exchange-httpd_admin.c170
1 files changed, 102 insertions, 68 deletions
diff --git a/src/exchange/taler-exchange-httpd_admin.c b/src/exchange/taler-exchange-httpd_admin.c
index e40775f51..83bfedf8b 100644
--- a/src/exchange/taler-exchange-httpd_admin.c
+++ b/src/exchange/taler-exchange-httpd_admin.c
@@ -28,66 +28,96 @@
/**
+ * Closure for #admin_add_incoming_transaction()
+ */
+struct AddIncomingContext
+{
+ /**
+ * public key of the reserve
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * amount to add to the reserve
+ */
+ struct TALER_Amount amount;
+
+ /**
+ * When did we receive the wire transfer
+ */
+ struct GNUNET_TIME_Absolute execution_time;
+
+ /**
+ * which account send the funds
+ */
+ json_t *sender_account_details;
+
+ /**
+ * Information that uniquely identifies the transfer
+ */
+ json_t *transfer_details;
+
+ /**
+ * Set to the transaction status.
+ */
+ enum GNUNET_DB_QueryStatus qs;
+};
+
+
+/**
* Add an incoming transaction to the database. Checks if the
* transaction is fresh (not a duplicate) and if so adds it to
* the database.
*
- * @param connection the MHD connection to handle
- * @param reserve_pub public key of the reserve
- * @param amount amount to add to the reserve
- * @param execution_time when did we receive the wire transfer
- * @param sender_account_details which account send the funds
- * @param transfer_details information that uniquely identifies the transfer
- * @return MHD result code
+ * If it returns a non-error code, the transaction logic MUST
+ * NOT queue a MHD response. IF it returns an hard error, the
+ * transaction logic MUST queue a MHD response and set @a mhd_ret. IF
+ * it returns the soft error code, the function MAY be called again to
+ * retry and MUST not queue a MHD response.
+ *
+ * @param cls closure with the `struct AddIncomingContext *`
+ * @param connection MHD request which triggered the transaction
+ * @param session database session to use
+ * @param[out] mhd_ret set to MHD response status for @a connection,
+ * if transaction failed (!)
+ * @return transaction status
*/
-static int
-execute_admin_add_incoming (struct MHD_Connection *connection,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_Amount *amount,
- struct GNUNET_TIME_Absolute execution_time,
- const json_t *sender_account_details,
- const json_t *transfer_details)
+static enum GNUNET_DB_QueryStatus
+admin_add_incoming_transaction (void *cls,
+ struct MHD_Connection *connection,
+ struct TALER_EXCHANGEDB_Session *session,
+ int *mhd_ret)
{
- struct TALER_EXCHANGEDB_Session *session;
- int ret;
+ struct AddIncomingContext *aic = cls;
void *json_str;
- if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
- {
- GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DB_SETUP_FAILED);
- }
- json_str = json_dumps (transfer_details,
+ json_str = json_dumps (aic->transfer_details,
JSON_INDENT(2));
if (NULL == json_str)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PARSER_OUT_OF_MEMORY);
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_PARSER_OUT_OF_MEMORY);
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
- ret = TEH_plugin->reserves_in_insert (TEH_plugin->cls,
- session,
- reserve_pub,
- amount,
- execution_time,
- sender_account_details,
- json_str,
- strlen (json_str));
+ aic->qs = TEH_plugin->reserves_in_insert (TEH_plugin->cls,
+ session,
+ &aic->reserve_pub,
+ &aic->amount,
+ aic->execution_time,
+ aic->sender_account_details,
+ json_str,
+ strlen (json_str));
free (json_str);
- if (GNUNET_SYSERR == ret)
+
+ if (GNUNET_DB_STATUS_HARD_ERROR == aic->qs)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_ADMIN_ADD_INCOMING_DB_STORE);
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_ADMIN_ADD_INCOMING_DB_STORE);
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:s}",
- "status",
- (GNUNET_OK == ret)
- ? "NEW"
- : "DUP");
+ return aic->qs;
}
@@ -110,23 +140,20 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
const char *upload_data,
size_t *upload_data_size)
{
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_Amount amount;
- struct GNUNET_TIME_Absolute at;
+ struct AddIncomingContext aic;
enum TALER_ErrorCode ec;
char *emsg;
- json_t *sender_account_details;
- json_t *transfer_details;
json_t *root;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("reserve_pub", &reserve_pub),
- TALER_JSON_spec_amount ("amount", &amount),
- GNUNET_JSON_spec_absolute_time ("execution_date", &at),
- GNUNET_JSON_spec_json ("sender_account_details", &sender_account_details),
- GNUNET_JSON_spec_json ("transfer_details", &transfer_details),
+ GNUNET_JSON_spec_fixed_auto ("reserve_pub", &aic.reserve_pub),
+ TALER_JSON_spec_amount ("amount", &aic.amount),
+ GNUNET_JSON_spec_absolute_time ("execution_date", &aic.execution_time),
+ GNUNET_JSON_spec_json ("sender_account_details", &aic.sender_account_details),
+ GNUNET_JSON_spec_json ("transfer_details", &aic.transfer_details),
GNUNET_JSON_spec_end ()
};
int res;
+ int mhd_ret;
res = TEH_PARSE_post_json (connection,
connection_cls,
@@ -135,7 +162,8 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
&root);
if (GNUNET_SYSERR == res)
return MHD_NO;
- if ( (GNUNET_NO == res) || (NULL == root) )
+ if ( (GNUNET_NO == res) ||
+ (NULL == root) )
return MHD_YES;
res = TEH_PARSE_json_data (connection,
root,
@@ -148,37 +176,43 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
}
if (TALER_EC_NONE !=
- (ec = TEH_json_validate_wireformat (sender_account_details,
+ (ec = TEH_json_validate_wireformat (aic.sender_account_details,
GNUNET_NO,
&emsg)))
{
GNUNET_JSON_parse_free (spec);
- res = TEH_RESPONSE_reply_external_error (connection,
- ec,
- emsg);
+ mhd_ret = TEH_RESPONSE_reply_external_error (connection,
+ ec,
+ emsg);
GNUNET_free (emsg);
- return res;
+ return mhd_ret;
}
- if (0 != strcasecmp (amount.currency,
+ if (0 != strcasecmp (aic.amount.currency,
TEH_exchange_currency_string))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Exchange uses currency `%s', but /admin/add/incoming tried to use currency `%s'\n",
TEH_exchange_currency_string,
- amount.currency);
+ aic.amount.currency);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED,
"amount:currency");
}
- res = execute_admin_add_incoming (connection,
- &reserve_pub,
- &amount,
- at,
- sender_account_details,
- transfer_details);
+ res = TEH_DB_run_transaction (connection,
+ &mhd_ret,
+ &admin_add_incoming_transaction,
+ &aic);
GNUNET_JSON_parse_free (spec);
- return res;
+ if (GNUNET_OK != res)
+ return mhd_ret;
+ return TEH_RESPONSE_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:s}",
+ "status",
+ (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == aic.qs)
+ ? "NEW"
+ : "DUP");
}
/* end of taler-exchange-httpd_admin.c */