-deduplicate

This commit is contained in:
Christian Grothoff 2022-05-17 12:12:52 +02:00
parent ccc7743fdd
commit 7bd1828482
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 107 additions and 153 deletions

View File

@ -99,45 +99,6 @@ struct BatchWithdrawContext
}; };
/**
* Send reserve history information to client with the
* message that we have insufficient funds for the
* requested withdraw operation.
*
* @param connection connection to the client
* @param ebalance expected balance based on our database
* @param withdraw_amount amount that the client requested to withdraw
* @param rh reserve history to return
* @return MHD result code
*/
static MHD_RESULT
reply_withdraw_insufficient_funds (
struct MHD_Connection *connection,
const struct TALER_Amount *ebalance,
const struct TALER_Amount *withdraw_amount,
const struct TALER_EXCHANGEDB_ReserveHistory *rh)
{
json_t *json_history;
json_history = TEH_RESPONSE_compile_reserve_history (rh);
if (NULL == json_history)
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS,
NULL);
return TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_CONFLICT,
TALER_JSON_pack_ec (TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS),
TALER_JSON_pack_amount ("balance",
ebalance),
TALER_JSON_pack_amount ("requested_amount",
withdraw_amount),
GNUNET_JSON_pack_array_steal ("history",
json_history));
}
/** /**
* Function implementing withdraw transaction. Runs the * Function implementing withdraw transaction. Runs the
* transaction logic; IF it returns a non-error code, the transaction * transaction logic; IF it returns a non-error code, the transaction
@ -195,47 +156,11 @@ batch_withdraw_transaction (void *cls,
} }
if (! balance_ok) if (! balance_ok)
{ {
/* FIXME: logic shared with normal withdraw
=> refactor and move to new TEH_responses function! */
struct TALER_EXCHANGEDB_ReserveHistory *rh;
struct TALER_Amount balance;
TEH_plugin->rollback (TEH_plugin->cls); TEH_plugin->rollback (TEH_plugin->cls);
// FIXME: maybe start read-committed here? *mhd_ret = TEH_RESPONSE_reply_reserve_insufficient_balance (
if (GNUNET_OK !=
TEH_plugin->start (TEH_plugin->cls,
"get_reserve_history on insufficient balance"))
{
GNUNET_break (0);
if (NULL != mhd_ret)
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_START_FAILED,
NULL);
return GNUNET_DB_STATUS_HARD_ERROR;
}
/* The reserve does not have the required amount (actual
* amount + withdraw fee) */
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
wc->reserve_pub,
&balance,
&rh);
if (NULL == rh)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"reserve history");
return GNUNET_DB_STATUS_HARD_ERROR;
}
*mhd_ret = reply_withdraw_insufficient_funds (
connection, connection,
&balance,
&wc->batch_total, &wc->batch_total,
rh); wc->reserve_pub);
TEH_plugin->free_reserve_history (TEH_plugin->cls,
rh);
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }

View File

@ -742,4 +742,91 @@ TEH_RESPONSE_compile_reserve_history (
} }
/**
* Send reserve history information to client with the
* message that we have insufficient funds for the
* requested withdraw operation.
*
* @param connection connection to the client
* @param ebalance expected balance based on our database
* @param withdraw_amount amount that the client requested to withdraw
* @param rh reserve history to return
* @return MHD result code
*/
static MHD_RESULT
reply_withdraw_insufficient_funds (
struct MHD_Connection *connection,
const struct TALER_Amount *ebalance,
const struct TALER_Amount *withdraw_amount,
const struct TALER_EXCHANGEDB_ReserveHistory *rh)
{
json_t *json_history;
json_history = TEH_RESPONSE_compile_reserve_history (rh);
if (NULL == json_history)
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS,
NULL);
return TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_CONFLICT,
TALER_JSON_pack_ec (TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS),
TALER_JSON_pack_amount ("balance",
ebalance),
TALER_JSON_pack_amount ("requested_amount",
withdraw_amount),
GNUNET_JSON_pack_array_steal ("history",
json_history));
}
MHD_RESULT
TEH_RESPONSE_reply_reserve_insufficient_balance (
struct MHD_Connection *connection,
const struct TALER_Amount *balance_required,
const struct TALER_ReservePublicKeyP *reserve_pub)
{
struct TALER_EXCHANGEDB_ReserveHistory *rh = NULL;
struct TALER_Amount balance;
enum GNUNET_DB_QueryStatus qs;
MHD_RESULT mhd_ret;
// FIXME: maybe start read-committed here?
if (GNUNET_OK !=
TEH_plugin->start (TEH_plugin->cls,
"get_reserve_history on insufficient balance"))
{
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_START_FAILED,
NULL);
}
/* The reserve does not have the required amount (actual
* amount + withdraw fee) */
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
reserve_pub,
&balance,
&rh);
TEH_plugin->rollback (TEH_plugin->cls);
if ( (qs < 0) ||
(NULL == rh) )
{
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"reserve history");
}
mhd_ret = reply_withdraw_insufficient_funds (
connection,
&balance,
balance_required,
rh);
TEH_plugin->free_reserve_history (TEH_plugin->cls,
rh);
return mhd_ret;
}
/* end of taler-exchange-httpd_responses.c */ /* end of taler-exchange-httpd_responses.c */

