properly handle GONE case on purse deposit
This commit is contained in:
parent
f9cc76ad3c
commit
d1c160d1b9
@ -1 +1 @@
|
|||||||
Subproject commit 20f8eb7a72e2160409f0f78264ec5198e9caa193
|
Subproject commit 149aa0a08d787419e02277ef231d93c6a0154a47
|
@ -201,6 +201,7 @@ create_transaction (void *cls,
|
|||||||
struct TEH_PurseDepositedCoin *coin = &pcc->coins[i];
|
struct TEH_PurseDepositedCoin *coin = &pcc->coins[i];
|
||||||
bool balance_ok = false;
|
bool balance_ok = false;
|
||||||
bool conflict = true;
|
bool conflict = true;
|
||||||
|
bool too_late = true;
|
||||||
|
|
||||||
qs = TEH_make_coin_known (&coin->cpi,
|
qs = TEH_make_coin_known (&coin->cpi,
|
||||||
connection,
|
connection,
|
||||||
@ -215,6 +216,7 @@ create_transaction (void *cls,
|
|||||||
&coin->coin_sig,
|
&coin->coin_sig,
|
||||||
&coin->amount_minus_fee,
|
&coin->amount_minus_fee,
|
||||||
&balance_ok,
|
&balance_ok,
|
||||||
|
&too_late,
|
||||||
&conflict);
|
&conflict);
|
||||||
if (qs <= 0)
|
if (qs <= 0)
|
||||||
{
|
{
|
||||||
@ -243,6 +245,15 @@ create_transaction (void *cls,
|
|||||||
&coin->cpi.coin_pub);
|
&coin->cpi.coin_pub);
|
||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
}
|
}
|
||||||
|
if (too_late)
|
||||||
|
{
|
||||||
|
*mhd_ret
|
||||||
|
= TALER_MHD_reply_with_ec (
|
||||||
|
connection,
|
||||||
|
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
|
||||||
|
"too late to deposit on purse creation");
|
||||||
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
}
|
||||||
if (conflict)
|
if (conflict)
|
||||||
{
|
{
|
||||||
struct TALER_Amount amount;
|
struct TALER_Amount amount;
|
||||||
|
@ -166,6 +166,7 @@ deposit_transaction (void *cls,
|
|||||||
struct TEH_PurseDepositedCoin *coin = &pcc->coins[i];
|
struct TEH_PurseDepositedCoin *coin = &pcc->coins[i];
|
||||||
bool balance_ok = false;
|
bool balance_ok = false;
|
||||||
bool conflict = true;
|
bool conflict = true;
|
||||||
|
bool too_late = true;
|
||||||
|
|
||||||
qs = TEH_make_coin_known (&coin->cpi,
|
qs = TEH_make_coin_known (&coin->cpi,
|
||||||
connection,
|
connection,
|
||||||
@ -180,6 +181,7 @@ deposit_transaction (void *cls,
|
|||||||
&coin->coin_sig,
|
&coin->coin_sig,
|
||||||
&coin->amount_minus_fee,
|
&coin->amount_minus_fee,
|
||||||
&balance_ok,
|
&balance_ok,
|
||||||
|
&too_late,
|
||||||
&conflict);
|
&conflict);
|
||||||
if (qs <= 0)
|
if (qs <= 0)
|
||||||
{
|
{
|
||||||
@ -204,9 +206,16 @@ deposit_transaction (void *cls,
|
|||||||
&coin->cpi.coin_pub);
|
&coin->cpi.coin_pub);
|
||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
}
|
}
|
||||||
// FIXME: there is also a 'conflict' case where the purse was already
|
if (too_late)
|
||||||
// decided (fully paid up OR expired), we should probably distinguish
|
{
|
||||||
// those better!
|
TEH_plugin->rollback (TEH_plugin->cls);
|
||||||
|
*mhd_ret
|
||||||
|
= TALER_MHD_reply_with_ec (
|
||||||
|
connection,
|
||||||
|
TALER_EC_EXCHANGE_PURSE_DEPOSIT_DECIDED_ALREADY,
|
||||||
|
NULL);
|
||||||
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
}
|
||||||
if (conflict)
|
if (conflict)
|
||||||
{
|
{
|
||||||
struct TALER_Amount amount;
|
struct TALER_Amount amount;
|
||||||
|
@ -26,6 +26,7 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_deposit(
|
|||||||
IN in_reserve_expiration INT8,
|
IN in_reserve_expiration INT8,
|
||||||
IN in_now INT8,
|
IN in_now INT8,
|
||||||
OUT out_balance_ok BOOLEAN,
|
OUT out_balance_ok BOOLEAN,
|
||||||
|
OUT out_late BOOLEAN,
|
||||||
OUT out_conflict BOOLEAN)
|
OUT out_conflict BOOLEAN)
|
||||||
LANGUAGE plpgsql
|
LANGUAGE plpgsql
|
||||||
AS $$
|
AS $$
|
||||||
@ -75,6 +76,7 @@ THEN
|
|||||||
THEN
|
THEN
|
||||||
-- Deposit exists, but with differences. Not allowed.
|
-- Deposit exists, but with differences. Not allowed.
|
||||||
out_balance_ok=FALSE;
|
out_balance_ok=FALSE;
|
||||||
|
out_late=FALSE;
|
||||||
out_conflict=TRUE;
|
out_conflict=TRUE;
|
||||||
RETURN;
|
RETURN;
|
||||||
END IF;
|
END IF;
|
||||||
@ -106,6 +108,7 @@ IF NOT FOUND
|
|||||||
THEN
|
THEN
|
||||||
-- Insufficient balance.
|
-- Insufficient balance.
|
||||||
out_balance_ok=FALSE;
|
out_balance_ok=FALSE;
|
||||||
|
out_late=FALSE;
|
||||||
out_conflict=FALSE;
|
out_conflict=FALSE;
|
||||||
RETURN;
|
RETURN;
|
||||||
END IF;
|
END IF;
|
||||||
@ -141,6 +144,8 @@ SELECT COALESCE(partner_serial_id,0)
|
|||||||
|
|
||||||
IF NOT FOUND
|
IF NOT FOUND
|
||||||
THEN
|
THEN
|
||||||
|
-- Purse was not yet merged. We are done.
|
||||||
|
out_late=FALSE;
|
||||||
RETURN;
|
RETURN;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
@ -159,6 +164,7 @@ SELECT
|
|||||||
OR (amount_with_fee_val < balance_val) ) );
|
OR (amount_with_fee_val < balance_val) ) );
|
||||||
IF NOT FOUND
|
IF NOT FOUND
|
||||||
THEN
|
THEN
|
||||||
|
out_late=FALSE;
|
||||||
RETURN;
|
RETURN;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
@ -175,10 +181,13 @@ ON CONFLICT DO NOTHING;
|
|||||||
|
|
||||||
IF NOT FOUND
|
IF NOT FOUND
|
||||||
THEN
|
THEN
|
||||||
out_conflict=TRUE;
|
-- Purse already decided, likely expired.
|
||||||
|
out_late=TRUE;
|
||||||
RETURN;
|
RETURN;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
out_late=FALSE;
|
||||||
|
|
||||||
IF (my_in_reserve_quota)
|
IF (my_in_reserve_quota)
|
||||||
THEN
|
THEN
|
||||||
UPDATE reserves
|
UPDATE reserves
|
||||||
@ -216,7 +225,7 @@ ELSE
|
|||||||
|
|
||||||
IF NOT FOUND
|
IF NOT FOUND
|
||||||
THEN
|
THEN
|
||||||
|
-- Reserve existed, thus UPDATE instead of INSERT.
|
||||||
UPDATE reserves
|
UPDATE reserves
|
||||||
SET
|
SET
|
||||||
current_balance_frac=current_balance_frac+my_amount_frac
|
current_balance_frac=current_balance_frac+my_amount_frac
|
||||||
@ -240,5 +249,3 @@ END IF;
|
|||||||
|
|
||||||
|
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ TEH_PG_do_purse_deposit (
|
|||||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||||
const struct TALER_Amount *amount_minus_fee,
|
const struct TALER_Amount *amount_minus_fee,
|
||||||
bool *balance_ok,
|
bool *balance_ok,
|
||||||
|
bool *too_late,
|
||||||
bool *conflict)
|
bool *conflict)
|
||||||
{
|
{
|
||||||
struct PostgresClosure *pg = cls;
|
struct PostgresClosure *pg = cls;
|
||||||
@ -57,6 +58,8 @@ TEH_PG_do_purse_deposit (
|
|||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_bool ("balance_ok",
|
GNUNET_PQ_result_spec_bool ("balance_ok",
|
||||||
balance_ok),
|
balance_ok),
|
||||||
|
GNUNET_PQ_result_spec_bool ("too_late",
|
||||||
|
too_late),
|
||||||
GNUNET_PQ_result_spec_bool ("conflict",
|
GNUNET_PQ_result_spec_bool ("conflict",
|
||||||
conflict),
|
conflict),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
@ -72,6 +75,7 @@ TEH_PG_do_purse_deposit (
|
|||||||
"SELECT "
|
"SELECT "
|
||||||
" out_balance_ok AS balance_ok"
|
" out_balance_ok AS balance_ok"
|
||||||
",out_conflict AS conflict"
|
",out_conflict AS conflict"
|
||||||
|
",out_late AS too_late"
|
||||||
" FROM exchange_do_purse_deposit"
|
" FROM exchange_do_purse_deposit"
|
||||||
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);");
|
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);");
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
* remaining balance is below @a amount;
|
* remaining balance is below @a amount;
|
||||||
* in this case, the return value will be
|
* in this case, the return value will be
|
||||||
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
|
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
|
||||||
|
* @param[out] too_late set to true if it is too late to deposit into the purse
|
||||||
* @param[out] conflict set to true if the deposit failed due to a conflict (coin already spent,
|
* @param[out] conflict set to true if the deposit failed due to a conflict (coin already spent,
|
||||||
* or deposited into this purse with a different amount)
|
* or deposited into this purse with a different amount)
|
||||||
* @return transaction status code
|
* @return transaction status code
|
||||||
@ -56,6 +57,7 @@ TEH_PG_do_purse_deposit (
|
|||||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||||
const struct TALER_Amount *amount_minus_fee,
|
const struct TALER_Amount *amount_minus_fee,
|
||||||
bool *balance_ok,
|
bool *balance_ok,
|
||||||
|
bool *too_late,
|
||||||
bool *conflict);
|
bool *conflict);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3465,7 +3465,8 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
*/
|
*/
|
||||||
enum GNUNET_DB_QueryStatus
|
enum GNUNET_DB_QueryStatus
|
||||||
(*batch2_reserves_in_insert)(void *cls,
|
(*batch2_reserves_in_insert)(void *cls,
|
||||||
const struct TALER_EXCHANGEDB_ReserveInInfo *reserves,
|
const struct
|
||||||
|
TALER_EXCHANGEDB_ReserveInInfo *reserves,
|
||||||
unsigned int reserves_length,
|
unsigned int reserves_length,
|
||||||
enum GNUNET_DB_QueryStatus *results);
|
enum GNUNET_DB_QueryStatus *results);
|
||||||
|
|
||||||
@ -5911,6 +5912,7 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
* remaining balance is below @a amount;
|
* remaining balance is below @a amount;
|
||||||
* in this case, the return value will be
|
* in this case, the return value will be
|
||||||
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
|
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
|
||||||
|
* @param[out] too_late it is too late to deposit into this purse
|
||||||
* @param[out] conflict the same coin was deposited into
|
* @param[out] conflict the same coin was deposited into
|
||||||
* this purse with a different amount already
|
* this purse with a different amount already
|
||||||
* @return transaction status code
|
* @return transaction status code
|
||||||
@ -5924,6 +5926,7 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||||
const struct TALER_Amount *amount_minus_fee,
|
const struct TALER_Amount *amount_minus_fee,
|
||||||
bool *balance_ok,
|
bool *balance_ok,
|
||||||
|
bool *too_late,
|
||||||
bool *conflict);
|
bool *conflict);
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "taler_util.h"
|
#include "taler_util.h"
|
||||||
#include "taler_crypto_lib.h"
|
|
||||||
|
|
||||||
extern uint8_t
|
extern uint8_t
|
||||||
get_age_group (
|
get_age_group (
|
||||||
|
Loading…
Reference in New Issue
Block a user