aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-03-26 20:54:41 +0100
committerChristian Grothoff <christian@grothoff.org>2020-03-26 20:54:41 +0100
commitf052527ea50e9e6b1de165833e83d7f191a121d1 (patch)
tree925e9d9f0be26b9975231638d394a22aa32c6505
parent394765a1e60cab4504817ca364429222e76f59ce (diff)
fix recoup-refresh audit logic
-rw-r--r--src/auditor/taler-helper-auditor-coins.c158
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c39
-rw-r--r--src/exchangedb/test_exchangedb.c1
-rw-r--r--src/include/taler_exchangedb_plugin.h4
4 files changed, 136 insertions, 66 deletions
diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c
index 33591cec9..9f9f6dc93 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -190,6 +190,10 @@ report_emergency_by_amount (
const struct TALER_Amount *risk,
const struct TALER_Amount *loss)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Reporting emergency on denomination `%s' over loss of %s\n",
+ GNUNET_h2s (&issue->denom_hash),
+ TALER_amount2s (loss));
TALER_ARL_report (report_emergencies,
json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}",
"denompub_hash",
@@ -808,14 +812,14 @@ withdraw_cb (void *cls,
GNUNET_h2s (&dh),
TALER_amount2s (&value));
ds->num_issued++;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "New balance of denomination `%s' is %s\n",
- GNUNET_h2s (&dh),
- TALER_amount2s (&ds->denom_balance));
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&ds->denom_balance,
&ds->denom_balance,
&value));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "New balance of denomination `%s' is %s\n",
+ GNUNET_h2s (&dh),
+ TALER_amount2s (&ds->denom_balance));
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&total_escrow_balance,
&total_escrow_balance,
@@ -1349,7 +1353,6 @@ deposit_cb (void *cls,
struct CoinContext *cc = cls;
const struct TALER_DenominationKeyValidityPS *issue;
struct DenominationSummary *ds;
- struct TALER_Amount tmp;
enum GNUNET_DB_QueryStatus qs;
(void) wire_deadline;
@@ -1459,6 +1462,8 @@ deposit_cb (void *cls,
}
else
{
+ struct TALER_Amount tmp;
+
if (GNUNET_SYSERR ==
TALER_amount_subtract (&tmp,
&ds->denom_balance,
@@ -1696,7 +1701,6 @@ check_recoup (struct CoinContext *cc,
const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_DenominationBlindingKeyP *coin_blind)
{
- struct TALER_RecoupRequestPS pr;
struct DenominationSummary *ds;
enum GNUNET_DB_QueryStatus qs;
const struct TALER_DenominationKeyValidityPS *issue;
@@ -1711,15 +1715,14 @@ check_recoup (struct CoinContext *cc,
"row", (json_int_t) rowid,
"loss", TALER_JSON_from_amount (amount),
"key_pub", GNUNET_JSON_from_data_auto (
- &pr.h_denom_pub)));
+ &coin->denom_pub_hash)));
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss,
amount));
}
- qs = TALER_ARL_get_denomination_info (denom_pub,
- &issue,
- &pr.h_denom_pub);
+ qs = TALER_ARL_get_denomination_info_by_hash (&coin->denom_pub_hash,
+ &issue);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
report_row_inconsistency ("recoup",
@@ -1735,28 +1738,34 @@ check_recoup (struct CoinContext *cc,
cc->qs = qs;
return GNUNET_SYSERR;
}
- pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP);
- pr.purpose.size = htonl (sizeof (pr));
- pr.coin_pub = coin->coin_pub;
- pr.coin_blind = *coin_blind;
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
- &pr.purpose,
- &coin_sig->eddsa_signature,
- &coin->coin_pub.eddsa_pub))
{
- TALER_ARL_report (report_bad_sig_losses,
- json_pack ("{s:s, s:I, s:o, s:o}",
- "operation", "recoup",
- "row", (json_int_t) rowid,
- "loss", TALER_JSON_from_amount (amount),
- "coin_pub", GNUNET_JSON_from_data_auto (
- &coin->coin_pub)));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_add (&total_bad_sig_loss,
- &total_bad_sig_loss,
- amount));
- return GNUNET_OK;
+ struct TALER_RecoupRequestPS pr = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
+ .purpose.size = htonl (sizeof (pr)),
+ .coin_pub = coin->coin_pub,
+ .coin_blind = *coin_blind,
+ .h_denom_pub = coin->denom_pub_hash
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
+ &pr.purpose,
+ &coin_sig->eddsa_signature,
+ &coin->coin_pub.eddsa_pub))
+ {
+ TALER_ARL_report (report_bad_sig_losses,
+ json_pack ("{s:s, s:I, s:o, s:o}",
+ "operation", "recoup",
+ "row", (json_int_t) rowid,
+ "loss", TALER_JSON_from_amount (amount),
+ "coin_pub", GNUNET_JSON_from_data_auto (
+ &coin->coin_pub)));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_add (&total_bad_sig_loss,
+ &total_bad_sig_loss,
+ amount));
+ return GNUNET_OK;
+ }
}
ds = get_denomination_summary (cc,
issue,
@@ -1803,7 +1812,7 @@ check_recoup (struct CoinContext *cc,
* @param amount how much should be added back to the reserve
* @param reserve_pub public key of the reserve
* @param coin public information about the coin
- * @param denom_pub denomination public key of @a coin
+ * @param denom_pub_hash hash of denomination public key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
@@ -1844,6 +1853,7 @@ recoup_cb (void *cls,
* @param timestamp when did we receive the recoup request
* @param amount how much should be added back to the reserve
* @param old_coin_pub original coin that was refreshed to create @a coin
+ * @param old_denom_pub public key of @a old_coin_pub
* @param coin public information about the coin
* @param denom_pub denomination public key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
@@ -1856,17 +1866,65 @@ recoup_refresh_cb (void *cls,
struct GNUNET_TIME_Absolute timestamp,
const struct TALER_Amount *amount,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ const struct GNUNET_HashCode *old_denom_pub_hash,
const struct TALER_CoinPublicInfo *coin,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_DenominationBlindingKeyP *coin_blind)
{
struct CoinContext *cc = cls;
+ const struct TALER_DenominationKeyValidityPS *issue;
+ enum GNUNET_DB_QueryStatus qs;
- GNUNET_assert (rowid >= ppc.last_recoup_refresh_serial_id); /* should be monotonically increasing */
- ppc.last_recoup_refresh_serial_id = rowid + 1;
(void) timestamp;
(void) old_coin_pub;
+ GNUNET_assert (rowid >= ppc.last_recoup_refresh_serial_id); /* should be monotonically increasing */
+ ppc.last_recoup_refresh_serial_id = rowid + 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Recoup-refresh amount is %s\n",
+ TALER_amount2s (amount));
+
+ /* Update old coin's denomination balance summary */
+ qs = TALER_ARL_get_denomination_info_by_hash (old_denom_pub_hash,
+ &issue);
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS >= qs)
+ {
+ if (qs < 0)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ cc->qs = qs;
+ return GNUNET_SYSERR;
+ }
+ report_row_inconsistency ("refresh-recoup",
+ rowid,
+ "denomination key of old coin not found");
+ }
+ else
+ {
+ struct DenominationSummary *dso;
+
+ dso = get_denomination_summary (cc,
+ issue,
+ old_denom_pub_hash);
+ if (NULL == dso)
+ {
+ report_row_inconsistency ("refresh_reveal",
+ rowid,
+ "denomination key for old coin unknown to auditor");
+ }
+ else
+ {
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_add (&dso->denom_balance,
+ &dso->denom_balance,
+ amount));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "New balance of denomination `%s' after refresh-recoup is %s\n",
+ GNUNET_h2s (&issue->denom_hash),
+ TALER_amount2s (&dso->denom_balance));
+ }
+ }
+
return check_recoup (cc,
rowid,
amount,
@@ -1970,13 +2028,13 @@ analyze_coins (void *cls)
if (0 > cc.qs)
return cc.qs;
- /* process refreshs */
+ /* process recoups */
if (0 >
- (qs = TALER_ARL_edb->select_refreshes_above_serial_id (
+ (qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id (
TALER_ARL_edb->cls,
TALER_ARL_esession,
- ppc.last_melt_serial_id,
- &refresh_session_cb,
+ ppc.last_recoup_refresh_serial_id,
+ &recoup_refresh_cb,
&cc)))
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -1984,14 +2042,12 @@ analyze_coins (void *cls)
}
if (0 > cc.qs)
return cc.qs;
-
- /* process deposits */
if (0 >
- (qs = TALER_ARL_edb->select_deposits_above_serial_id (
+ (qs = TALER_ARL_edb->select_recoup_above_serial_id (
TALER_ARL_edb->cls,
TALER_ARL_esession,
- ppc.last_deposit_serial_id,
- &deposit_cb,
+ ppc.last_recoup_serial_id,
+ &recoup_cb,
&cc)))
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -2000,13 +2056,13 @@ analyze_coins (void *cls)
if (0 > cc.qs)
return cc.qs;
- /* process recoups */
+ /* process refreshs */
if (0 >
- (qs = TALER_ARL_edb->select_recoup_above_serial_id (
+ (qs = TALER_ARL_edb->select_refreshes_above_serial_id (
TALER_ARL_edb->cls,
TALER_ARL_esession,
- ppc.last_recoup_serial_id,
- &recoup_cb,
+ ppc.last_melt_serial_id,
+ &refresh_session_cb,
&cc)))
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -2014,12 +2070,14 @@ analyze_coins (void *cls)
}
if (0 > cc.qs)
return cc.qs;
+
+ /* process deposits */
if (0 >
- (qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id (
+ (qs = TALER_ARL_edb->select_deposits_above_serial_id (
TALER_ARL_edb->cls,
TALER_ARL_esession,
- ppc.last_recoup_refresh_serial_id,
- &recoup_refresh_cb,
+ ppc.last_deposit_serial_id,
+ &deposit_cb,
&cc)))
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 31f92d58c..c21f1b1a9 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -1192,8 +1192,8 @@ postgres_get_session (void *cls)
",coin_blind"
",h_blind_ev"
",coins.denom_pub_hash"
- ",denoms.denom_pub"
",coins.denom_sig"
+ ",denoms.denom_pub"
",amount_val"
",amount_frac"
" FROM recoup"
@@ -1213,24 +1213,27 @@ postgres_get_session (void *cls)
" recoup_refresh_uuid"
",timestamp"
",rc.old_coin_pub"
- ",coin_pub"
+ ",old_coins.denom_pub_hash AS old_denom_pub_hash"
+ ",recoup_refresh.coin_pub"
",coin_sig"
",coin_blind"
- ",h_blind_ev"
- ",coins.denom_pub_hash"
",denoms.denom_pub"
- ",coins.denom_sig"
+ ",h_blind_ev"
+ ",new_coins.denom_pub_hash"
+ ",new_coins.denom_sig"
",amount_val"
",amount_frac"
" FROM recoup_refresh"
- " JOIN refresh_revealed_coins rrc"
+ " INNER JOIN refresh_revealed_coins rrc"
" ON (rrc.h_coin_ev = h_blind_ev)"
- " JOIN refresh_commitments rc"
+ " INNER JOIN refresh_commitments rc"
" ON (rrc.rc = rc.rc)"
- " JOIN known_coins coins"
- " USING (coin_pub)"
- " JOIN denominations denoms"
- " ON (coins.denom_pub_hash = denoms.denom_pub_hash)"
+ " INNER JOIN known_coins old_coins"
+ " ON (rc.old_coin_pub = old_coins.coin_pub)"
+ " INNER JOIN known_coins new_coins"
+ " ON (new_coins.coin_pub = recoup_refresh.coin_pub)"
+ " INNER JOIN denominations denoms"
+ " ON (new_coins.denom_pub_hash = denoms.denom_pub_hash)"
" WHERE recoup_refresh_uuid>=$1"
" ORDER BY recoup_refresh_uuid ASC;",
1),
@@ -6381,8 +6384,8 @@ recoup_serial_helper_cb (void *cls,
struct TALER_CoinPublicInfo coin;
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationBlindingKeyP coin_blind;
- struct TALER_DenominationPublicKey denom_pub;
struct TALER_Amount amount;
+ struct TALER_DenominationPublicKey denom_pub;
struct GNUNET_HashCode h_blind_ev;
struct GNUNET_TIME_Absolute timestamp;
struct GNUNET_PQ_ResultSpec rs[] = {
@@ -6394,6 +6397,8 @@ recoup_serial_helper_cb (void *cls,
&reserve_pub),
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
&coin.coin_pub),
+ GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+ &denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
&coin_sig),
GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
@@ -6402,8 +6407,6 @@ recoup_serial_helper_cb (void *cls,
&h_blind_ev),
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
&coin.denom_pub_hash),
- GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
- &denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
&coin.denom_sig.rsa_signature),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
@@ -6532,6 +6535,7 @@ recoup_refresh_serial_helper_cb (void *cls,
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationBlindingKeyP coin_blind;
struct TALER_DenominationPublicKey denom_pub;
+ struct GNUNET_HashCode old_denom_pub_hash;
struct TALER_Amount amount;
struct GNUNET_HashCode h_blind_ev;
struct GNUNET_TIME_Absolute timestamp;
@@ -6542,18 +6546,20 @@ recoup_refresh_serial_helper_cb (void *cls,
&timestamp),
GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
&old_coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("old_denom_pub_hash",
+ &old_denom_pub_hash),
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
&coin.coin_pub),
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
&coin_sig),
GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
&coin_blind),
+ GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+ &denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
&h_blind_ev),
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
&coin.denom_pub_hash),
- GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
- &denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
&coin.denom_sig.rsa_signature),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
@@ -6576,6 +6582,7 @@ recoup_refresh_serial_helper_cb (void *cls,
timestamp,
&amount,
&old_coin_pub,
+ &old_denom_pub_hash,
&coin,
&denom_pub,
&coin_sig,
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index e9b47942a..96fbe3dc2 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -1317,6 +1317,7 @@ drop:
* @param amount how much should be added back to the reserve
* @param reserve_pub public key of the reserve
* @param coin public information about the coin
+ * @param denom_pub denomination key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index f81c28bbb..c19428b18 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1346,6 +1346,7 @@ typedef int
* @param amount how much should be added back to the reserve
* @param reserve_pub public key of the reserve
* @param coin public information about the coin
+ * @param denom_pub denomination key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
@@ -1372,7 +1373,9 @@ typedef int
* @param timestamp when did we receive the recoup request
* @param amount how much should be added back to the reserve
* @param old_coin_pub original coin that was refreshed to create @a coin
+ * @param old_denom_pub_hash hash of public key of @a old_coin_pub
* @param coin public information about the coin
+ * @param denom_pub denomination key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
@@ -1384,6 +1387,7 @@ typedef int
struct GNUNET_TIME_Absolute timestamp,
const struct TALER_Amount *amount,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ const struct GNUNET_HashCode *old_denom_pub_hash,
const struct TALER_CoinPublicInfo *coin,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendSignatureP *coin_sig,