finish sync_denomination() implementation

This commit is contained in:
Christian Grothoff 2017-03-18 23:03:00 +01:00
parent 0f5ce284c4
commit e4a4a7e193
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 68 additions and 108 deletions

View File

@ -26,7 +26,6 @@
*
* TODO:
* - FIXME: do proper transaction history check in #check_transaction_history()
* - COMPLETE: deal with risk / expired denomination keys in #sync_denomination()
* - SANITY: rename functions/operations to better describe what they do!
* - OPTIMIZE/SIMPLIFY: modify auditordb to return DK when we inquire about deposit/refresh/refund,
* so we can avoid the costly #get_coin_summary with the transaction history building
@ -57,6 +56,11 @@
*/
#define MAX_COIN_SUMMARIES 4
/**
* Use a 1 day grace period to deal with clocks not being perfectly synchronized.
*/
#define DEPOSIT_GRACE_PERIOD GNUNET_TIME_UNIT_DAYS
/**
* Return value from main().
*/
@ -305,11 +309,11 @@ get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub,
dkip = GNUNET_CONTAINER_multihashmap_get (denominations,
dh);
if (NULL != dkip)
{
/* cache hit */
*dki = dkip;
return GNUNET_OK;
}
{
/* cache hit */
*dki = dkip;
return GNUNET_OK;
}
dkip = GNUNET_new (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
ret = edb->get_denomination_info (edb->cls,
esession,
@ -1018,6 +1022,11 @@ struct DenominationSummary
*/
struct TALER_Amount denom_risk;
/**
* Denomination key information for this denomination.
*/
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki;
/**
* #GNUNET_YES if this record already existed in the DB.
* Used to decide between insert/update in
@ -1133,11 +1142,13 @@ init_denomination (const struct GNUNET_HashCode *denom_hash,
* Obtain the denomination summary for the given @a dh
*
* @param cc our execution context
* @param dki denomination key information for @a dh
* @param dh the denomination hash to use for the lookup
* @return NULL on error
*/
static struct DenominationSummary *
get_denomination_summary (struct CoinContext *cc,
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki,
const struct GNUNET_HashCode *dh)
{
struct DenominationSummary *ds;
@ -1147,6 +1158,7 @@ get_denomination_summary (struct CoinContext *cc,
if (NULL != ds)
return ds;
ds = GNUNET_new (struct DenominationSummary);
ds->dki = dki;
if (GNUNET_OK !=
init_denomination (dh,
ds))
@ -1181,13 +1193,21 @@ sync_denomination (void *cls,
{
struct CoinContext *cc = cls;
struct DenominationSummary *ds = value;
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki = ds->dki;
struct GNUNET_TIME_Absolute now;
struct GNUNET_TIME_Absolute expire_deposit;
struct GNUNET_TIME_Absolute expire_deposit_grace;
int ret;
// COMPLETE: if expired, insert remaining balance historic denomination revenue,
// DELETE denomination balance, and REDUCE cc->risk exposure!
if (0 /* COMPLETE: add expiration check! */)
now = GNUNET_TIME_absolute_get ();
expire_deposit = GNUNET_TIME_absolute_ntoh (dki->properties.expire_deposit);
/* add day grace period to deal with clocks not being perfectly synchronized */
expire_deposit_grace = GNUNET_TIME_absolute_add (expire_deposit,
DEPOSIT_GRACE_PERIOD);
if (now.abs_value_us > expire_deposit_grace.abs_value_us)
{
/* Denominationkey has expired, book remaining balance of
outstanding coins as revenue; and reduce cc->risk exposure. */
if (ds->in_db)
ret = adb->del_denomination_balance (adb->cls,
asession,
@ -1195,9 +1215,7 @@ sync_denomination (void *cls,
else
ret = GNUNET_OK;
if ( (GNUNET_OK == ret) &&
( (0 != ds->denom_balance.value) ||
(0 != ds->denom_balance.fraction) ||
(0 != ds->denom_risk.value) ||
( (0 != ds->denom_risk.value) ||
(0 != ds->denom_risk.fraction) ) )
{
/* The denomination expired and carried a balance; we can now
@ -1214,8 +1232,25 @@ sync_denomination (void *cls,
cc->ret = GNUNET_SYSERR;
return GNUNET_OK;
}
// TODO: book denom_balance expiration profits!
}
if ( (GNUNET_OK == ret) &&
( (0 != ds->denom_balance.value) ||
(0 != ds->denom_balance.fraction) ) )
{
/* book denom_balance coin expiration profits! */
if (GNUNET_OK !=
adb->insert_historic_denom_revenue (adb->cls,
asession,
&master_pub,
denom_hash,
expire_deposit,
&ds->denom_balance))
{
/* Failed to store profits? Bad database */
GNUNET_break (0);
cc->ret = GNUNET_SYSERR;
return GNUNET_OK;
}
}
}
else
@ -1412,6 +1447,7 @@ withdraw_cb (void *cls,
return GNUNET_SYSERR;
}
ds = get_denomination_summary (cc,
dki,
&dh);
TALER_amount_ntoh (&value,
&dki->properties.value);
@ -1590,6 +1626,7 @@ refresh_session_cb (void *cls,
struct TALER_Amount value;
dsi = get_denomination_summary (cc,
new_dki[i],
&new_dki[i]->properties.denom_hash);
TALER_amount_ntoh (&value,
&new_dki[i]->properties.value);
@ -1614,6 +1651,7 @@ refresh_session_cb (void *cls,
/* update old coin's denomination balance */
dso = get_denomination_summary (cc,
dki,
&dki->properties.denom_hash);
if (GNUNET_OK !=
TALER_amount_subtract (&dso->denom_balance,
@ -1729,6 +1767,7 @@ deposit_cb (void *cls,
/* update old coin's denomination balance */
ds = get_denomination_summary (cc,
dki,
&dki->properties.denom_hash);
if (GNUNET_OK !=
TALER_amount_subtract (&ds->denom_balance,
@ -1842,6 +1881,7 @@ refund_cb (void *cls,
/* update coin's denomination balance */
ds = get_denomination_summary (cc,
dki,
&dki->properties.denom_hash);
if (GNUNET_OK !=
TALER_amount_add (&ds->denom_balance,

View File

@ -375,15 +375,7 @@ postgres_create_tables (void *cls)
",revenue_balance_val INT8 NOT NULL"
",revenue_balance_frac INT4 NOT NULL"
",revenue_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
",deposit_fee_balance_val INT8 NOT NULL"
",deposit_fee_balance_frac INT4 NOT NULL"
",deposit_fee_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
",melt_fee_balance_val INT8 NOT NULL"
",melt_fee_balance_frac INT4 NOT NULL"
",melt_fee_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
",refund_fee_balance_val INT8 NOT NULL"
",refund_fee_balance_frac INT4 NOT NULL"
",refund_fee_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ")");
")");
/* Table with historic losses; basically, when we need to
@ -779,17 +771,8 @@ postgres_prepare (PGconn *db_conn)
",revenue_balance_val"
",revenue_balance_frac"
",revenue_balance_curr"
",deposit_fee_balance_val"
",deposit_fee_balance_frac"
",deposit_fee_balance_curr"
",melt_fee_balance_val"
",melt_fee_balance_frac"
",melt_fee_balance_curr"
",refund_fee_balance_val"
",refund_fee_balance_frac"
",refund_fee_balance_curr"
") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15);",
15, NULL);
") VALUES ($1,$2,$3,$4,$5,$6);",
6, NULL);
/* Used in #postgres_select_historic_denom_revenue() */
PREPARE ("historic_denomination_revenue_select",
@ -799,15 +782,6 @@ postgres_prepare (PGconn *db_conn)
",revenue_balance_val"
",revenue_balance_frac"
",revenue_balance_curr"
",deposit_fee_balance_val"
",deposit_fee_balance_frac"
",deposit_fee_balance_curr"
",melt_fee_balance_val"
",melt_fee_balance_frac"
",melt_fee_balance_curr"
",refund_fee_balance_val"
",refund_fee_balance_frac"
",refund_fee_balance_curr"
" FROM historic_denomination_revenue"
" WHERE master_pub=$1;",
1, NULL);
@ -2133,9 +2107,6 @@ postgres_get_denomination_summary (void *cls,
* @param revenue_balance what was the total profit made from
* deposit fees, melting fees, refresh fees
* and coins that were never returned?
* @param deposit_fee_balance total profits from deposit fees
* @param melt_fee_balance total profits from melting fees
* @param refund_fee_balance total profits from refund fees
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
*/
static int
@ -2144,10 +2115,7 @@ postgres_insert_historic_denom_revenue (void *cls,
const struct TALER_MasterPublicKeyP *master_pub,
const struct GNUNET_HashCode *denom_pub_hash,
struct GNUNET_TIME_Absolute revenue_timestamp,
const struct TALER_Amount *revenue_balance,
const struct TALER_Amount *deposit_fee_balance,
const struct TALER_Amount *melt_fee_balance,
const struct TALER_Amount *refund_fee_balance)
const struct TALER_Amount *revenue_balance)
{
PGresult *result;
int ret;
@ -2156,24 +2124,9 @@ postgres_insert_historic_denom_revenue (void *cls,
GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
GNUNET_PQ_query_param_auto_from_type (&revenue_timestamp),
TALER_PQ_query_param_amount (revenue_balance),
TALER_PQ_query_param_amount (deposit_fee_balance),
TALER_PQ_query_param_amount (melt_fee_balance),
TALER_PQ_query_param_amount (refund_fee_balance),
GNUNET_PQ_query_param_end
};
GNUNET_assert (GNUNET_YES ==
TALER_amount_cmp_currency (revenue_balance,
deposit_fee_balance));
GNUNET_assert (GNUNET_YES ==
TALER_amount_cmp_currency (revenue_balance,
melt_fee_balance));
GNUNET_assert (GNUNET_YES ==
TALER_amount_cmp_currency (revenue_balance,
refund_fee_balance));
result = GNUNET_PQ_exec_prepared (session->conn,
"historic_denomination_revenue_insert",
params);
@ -2240,16 +2193,10 @@ postgres_select_historic_denom_revenue (void *cls,
struct GNUNET_HashCode denom_pub_hash;
struct GNUNET_TIME_Absolute revenue_timestamp;
struct TALER_Amount revenue_balance;
struct TALER_Amount deposit_fee_balance;
struct TALER_Amount melt_fee_balance;
struct TALER_Amount refund_fee_balance;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", &denom_pub_hash),
GNUNET_PQ_result_spec_auto_from_type ("revenue_timestamp", &revenue_timestamp),
TALER_PQ_result_spec_amount ("revenue_balance", &revenue_balance),
TALER_PQ_result_spec_amount ("deposit_fee_balance", &deposit_fee_balance),
TALER_PQ_result_spec_amount ("melt_fee_balance", &melt_fee_balance),
TALER_PQ_result_spec_amount ("refund_fee_balance", &refund_fee_balance),
GNUNET_PQ_result_spec_end
};
@ -2264,10 +2211,7 @@ postgres_select_historic_denom_revenue (void *cls,
ret = cb (cb_cls,
&denom_pub_hash,
revenue_timestamp,
&revenue_balance,
&deposit_fee_balance,
&melt_fee_balance,
&refund_fee_balance);
&revenue_balance);
switch (ret)
{
case GNUNET_OK:

View File

@ -461,10 +461,7 @@ run (void *cls)
&master_pub,
&denom_pub_hash,
past,
&rbalance,
&deposit_fee_balance,
&melt_fee_balance,
&refund_fee_balance));
&rbalance));
FAILIF (GNUNET_OK !=
plugin->insert_historic_denom_revenue (plugin->cls,
@ -472,10 +469,7 @@ run (void *cls)
&master_pub,
&rnd_hash,
now,
&rbalance,
&deposit_fee_balance,
&melt_fee_balance,
&refund_fee_balance));
&rbalance));
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Test: select_historic_denom_revenue\n");
@ -484,10 +478,7 @@ run (void *cls)
select_historic_denom_revenue_result (void *cls,
const struct GNUNET_HashCode *denom_pub_hash2,
struct GNUNET_TIME_Absolute revenue_timestamp2,
const struct TALER_Amount *revenue_balance2,
const struct TALER_Amount *deposit_fee_balance2,
const struct TALER_Amount *melt_fee_balance2,
const struct TALER_Amount *refund_fee_balance2)
const struct TALER_Amount *revenue_balance2)
{
static int n = 0;
@ -500,10 +491,7 @@ run (void *cls)
&& 0 != memcmp (&revenue_timestamp2, &now, sizeof (now)))
|| (0 != memcmp (denom_pub_hash2, &denom_pub_hash, sizeof (denom_pub_hash))
&& 0 != memcmp (denom_pub_hash2, &rnd_hash, sizeof (rnd_hash)))
|| 0 != memcmp (revenue_balance2, &rbalance, sizeof (rbalance))
|| 0 != memcmp (deposit_fee_balance2, &deposit_fee_balance, sizeof (deposit_fee_balance))
|| 0 != memcmp (melt_fee_balance2, &melt_fee_balance, sizeof (melt_fee_balance))
|| 0 != memcmp (refund_fee_balance2, &refund_fee_balance, sizeof (refund_fee_balance)))
|| 0 != memcmp (revenue_balance2, &rbalance, sizeof (rbalance)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"select_historic_denom_revenue_result: result does not match\n");

View File

@ -53,10 +53,6 @@ typedef int
* @param revenue_balance what was the total profit made from
* deposit fees, melting fees, refresh fees
* and coins that were never returned?
* @param deposit_fee_balance total profits from deposit fees
* @param melt_fee_balance total profits from melting fees
* @param refund_fee_balance total profits from refund fees
*
* @return sets the return value of select_denomination_info(),
* #GNUNET_OK to continue,
* #GNUNET_NO to stop processing further rows
@ -66,10 +62,7 @@ typedef int
(*TALER_AUDITORDB_HistoricDenominationRevenueDataCallback)(void *cls,
const struct GNUNET_HashCode *denom_pub_hash,
struct GNUNET_TIME_Absolute revenue_timestamp,
const struct TALER_Amount *revenue_balance,
const struct TALER_Amount *deposit_fee_balance,
const struct TALER_Amount *melt_fee_balance,
const struct TALER_Amount *refund_fee_balance);
const struct TALER_Amount *revenue_balance);
/**
@ -650,10 +643,7 @@ struct TALER_AUDITORDB_Plugin
* @param revenue_balance what was the total profit made from
* deposit fees, melting fees, refresh fees
* and coins that were never returned?
* @param deposit_fee_balance total profits from deposit fees
* @param melt_fee_balance total profits from melting fees
* @param refund_fee_balance total profits from refund fees
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
*/
int
(*insert_historic_denom_revenue)(void *cls,
@ -661,10 +651,8 @@ struct TALER_AUDITORDB_Plugin
const struct TALER_MasterPublicKeyP *master_pub,
const struct GNUNET_HashCode *denom_pub_hash,
struct GNUNET_TIME_Absolute revenue_timestamp,
const struct TALER_Amount *revenue_balance,
const struct TALER_Amount *deposit_fee_balance,
const struct TALER_Amount *melt_fee_balance,
const struct TALER_Amount *refund_fee_balance);
const struct TALER_Amount *revenue_balance);
/**
* Obtain all of the historic denomination key revenue