-implement reserve history DB logic
This commit is contained in:
parent
96fb11bed0
commit
4a5d71cca2
@ -96,6 +96,8 @@ reply_reserve_history_success (struct MHD_Connection *connection,
|
|||||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
TALER_EC_GENERIC_JSON_ALLOCATION_FAILURE,
|
TALER_EC_GENERIC_JSON_ALLOCATION_FAILURE,
|
||||||
NULL);
|
NULL);
|
||||||
|
/* FIXME: should set explicit cache control headers
|
||||||
|
for this response to enable caching! */
|
||||||
return TALER_MHD_REPLY_JSON_PACK (
|
return TALER_MHD_REPLY_JSON_PACK (
|
||||||
connection,
|
connection,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
@ -129,7 +131,45 @@ reserve_history_transaction (void *cls,
|
|||||||
struct ReserveHistoryContext *rsc = cls;
|
struct ReserveHistoryContext *rsc = cls;
|
||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
// FIXME: first deduct rsc->gf->fees.history from reserve balance (and persist the signature justifying this)
|
if (! TALER_amount_is_zero (&rsc->gf->fees.history))
|
||||||
|
{
|
||||||
|
bool balance_ok = false;
|
||||||
|
bool idempotent = true;
|
||||||
|
|
||||||
|
qs = TEH_plugin->insert_history_request (TEH_plugin->cls,
|
||||||
|
rsc->reserve_pub,
|
||||||
|
&rsc->reserve_sig,
|
||||||
|
rsc->timestamp,
|
||||||
|
&rsc->gf->fees.history,
|
||||||
|
&balance_ok,
|
||||||
|
&idempotent);
|
||||||
|
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
*mhd_ret
|
||||||
|
= TALER_MHD_reply_with_error (connection,
|
||||||
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
|
TALER_EC_GENERIC_DB_FETCH_FAILED,
|
||||||
|
"get_reserve_history");
|
||||||
|
}
|
||||||
|
if (qs <= 0)
|
||||||
|
{
|
||||||
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||||
|
return qs;
|
||||||
|
}
|
||||||
|
if (! balance_ok)
|
||||||
|
{
|
||||||
|
return TALER_MHD_reply_with_error (connection,
|
||||||
|
MHD_HTTP_CONFLICT,
|
||||||
|
TALER_EC_EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
if (idempotent)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"Idempotent /reserves/history request observed. Is caching working?\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
||||||
rsc->reserve_pub,
|
rsc->reserve_pub,
|
||||||
&rsc->balance,
|
&rsc->balance,
|
||||||
|
@ -3429,11 +3429,65 @@ CREATE OR REPLACE FUNCTION exchange_do_history_request(
|
|||||||
IN in_history_fee_val INT8,
|
IN in_history_fee_val INT8,
|
||||||
IN in_history_fee_frac INT4,
|
IN in_history_fee_frac INT4,
|
||||||
OUT out_balance_ok BOOLEAN,
|
OUT out_balance_ok BOOLEAN,
|
||||||
OUT out_conflict BOOLEAN)
|
OUT out_idempotent BOOLEAN)
|
||||||
LANGUAGE plpgsql
|
LANGUAGE plpgsql
|
||||||
AS $$
|
AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
-- FIXME
|
|
||||||
|
-- Insert and check for idempotency.
|
||||||
|
INSERT INTO history_requests
|
||||||
|
(reserve_pub
|
||||||
|
,request_timestamp
|
||||||
|
,reserve_sig
|
||||||
|
,history_fee_val
|
||||||
|
,history_fee_frac)
|
||||||
|
VALUES
|
||||||
|
(in_reserve_pub
|
||||||
|
,in_request_timestamp
|
||||||
|
,in_reserve_sig
|
||||||
|
,in_history_fee_val
|
||||||
|
,in_history_fee_frac)
|
||||||
|
ON CONFLICT DO NOTHING;
|
||||||
|
|
||||||
|
IF NOT FOUND
|
||||||
|
THEN
|
||||||
|
out_balance_ok=TRUE;
|
||||||
|
out_conflict=TRUE;
|
||||||
|
RETURN;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
out_conflict=FALSE;
|
||||||
|
|
||||||
|
-- Update reserve balance.
|
||||||
|
UPDATE reserves
|
||||||
|
SET
|
||||||
|
current_balance_frac=current_balance_frac-in_history_fee_frac
|
||||||
|
+ CASE
|
||||||
|
WHEN reserve_frac < in_history_fee_frac
|
||||||
|
THEN 100000000
|
||||||
|
ELSE 0
|
||||||
|
END,
|
||||||
|
current_balance_val=current_balance_val-in_history_fee_val
|
||||||
|
- CASE
|
||||||
|
WHEN current_balance_frac < in_history_fee_frac
|
||||||
|
THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
WHERE
|
||||||
|
reserve_pub=in_reserve_pub
|
||||||
|
AND ( (current_balance_val > in_history_fee_val) OR
|
||||||
|
( (current_balance_frac >= in_history_fee_frac) AND
|
||||||
|
(current_balance_val >= in_history_fee_val) ) );
|
||||||
|
|
||||||
|
IF NOT FOUND
|
||||||
|
THEN
|
||||||
|
-- Either reserve does not exist, or balance insufficient.
|
||||||
|
-- Both we treat the same here as balance insufficient.
|
||||||
|
out_balance_ok=FALSE;
|
||||||
|
RETURN;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
out_balance_ok=TRUE;
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
|
|
||||||
|
@ -3641,7 +3641,9 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
/* Used in #postgres_insert_history_request() */
|
/* Used in #postgres_insert_history_request() */
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"call_history_request",
|
"call_history_request",
|
||||||
"SELECT 1"
|
"SELECT"
|
||||||
|
" out_balance_ok AS balance_ok"
|
||||||
|
" ,out_idempotent AS idempotent"
|
||||||
" FROM exchange_do_history_request"
|
" FROM exchange_do_history_request"
|
||||||
" ($1, $2, $3, $4, $5)",
|
" ($1, $2, $3, $4, $5)",
|
||||||
5),
|
5),
|
||||||
@ -14014,6 +14016,9 @@ postgres_do_account_merge (
|
|||||||
* @param reserve_sig signature affirming the request
|
* @param reserve_sig signature affirming the request
|
||||||
* @param request_timestamp when was the request made
|
* @param request_timestamp when was the request made
|
||||||
* @param history_fee how much should the @a reserve_pub be charged for the request
|
* @param history_fee how much should the @a reserve_pub be charged for the request
|
||||||
|
* @param[out] balance_ok set to TRUE if the reserve balance
|
||||||
|
* was sufficient
|
||||||
|
* @param[out] idempotent set to TRUE if the request is already in the DB
|
||||||
* @return transaction status code
|
* @return transaction status code
|
||||||
*/
|
*/
|
||||||
static enum GNUNET_DB_QueryStatus
|
static enum GNUNET_DB_QueryStatus
|
||||||
@ -14021,11 +14026,31 @@ postgres_insert_history_request (
|
|||||||
void *cls,
|
void *cls,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
const struct TALER_ReserveSignatureP *reserve_sig,
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
struct GNUNET_TIME_Absolute request_timestamp,
|
struct GNUNET_TIME_Timestamp request_timestamp,
|
||||||
const struct TALER_Amount *history)
|
const struct TALER_Amount *history,
|
||||||
|
bool *balance_ok,
|
||||||
|
bool *idempotent)
|
||||||
{
|
{
|
||||||
GNUNET_break (0); // FIXME
|
struct PostgresClosure *pg = cls;
|
||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
|
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
|
||||||
|
GNUNET_PQ_query_param_auto_from_type (reserve_sig),
|
||||||
|
GNUNET_PQ_query_param_timestamp (&request_timestamp),
|
||||||
|
TALER_PQ_query_param_amount (history),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_bool ("balance_ok",
|
||||||
|
balance_ok),
|
||||||
|
GNUNET_PQ_result_spec_bool ("idempotent",
|
||||||
|
idempotent),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
|
||||||
|
"call_history_request",
|
||||||
|
params,
|
||||||
|
rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4864,6 +4864,9 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
* @param reserve_sig signature affirming the request
|
* @param reserve_sig signature affirming the request
|
||||||
* @param request_timestamp when was the request made
|
* @param request_timestamp when was the request made
|
||||||
* @param history_fee how much should the @a reserve_pub be charged for the request
|
* @param history_fee how much should the @a reserve_pub be charged for the request
|
||||||
|
* @param[out] balance_ok set to TRUE if the reserve balance
|
||||||
|
* was sufficient
|
||||||
|
* @param[out] idempotent set to TRUE if the request is already in the DB
|
||||||
* @return transaction status code
|
* @return transaction status code
|
||||||
*/
|
*/
|
||||||
enum GNUNET_DB_QueryStatus
|
enum GNUNET_DB_QueryStatus
|
||||||
@ -4871,8 +4874,10 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
void *cls,
|
void *cls,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
const struct TALER_ReserveSignatureP *reserve_sig,
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
struct GNUNET_TIME_Absolute request_timestamp,
|
struct GNUNET_TIME_Timestamp request_timestamp,
|
||||||
const struct TALER_Amount *history_fee);
|
const struct TALER_Amount *history_fee,
|
||||||
|
bool *balance_ok,
|
||||||
|
bool *idempotent);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user