View File

@ -58,6 +58,22 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash (
const struct TALER_DenominationHashP *dph); const struct TALER_DenominationHashP *dph);
/**
* Return error message indicating that a reserve had
* an insufficient balance for the given operation.
*
* @param connection connection to the client
* @param balance_required the balance required for the operation
* @param reserve_pub the reserve with insufficient balance
* @return MHD result code
*/
MHD_RESULT
TEH_RESPONSE_reply_reserve_insufficient_balance (
struct MHD_Connection *connection,
const struct TALER_Amount *balance_required,
const struct TALER_ReservePublicKeyP *reserve_pub);
/** /**
* Send assertion that the given denomination key hash * Send assertion that the given denomination key hash
* is not usable (typically expired) at this time. * is not usable (typically expired) at this time.

View File

@ -33,45 +33,6 @@
#include "taler-exchange-httpd_keys.h" #include "taler-exchange-httpd_keys.h"
/**
* Send reserve history information to client with the
* message that we have insufficient funds for the
* requested withdraw operation.
*
* @param connection connection to the client
* @param ebalance expected balance based on our database
* @param withdraw_amount amount that the client requested to withdraw
* @param rh reserve history to return
* @return MHD result code
*/
static MHD_RESULT
reply_withdraw_insufficient_funds (
struct MHD_Connection *connection,
const struct TALER_Amount *ebalance,
const struct TALER_Amount *withdraw_amount,
const struct TALER_EXCHANGEDB_ReserveHistory *rh)
{
json_t *json_history;
json_history = TEH_RESPONSE_compile_reserve_history (rh);
if (NULL == json_history)
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS,
NULL);
return TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_CONFLICT,
TALER_JSON_pack_ec (TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS),
TALER_JSON_pack_amount ("balance",
ebalance),
TALER_JSON_pack_amount ("requested_amount",
withdraw_amount),
GNUNET_JSON_pack_array_steal ("history",
json_history));
}
/** /**
* Context for #withdraw_transaction. * Context for #withdraw_transaction.
*/ */
@ -178,48 +139,13 @@ withdraw_transaction (void *cls,
} }
if (! balance_ok) if (! balance_ok)
{ {
struct TALER_EXCHANGEDB_ReserveHistory *rh;
struct TALER_Amount balance;
TEH_plugin->rollback (TEH_plugin->cls); TEH_plugin->rollback (TEH_plugin->cls);
// FIXME: maybe start read-committed here? *mhd_ret = TEH_RESPONSE_reply_reserve_insufficient_balance (
if (GNUNET_OK !=
TEH_plugin->start (TEH_plugin->cls,
"get_reserve_history on insufficient balance"))
{
GNUNET_break (0);
if (NULL != mhd_ret)
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_START_FAILED,
NULL);
return GNUNET_DB_STATUS_HARD_ERROR;
}
/* The reserve does not have the required amount (actual
* amount + withdraw fee) */
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
&wc->collectable.reserve_pub,
&balance,
&rh);
if (NULL == rh)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"reserve history");
return GNUNET_DB_STATUS_HARD_ERROR;
}
*mhd_ret = reply_withdraw_insufficient_funds (
connection, connection,
&balance,
&wc->collectable.amount_with_fee, &wc->collectable.amount_with_fee,
rh); &wc->collectable.reserve_pub);
TEH_plugin->free_reserve_history (TEH_plugin->cls,
rh);
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if ( (TEH_KYC_NONE != TEH_kyc_config.mode) && if ( (TEH_KYC_NONE != TEH_kyc_config.mode) &&
(! wc->kyc.ok) && (! wc->kyc.ok) &&
(TALER_EXCHANGEDB_KYC_W2W == wc->kyc.type) ) (TALER_EXCHANGEDB_KYC_W2W == wc->kyc.type) )