refactor to avoid duping all the RSA keys on refresh processing
This commit is contained in:
parent
0ff8ec8da9
commit
8acfca6718
@ -616,16 +616,15 @@ sync_denomination (void *cls,
|
|||||||
/* The denomination expired and carried a balance; we can now
|
/* The denomination expired and carried a balance; we can now
|
||||||
book the remaining balance as profit, and reduce our risk
|
book the remaining balance as profit, and reduce our risk
|
||||||
exposure by the accumulated risk of the denomination. */
|
exposure by the accumulated risk of the denomination. */
|
||||||
if (GNUNET_SYSERR ==
|
GNUNET_assert (GNUNET_SYSERR !=
|
||||||
TALER_amount_subtract (&total_risk,
|
TALER_amount_subtract (&total_risk,
|
||||||
&total_risk,
|
&total_risk,
|
||||||
&ds->denom_risk))
|
&ds->denom_risk));
|
||||||
{
|
/* If the above fails, our risk assessment is inconsistent!
|
||||||
/* Holy smokes, our risk assessment was inconsistent!
|
This is really, really bad (auditor-internal invariant
|
||||||
This is really, really bad. */
|
would be violated). Hence we can "safely" assert. If
|
||||||
GNUNET_break (0);
|
this assertion fails, well, good luck: there is a bug
|
||||||
cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
|
in the auditor _or_ the auditor's database is corrupt. *///
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) &&
|
if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) &&
|
||||||
( (0 != ds->denom_balance.value) ||
|
( (0 != ds->denom_balance.value) ||
|
||||||
@ -654,6 +653,8 @@ sync_denomination (void *cls,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Not expired, just store current denomination summary
|
||||||
|
to auditor database for next iteration */
|
||||||
long long cnt;
|
long long cnt;
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
@ -675,6 +676,7 @@ sync_denomination (void *cls,
|
|||||||
{
|
{
|
||||||
if (ds->num_issued < (uint64_t) cnt)
|
if (ds->num_issued < (uint64_t) cnt)
|
||||||
{
|
{
|
||||||
|
/* more coins deposited than issued! very bad */
|
||||||
report_emergency_by_count (issue,
|
report_emergency_by_count (issue,
|
||||||
ds->num_issued,
|
ds->num_issued,
|
||||||
cnt,
|
cnt,
|
||||||
@ -682,6 +684,8 @@ sync_denomination (void *cls,
|
|||||||
}
|
}
|
||||||
if (GNUNET_YES == ds->report_emergency)
|
if (GNUNET_YES == ds->report_emergency)
|
||||||
{
|
{
|
||||||
|
/* Value of coins deposited exceed value of coins
|
||||||
|
issued! Also very bad! */
|
||||||
report_emergency_by_amount (issue,
|
report_emergency_by_amount (issue,
|
||||||
&ds->denom_risk,
|
&ds->denom_risk,
|
||||||
&ds->denom_loss);
|
&ds->denom_loss);
|
||||||
@ -729,7 +733,8 @@ sync_denomination (void *cls,
|
|||||||
* we now have additional coins that have been issued.
|
* we now have additional coins that have been issued.
|
||||||
*
|
*
|
||||||
* Note that the signature was already checked in
|
* Note that the signature was already checked in
|
||||||
* #handle_reserve_out(), so we do not check it again here.
|
* taler-helper-auditor-reserves.c::#handle_reserve_out(), so we do not check
|
||||||
|
* it again here.
|
||||||
*
|
*
|
||||||
* @param cls our `struct CoinContext`
|
* @param cls our `struct CoinContext`
|
||||||
* @param rowid unique serial ID for the refresh session in our DB
|
* @param rowid unique serial ID for the refresh session in our DB
|
||||||
@ -758,6 +763,8 @@ withdraw_cb (void *cls,
|
|||||||
struct TALER_Amount value;
|
struct TALER_Amount value;
|
||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
|
/* Note: some optimization potential here: lots of fields we
|
||||||
|
could avoid fetching from the database with a custom function. */
|
||||||
(void) h_blind_ev;
|
(void) h_blind_ev;
|
||||||
(void) reserve_pub;
|
(void) reserve_pub;
|
||||||
(void) reserve_sig;
|
(void) reserve_sig;
|
||||||
@ -788,7 +795,8 @@ withdraw_cb (void *cls,
|
|||||||
&dh);
|
&dh);
|
||||||
if (NULL == ds)
|
if (NULL == ds)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
/* cc->qs is set by #get_denomination_summary() */
|
||||||
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == cc->qs);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&value,
|
TALER_amount_ntoh (&value,
|
||||||
@ -798,14 +806,14 @@ withdraw_cb (void *cls,
|
|||||||
GNUNET_h2s (&dh),
|
GNUNET_h2s (&dh),
|
||||||
TALER_amount2s (&value));
|
TALER_amount2s (&value));
|
||||||
ds->num_issued++;
|
ds->num_issued++;
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
TALER_amount_add (&ds->denom_balance,
|
|
||||||
&ds->denom_balance,
|
|
||||||
&value));
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"New balance of denomination `%s' is %s\n",
|
"New balance of denomination `%s' is %s\n",
|
||||||
GNUNET_h2s (&dh),
|
GNUNET_h2s (&dh),
|
||||||
TALER_amount2s (&ds->denom_balance));
|
TALER_amount2s (&ds->denom_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_add (&ds->denom_balance,
|
||||||
|
&ds->denom_balance,
|
||||||
|
&value));
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_amount_add (&total_escrow_balance,
|
TALER_amount_add (&total_escrow_balance,
|
||||||
&total_escrow_balance,
|
&total_escrow_balance,
|
||||||
@ -829,21 +837,38 @@ struct RevealContext
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denomination public keys of the new coins.
|
* Denomination public data of the new coins.
|
||||||
*/
|
*/
|
||||||
struct TALER_DenominationPublicKey *new_dps;
|
const struct TALER_DenominationKeyValidityPS **new_issues;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Size of the @a new_dp and @a new_dps arrays.
|
* Set to the size of the @a new_issues array.
|
||||||
*/
|
*/
|
||||||
unsigned int num_freshcoins;
|
unsigned int num_freshcoins;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which coin row are we currently processing (for report generation).
|
||||||
|
*/
|
||||||
|
uint64_t rowid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error status. #GNUNET_OK if all is OK.
|
||||||
|
* #GNUNET_NO if a denomination key was not found
|
||||||
|
* #GNUNET_SYSERR if we had a database error.
|
||||||
|
*/
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database error, if @e err is #GNUNET_SYSERR.
|
||||||
|
*/
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called with information about a refresh order.
|
* Function called with information about a refresh order.
|
||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure with a `struct RevealContext *` in it
|
||||||
* @param num_freshcoins size of the @a rrcs array
|
* @param num_freshcoins size of the @a rrcs array
|
||||||
* @param rrcs array of @a num_freshcoins information about coins to be created
|
* @param rrcs array of @a num_freshcoins information about coins to be created
|
||||||
* @param num_tprivs number of entries in @a tprivs, should be #TALER_CNC_KAPPA - 1
|
* @param num_tprivs number of entries in @a tprivs, should be #TALER_CNC_KAPPA - 1
|
||||||
@ -860,15 +885,40 @@ reveal_data_cb (void *cls,
|
|||||||
{
|
{
|
||||||
struct RevealContext *rctx = cls;
|
struct RevealContext *rctx = cls;
|
||||||
|
|
||||||
|
/* Note: optimization using custom database accessor API could avoid
|
||||||
|
fetching these fields -- and we */
|
||||||
(void) num_tprivs;
|
(void) num_tprivs;
|
||||||
(void) tprivs;
|
(void) tprivs;
|
||||||
(void) tp;
|
(void) tp;
|
||||||
|
|
||||||
rctx->num_freshcoins = num_freshcoins;
|
rctx->num_freshcoins = num_freshcoins;
|
||||||
rctx->new_dps = GNUNET_new_array (num_freshcoins,
|
rctx->new_issues = GNUNET_new_array (
|
||||||
struct TALER_DenominationPublicKey);
|
num_freshcoins,
|
||||||
|
const struct TALER_DenominationKeyValidityPS *);
|
||||||
|
|
||||||
|
/* Update outstanding amounts for all new coin's denominations */
|
||||||
for (unsigned int i = 0; i<num_freshcoins; i++)
|
for (unsigned int i = 0; i<num_freshcoins; i++)
|
||||||
rctx->new_dps[i].rsa_public_key
|
{
|
||||||
= GNUNET_CRYPTO_rsa_public_key_dup (rrcs[i].denom_pub.rsa_public_key);
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
|
/* lookup new coin denomination key */
|
||||||
|
qs = TALER_ARL_get_denomination_info (&rrcs[i].denom_pub,
|
||||||
|
&rctx->new_issues[i],
|
||||||
|
NULL);
|
||||||
|
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
|
||||||
|
{
|
||||||
|
report_row_inconsistency ("refresh_reveal",
|
||||||
|
rctx->rowid,
|
||||||
|
"denomination key not found");
|
||||||
|
rctx->err = GNUNET_NO; /* terminate, but return "OK" */
|
||||||
|
}
|
||||||
|
else if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||||
|
{
|
||||||
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||||
|
rctx->qs = qs;
|
||||||
|
rctx->err = GNUNET_SYSERR; /* terminate, return GNUNET_SYSERR */
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1031,16 +1081,12 @@ refresh_session_cb (void *cls,
|
|||||||
TALER_amount2s (amount_with_fee));
|
TALER_amount2s (amount_with_fee));
|
||||||
|
|
||||||
{
|
{
|
||||||
struct RevealContext reveal_ctx;
|
|
||||||
struct TALER_Amount refresh_cost;
|
struct TALER_Amount refresh_cost;
|
||||||
int err;
|
struct RevealContext reveal_ctx = {
|
||||||
|
.rowid = rowid,
|
||||||
|
.err = GNUNET_OK
|
||||||
|
};
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
TALER_amount_get_zero (amount_with_fee->currency,
|
|
||||||
&refresh_cost));
|
|
||||||
memset (&reveal_ctx,
|
|
||||||
0,
|
|
||||||
sizeof (reveal_ctx));
|
|
||||||
qs = TALER_ARL_edb->get_refresh_reveal (TALER_ARL_edb->cls,
|
qs = TALER_ARL_edb->get_refresh_reveal (TALER_ARL_edb->cls,
|
||||||
TALER_ARL_esession,
|
TALER_ARL_esession,
|
||||||
rc,
|
rc,
|
||||||
@ -1055,9 +1101,9 @@ refresh_session_cb (void *cls,
|
|||||||
if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) ||
|
if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) ||
|
||||||
(0 == reveal_ctx.num_freshcoins) )
|
(0 == reveal_ctx.num_freshcoins) )
|
||||||
{
|
{
|
||||||
/* This can happen if /refresh/reveal was not yet called or only
|
/* This can happen if reveal was not yet called or only
|
||||||
with invalid data, even if the exchange is correctly
|
with invalid data, even if the exchange is correctly
|
||||||
operating. We still TALER_ARL_report it. */
|
operating. We still report it. */
|
||||||
TALER_ARL_report (report_refreshs_hanging,
|
TALER_ARL_report (report_refreshs_hanging,
|
||||||
json_pack ("{s:I, s:o, s:o}",
|
json_pack ("{s:I, s:o, s:o}",
|
||||||
"row", (json_int_t) rowid,
|
"row", (json_int_t) rowid,
|
||||||
@ -1071,44 +1117,20 @@ refresh_session_cb (void *cls,
|
|||||||
amount_with_fee));
|
amount_with_fee));
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
if (GNUNET_SYSERR == reveal_ctx.err)
|
||||||
|
cc->qs = reveal_ctx.qs;
|
||||||
|
|
||||||
|
if (GNUNET_OK != reveal_ctx.err)
|
||||||
{
|
{
|
||||||
const struct TALER_DenominationKeyValidityPS *new_issues[reveal_ctx.
|
GNUNET_free_non_null (reveal_ctx.new_issues);
|
||||||
num_freshcoins];
|
return (GNUNET_SYSERR == reveal_ctx.err) ? GNUNET_SYSERR : GNUNET_OK;
|
||||||
|
|
||||||
/* Update outstanding amounts for all new coin's denominations, and check
|
|
||||||
that the resulting amounts are consistent with the value being refreshed. */
|
|
||||||
err = GNUNET_OK;
|
|
||||||
for (unsigned int i = 0; i<reveal_ctx.num_freshcoins; i++)
|
|
||||||
{
|
|
||||||
/* lookup new coin denomination key */
|
|
||||||
qs = TALER_ARL_get_denomination_info (&reveal_ctx.new_dps[i],
|
|
||||||
&new_issues[i],
|
|
||||||
NULL);
|
|
||||||
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
|
|
||||||
{
|
|
||||||
report_row_inconsistency ("refresh_reveal",
|
|
||||||
rowid,
|
|
||||||
"denomination key not found");
|
|
||||||
err = GNUNET_NO; /* terminate, but return "OK" */
|
|
||||||
}
|
}
|
||||||
else if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
|
||||||
{
|
|
||||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
|
||||||
cc->qs = qs;
|
|
||||||
err = GNUNET_SYSERR; /* terminate, return GNUNET_SYSERR */
|
|
||||||
}
|
|
||||||
GNUNET_CRYPTO_rsa_public_key_free (
|
|
||||||
reveal_ctx.new_dps[i].rsa_public_key);
|
|
||||||
reveal_ctx.new_dps[i].rsa_public_key = NULL;
|
|
||||||
}
|
|
||||||
GNUNET_free (reveal_ctx.new_dps);
|
|
||||||
reveal_ctx.new_dps = NULL;
|
|
||||||
|
|
||||||
if (GNUNET_OK != err)
|
/* Check that the resulting amounts are consistent with the value being
|
||||||
return (GNUNET_SYSERR == err) ? GNUNET_SYSERR : GNUNET_OK;
|
refreshed by calculating the total refresh cost */
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
/* calculate total refresh cost */
|
TALER_amount_get_zero (amount_with_fee->currency,
|
||||||
|
&refresh_cost));
|
||||||
for (unsigned int i = 0; i<reveal_ctx.num_freshcoins; i++)
|
for (unsigned int i = 0; i<reveal_ctx.num_freshcoins; i++)
|
||||||
{
|
{
|
||||||
/* update cost of refresh */
|
/* update cost of refresh */
|
||||||
@ -1116,9 +1138,9 @@ refresh_session_cb (void *cls,
|
|||||||
struct TALER_Amount value;
|
struct TALER_Amount value;
|
||||||
|
|
||||||
TALER_amount_ntoh (&fee,
|
TALER_amount_ntoh (&fee,
|
||||||
&new_issues[i]->fee_withdraw);
|
&reveal_ctx.new_issues[i]->fee_withdraw);
|
||||||
TALER_amount_ntoh (&value,
|
TALER_amount_ntoh (&value,
|
||||||
&new_issues[i]->value);
|
&reveal_ctx.new_issues[i]->value);
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_amount_add (&refresh_cost,
|
TALER_amount_add (&refresh_cost,
|
||||||
&refresh_cost,
|
&refresh_cost,
|
||||||
@ -1143,6 +1165,7 @@ refresh_session_cb (void *cls,
|
|||||||
// FIXME: handle properly!
|
// FIXME: handle properly!
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
|
cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
GNUNET_free_non_null (reveal_ctx.new_issues);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1157,6 +1180,7 @@ refresh_session_cb (void *cls,
|
|||||||
&amount_without_fee,
|
&amount_without_fee,
|
||||||
&refresh_cost,
|
&refresh_cost,
|
||||||
-1);
|
-1);
|
||||||
|
GNUNET_free_non_null (reveal_ctx.new_issues);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1167,18 +1191,18 @@ refresh_session_cb (void *cls,
|
|||||||
struct TALER_Amount value;
|
struct TALER_Amount value;
|
||||||
|
|
||||||
dsi = get_denomination_summary (cc,
|
dsi = get_denomination_summary (cc,
|
||||||
new_issues[i],
|
reveal_ctx.new_issues[i],
|
||||||
&new_issues[i]->denom_hash);
|
&reveal_ctx.new_issues[i]->denom_hash);
|
||||||
if (NULL == dsi)
|
if (NULL == dsi)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&value,
|
TALER_amount_ntoh (&value,
|
||||||
&new_issues[i]->value);
|
&reveal_ctx.new_issues[i]->value);
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"Created fresh coin in denomination `%s' of value %s\n",
|
"Created fresh coin in denomination `%s' of value %s\n",
|
||||||
GNUNET_h2s (&new_issues[i]->denom_hash),
|
GNUNET_h2s (&reveal_ctx.new_issues[i]->denom_hash),
|
||||||
TALER_amount2s (&value));
|
TALER_amount2s (&value));
|
||||||
dsi->num_issued++;
|
dsi->num_issued++;
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
@ -1191,7 +1215,7 @@ refresh_session_cb (void *cls,
|
|||||||
&value));
|
&value));
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"New balance of denomination `%s' is %s\n",
|
"New balance of denomination `%s' is %s\n",
|
||||||
GNUNET_h2s (&new_issues[i]->denom_hash),
|
GNUNET_h2s (&reveal_ctx.new_issues[i]->denom_hash),
|
||||||
TALER_amount2s (&dsi->denom_balance));
|
TALER_amount2s (&dsi->denom_balance));
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_amount_add (&total_escrow_balance,
|
TALER_amount_add (&total_escrow_balance,
|
||||||
@ -1202,7 +1226,7 @@ refresh_session_cb (void *cls,
|
|||||||
&total_risk,
|
&total_risk,
|
||||||
&value));
|
&value));
|
||||||
}
|
}
|
||||||
}
|
GNUNET_free_non_null (reveal_ctx.new_issues);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update old coin's denomination balance */
|
/* update old coin's denomination balance */
|
||||||
|
Loading…
Reference in New Issue
Block a user