-implemented bounded history for reserve status requests
This commit is contained in:
parent
bf9b7e168b
commit
36a8ecd4c4
@ -58,6 +58,18 @@ struct ReserveStatusContext
|
||||
*/
|
||||
struct TALER_EXCHANGEDB_KycStatus kyc;
|
||||
|
||||
/**
|
||||
* Sum of incoming transactions within the returned history.
|
||||
* (currently not used).
|
||||
*/
|
||||
struct TALER_Amount balance_in;
|
||||
|
||||
/**
|
||||
* Sum of outgoing transactions within the returned history.
|
||||
* (currently not used).
|
||||
*/
|
||||
struct TALER_Amount balance_out;
|
||||
|
||||
/**
|
||||
* Current reserve balance.
|
||||
*/
|
||||
@ -135,10 +147,11 @@ reserve_status_transaction (void *cls,
|
||||
"inselect_wallet_status");
|
||||
return qs;
|
||||
}
|
||||
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
||||
rsc->reserve_pub,
|
||||
&rsc->balance,
|
||||
&rsc->rh);
|
||||
qs = TEH_plugin->get_reserve_status (TEH_plugin->cls,
|
||||
rsc->reserve_pub,
|
||||
&rsc->balance_in,
|
||||
&rsc->balance_out,
|
||||
&rsc->rh);
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -148,6 +161,18 @@ reserve_status_transaction (void *cls,
|
||||
TALER_EC_GENERIC_DB_FETCH_FAILED,
|
||||
"get_reserve_status");
|
||||
}
|
||||
qs = TEH_plugin->get_reserve_balance (TEH_plugin->cls,
|
||||
rsc->reserve_pub,
|
||||
&rsc->balance);
|
||||
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_balance");
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
|
||||
|
@ -815,6 +815,42 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" SELECT wire_source_h_payto FROM ri "
|
||||
"); ",
|
||||
1),
|
||||
/* Used in #postgres_get_reserve_status() to obtain inbound transactions
|
||||
for a reserve */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"reserves_in_get_transactions_truncated",
|
||||
/*
|
||||
"SELECT"
|
||||
" wire_reference"
|
||||
",credit_val"
|
||||
",credit_frac"
|
||||
",execution_date"
|
||||
",payto_uri AS sender_account_details"
|
||||
" FROM reserves_in"
|
||||
" JOIN wire_targets"
|
||||
" ON (wire_source_h_payto = wire_target_h_payto)"
|
||||
" WHERE reserve_pub=$1"
|
||||
" AND execution_date>=$2;",
|
||||
*/
|
||||
"WITH ri AS MATERIALIZED ( "
|
||||
" SELECT * "
|
||||
" FROM reserves_in "
|
||||
" WHERE reserve_pub = $1 "
|
||||
") "
|
||||
"SELECT "
|
||||
" wire_reference "
|
||||
" ,credit_val "
|
||||
" ,credit_frac "
|
||||
" ,execution_date "
|
||||
" ,payto_uri AS sender_account_details "
|
||||
"FROM wire_targets "
|
||||
"JOIN ri "
|
||||
" ON (wire_target_h_payto = wire_source_h_payto) "
|
||||
"WHERE execution_date >= $2"
|
||||
" AND wire_target_h_payto = ( "
|
||||
" SELECT wire_source_h_payto FROM ri "
|
||||
"); ",
|
||||
2),
|
||||
/* Used in #postgres_do_withdraw() to store
|
||||
the signature of a blinded coin with the blinded coin's
|
||||
details before returning it during /reserve/withdraw. We store
|
||||
@ -1020,6 +1056,58 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
"JOIN denominations denom "
|
||||
" ON (ro.denominations_serial = denom.denominations_serial); ",
|
||||
1),
|
||||
/* Used during #postgres_get_reserve_status() to
|
||||
obtain all of the /reserve/withdraw operations that
|
||||
have been performed on a given reserve. (i.e. to
|
||||
demonstrate double-spending) */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"get_reserves_out_truncated",
|
||||
/*
|
||||
"SELECT"
|
||||
" ro.h_blind_ev"
|
||||
",denom.denom_pub_hash"
|
||||
",ro.denom_sig"
|
||||
",ro.reserve_sig"
|
||||
",ro.execution_date"
|
||||
",ro.amount_with_fee_val"
|
||||
",ro.amount_with_fee_frac"
|
||||
",denom.fee_withdraw_val"
|
||||
",denom.fee_withdraw_frac"
|
||||
" FROM reserves res"
|
||||
" JOIN reserves_out_by_reserve ror"
|
||||
" ON (res.reserve_uuid = ror.reserve_uuid)"
|
||||
" JOIN reserves_out ro"
|
||||
" ON (ro.h_blind_ev = ror.h_blind_ev)"
|
||||
" JOIN denominations denom"
|
||||
" ON (ro.denominations_serial = denom.denominations_serial)"
|
||||
" WHERE res.reserve_pub=$1"
|
||||
" AND execution_date>=$2;",
|
||||
*/
|
||||
"WITH robr AS MATERIALIZED ( "
|
||||
" SELECT h_blind_ev "
|
||||
" FROM reserves_out_by_reserve "
|
||||
" WHERE reserve_uuid= ( "
|
||||
" SELECT reserve_uuid "
|
||||
" FROM reserves "
|
||||
" WHERE reserve_pub = $1 "
|
||||
" ) "
|
||||
") SELECT "
|
||||
" ro.h_blind_ev "
|
||||
" ,denom.denom_pub_hash "
|
||||
" ,ro.denom_sig "
|
||||
" ,ro.reserve_sig "
|
||||
" ,ro.execution_date "
|
||||
" ,ro.amount_with_fee_val "
|
||||
" ,ro.amount_with_fee_frac "
|
||||
" ,denom.fee_withdraw_val "
|
||||
" ,denom.fee_withdraw_frac "
|
||||
"FROM robr "
|
||||
"JOIN reserves_out ro "
|
||||
" ON (ro.h_blind_ev = robr.h_blind_ev) "
|
||||
"JOIN denominations denom "
|
||||
" ON (ro.denominations_serial = denom.denominations_serial)"
|
||||
" WHERE ro.execution_date>=$2;",
|
||||
2),
|
||||
/* Used in #postgres_select_withdrawals_above_serial_id() */
|
||||
|
||||
GNUNET_PQ_make_prepare (
|
||||
@ -2240,6 +2328,51 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" JOIN exchange_do_recoup_by_reserve($1) robr"
|
||||
" USING (denominations_serial);",
|
||||
1),
|
||||
/* Used in #postgres_get_reserve_status() to obtain recoup transactions
|
||||
for a reserve - query optimization should be disabled i.e.
|
||||
BEGIN; SET LOCAL join_collapse_limit=1; query; COMMIT; */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"recoup_by_reserve_truncated",
|
||||
/*
|
||||
"SELECT"
|
||||
" recoup.coin_pub"
|
||||
",recoup.coin_sig"
|
||||
",recoup.coin_blind"
|
||||
",recoup.amount_val"
|
||||
",recoup.amount_frac"
|
||||
",recoup.recoup_timestamp"
|
||||
",denominations.denom_pub_hash"
|
||||
",known_coins.denom_sig"
|
||||
" FROM denominations"
|
||||
" JOIN (known_coins"
|
||||
" JOIN recoup "
|
||||
" ON (recoup.coin_pub = known_coins.coin_pub))"
|
||||
" ON (known_coins.denominations_serial = denominations.denominations_serial)"
|
||||
" WHERE recoup_timestamp>=$2"
|
||||
" AND recoup.coin_pub"
|
||||
" IN (SELECT coin_pub"
|
||||
" FROM recoup_by_reserve"
|
||||
" JOIN (reserves_out"
|
||||
" JOIN (reserves_out_by_reserve"
|
||||
" JOIN reserves"
|
||||
" ON (reserves.reserve_uuid = reserves_out_by_reserve.reserve_uuid))"
|
||||
" ON (reserves_out_by_reserve.h_blind_ev = reserves_out.h_blind_ev))"
|
||||
" ON (recoup_by_reserve.reserve_out_serial_id = reserves_out.reserve_out_serial_id)"
|
||||
" WHERE reserves.reserve_pub=$1);",
|
||||
*/
|
||||
"SELECT robr.coin_pub "
|
||||
" ,robr.coin_sig "
|
||||
" ,robr.coin_blind "
|
||||
" ,robr.amount_val "
|
||||
" ,robr.amount_frac "
|
||||
" ,robr.recoup_timestamp "
|
||||
" ,denominations.denom_pub_hash "
|
||||
" ,robr.denom_sig "
|
||||
"FROM denominations "
|
||||
" JOIN exchange_do_recoup_by_reserve($1) robr"
|
||||
" USING (denominations_serial)"
|
||||
" WHERE recoup_timestamp>=$2;",
|
||||
2),
|
||||
/* Used in #postgres_get_coin_transactions() to obtain recoup transactions
|
||||
affecting old coins of refreshed coins */
|
||||
GNUNET_PQ_make_prepare (
|
||||
@ -2282,6 +2415,23 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" USING (wire_target_h_payto)"
|
||||
" WHERE reserve_pub=$1;",
|
||||
1),
|
||||
/* Used in #postgres_get_reserve_status() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"close_by_reserve_truncated",
|
||||
"SELECT"
|
||||
" amount_val"
|
||||
",amount_frac"
|
||||
",closing_fee_val"
|
||||
",closing_fee_frac"
|
||||
",execution_date"
|
||||
",payto_uri AS receiver_account"
|
||||
",wtid"
|
||||
" FROM reserves_close"
|
||||
" JOIN wire_targets"
|
||||
" USING (wire_target_h_payto)"
|
||||
" WHERE reserve_pub=$1"
|
||||
" AND execution_date>=$2;",
|
||||
2),
|
||||
/* Used in #postgres_get_reserve_history() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"merge_by_reserve",
|
||||
@ -2311,6 +2461,36 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" AND pr.finished"
|
||||
" AND NOT pr.refunded;",
|
||||
1),
|
||||
/* Used in #postgres_get_reserve_status() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"merge_by_reserve_truncated",
|
||||
"SELECT"
|
||||
" pr.amount_with_fee_val"
|
||||
",pr.amount_with_fee_frac"
|
||||
",pr.balance_val"
|
||||
",pr.balance_frac"
|
||||
",pr.purse_fee_val"
|
||||
",pr.purse_fee_frac"
|
||||
",pr.h_contract_terms"
|
||||
",pr.merge_pub"
|
||||
",am.reserve_sig"
|
||||
",pm.purse_pub"
|
||||
",pm.merge_timestamp"
|
||||
",pr.purse_expiration"
|
||||
",pr.age_limit"
|
||||
",pr.flags"
|
||||
" FROM purse_merges pm"
|
||||
" JOIN purse_requests pr"
|
||||
" USING (purse_pub)"
|
||||
" JOIN account_merges am"
|
||||
" ON (am.purse_pub = pm.purse_pub AND"
|
||||
" am.reserve_pub = pm.reserve_pub)"
|
||||
" WHERE pm.reserve_pub=$1"
|
||||
" AND pm.merge_timestamp >= $2"
|
||||
" AND pm.partner_serial_id=0" /* must be local! */
|
||||
" AND pr.finished"
|
||||
" AND NOT pr.refunded;",
|
||||
2),
|
||||
/* Used in #postgres_get_reserve_history() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"history_by_reserve",
|
||||
@ -2322,6 +2502,18 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" FROM history_requests"
|
||||
" WHERE reserve_pub=$1;",
|
||||
1),
|
||||
/* Used in #postgres_get_reserve_status() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"history_by_reserve_truncated",
|
||||
"SELECT"
|
||||
" history_fee_val"
|
||||
",history_fee_frac"
|
||||
",request_timestamp"
|
||||
",reserve_sig"
|
||||
" FROM history_requests"
|
||||
" WHERE reserve_pub=$1"
|
||||
" AND request_timestamp>=$2;",
|
||||
2),
|
||||
/* Used in #postgres_get_expired_reserves() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"get_expired_reserves",
|
||||
@ -7031,14 +7223,18 @@ postgres_get_reserve_history (void *cls,
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param reserve_pub public key of the reserve
|
||||
* @param[out] balance set to the reserve balance
|
||||
* @param[out] balance_in set to the total of inbound
|
||||
* transactions in the returned history
|
||||
* @param[out] balance_out set to the total of outbound
|
||||
* transactions in the returned history
|
||||
* @param[out] rhp set to known transaction history (NULL if reserve is unknown)
|
||||
* @return transaction status
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
postgres_get_reserve_status (void *cls,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
struct TALER_Amount *balance,
|
||||
struct TALER_Amount *balance_in,
|
||||
struct TALER_Amount *balance_out,
|
||||
struct TALER_EXCHANGEDB_ReserveHistory **rhp)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
@ -7055,33 +7251,39 @@ postgres_get_reserve_status (void *cls,
|
||||
GNUNET_PQ_PostgresResultHandler cb;
|
||||
} work[] = {
|
||||
/** #TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE */
|
||||
{ "reserves_in_get_transactions",
|
||||
{ "reserves_in_get_transactions_truncated",
|
||||
add_bank_to_exchange },
|
||||
/** #TALER_EXCHANGEDB_RO_WITHDRAW_COIN */
|
||||
{ "get_reserves_out",
|
||||
{ "get_reserves_out_truncated",
|
||||
&add_withdraw_coin },
|
||||
/** #TALER_EXCHANGEDB_RO_RECOUP_COIN */
|
||||
{ "recoup_by_reserve",
|
||||
{ "recoup_by_reserve_truncated",
|
||||
&add_recoup },
|
||||
/** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */
|
||||
{ "close_by_reserve",
|
||||
{ "close_by_reserve_truncated",
|
||||
&add_exchange_to_bank },
|
||||
/** #TALER_EXCHANGEDB_RO_PURSE_MERGE */
|
||||
{ "merge_by_reserve",
|
||||
{ "merge_by_reserve_truncated",
|
||||
&add_p2p_merge },
|
||||
/** #TALER_EXCHANGEDB_RO_HISTORY_REQUEST */
|
||||
{ "history_by_reserve",
|
||||
{ "history_by_reserve_truncated",
|
||||
&add_history_requests },
|
||||
/* List terminator */
|
||||
{ NULL,
|
||||
NULL }
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
struct GNUNET_TIME_Absolute timelimit;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
|
||||
GNUNET_PQ_query_param_absolute_time (&timelimit),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
timelimit = GNUNET_TIME_absolute_subtract (
|
||||
GNUNET_TIME_absolute_get (),
|
||||
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_WEEKS,
|
||||
5));
|
||||
/* FIXME: actually implement reserve history truncation logic! */
|
||||
rhc.reserve_pub = reserve_pub;
|
||||
rhc.rh = NULL;
|
||||
@ -7119,10 +7321,8 @@ postgres_get_reserve_status (void *cls,
|
||||
}
|
||||
}
|
||||
*rhp = rhc.rh;
|
||||
GNUNET_assert (0 <=
|
||||
TALER_amount_subtract (balance,
|
||||
&rhc.balance_in,
|
||||
&rhc.balance_out));
|
||||
*balance_in = rhc.balance_in;
|
||||
*balance_out = rhc.balance_out;
|
||||
return qs;
|
||||
}
|
||||
|
||||
|
@ -3442,14 +3442,18 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param reserve_pub public key of the reserve
|
||||
* @param[out] balance set to the reserve balance
|
||||
* @param[out] balance_in set to the total of inbound
|
||||
* transactions in the returned history
|
||||
* @param[out] balance_out set to the total of outbound
|
||||
* transactions in the returned history
|
||||
* @param[out] rhp set to known transaction history (NULL if reserve is unknown)
|
||||
* @return transaction status
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*get_reserve_status)(void *cls,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
struct TALER_Amount *balance,
|
||||
struct TALER_Amount *balance_in,
|
||||
struct TALER_Amount *balance_out,
|
||||
struct TALER_EXCHANGEDB_ReserveHistory **rhp);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user