gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-exchange] branch master updated: update auditor repo


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: update auditor report format to capture nicely all diagnostics that may currently be generated by the auditor (closes #4962)
Date: Mon, 06 Nov 2017 19:11:46 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 45c443f  update auditor report format to capture nicely all 
diagnostics that may currently be generated by the auditor (closes #4962)
45c443f is described below

commit 45c443f3489537b33ffece578a920656adcc643b
Author: Christian Grothoff <address@hidden>
AuthorDate: Mon Nov 6 19:11:43 2017 +0100

    update auditor report format to capture nicely all diagnostics that may 
currently be generated by the auditor (closes #4962)
---
 contrib/auditor-report.tex.j2 | 161 +++++++++++++++--
 src/auditor/taler-auditor.c   | 411 ++++++++++++++++++++++++++++++++----------
 2 files changed, 458 insertions(+), 114 deletions(-)

diff --git a/contrib/auditor-report.tex.j2 b/contrib/auditor-report.tex.j2
index 9f454ff..11b7841 100644
--- a/contrib/auditor-report.tex.j2
+++ b/contrib/auditor-report.tex.j2
@@ -108,31 +108,39 @@ compromise.
 {% endif %}
 
 
+\subsection{Arithmetic problems}
 
+This section lists cases where the arithmetic of the exchange
+involving amounts disagrees with the arithmetic of the auditor.
+Disagreements imply that either the exchange made a loss (sending out
+too much money), or screwed a customer (and thus at least needs to fix
+the financial damage done to the customer).
 
-  \begin{longtable}{p{1.5cm}|rl|rl|p{4cm}}
-  {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Expected}} & 
\multicolumn{2}{|c|}{ {\bf Observed}} & {\bf Diagnostic} \\ \hline \hline
+  \begin{longtable}{p{5.5cm}|l|rl|rl}
+  {\bf Operation} & {\bf Table row} & \multicolumn{2}{|c|}{ {\bf Exchange}} & 
\multicolumn{2}{|c|}{ {\bf Auditor}} \\
+  \hline \hline
 \endfirsthead
-  {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Expected}} & 
\multicolumn{2}{|c|}{ {\bf Observed}} & {\bf Diagnostic} \\ \hline \hline
+  {\bf Operation} & {\bf Table row} & \ \multicolumn{2}{|c|}{ {\bf Exchange}} 
& \multicolumn{2}{|c|}{ {\bf Auditor}} \\ \hline \hline
 \endhead
   \hline \hline
-  {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Expected}} & 
\multicolumn{2}{|c|}{ {\bf Observed}} & {\bf Diagnostic} \\
+  {\bf Operation} & {\bf Table row} & \ \multicolumn{2}{|c|}{ {\bf Exchange}} 
& \multicolumn{2}{|c|}{ {\bf Auditor}} \\
 \endfoot
   \hline
-% FIXME: replace these with the summary column adding up the amounts!
-  {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Expected}} & 
\multicolumn{2}{|c|}{ {\bf Observed}} & {\bf Diagnostic} \\
-    \caption{Reserve inconsistencies.}
-    \label{table:reserve:inconsistencies}
+  {\bf Total} & &
+  {{ data.total_arithmetic_delta_plus.value }}.{{ 
data.total_arithmetic_delta_plus.fraction }} &
+  {{ data.total_arithmetic_delta_plus.currency }} &
+  {{ data.total_arithmetic_delta_minus.value }}.{{ 
data.total_arithmetic_delta_minus.fraction }} &
+  {{ data.total_arithmetic_delta_minus.currency }} &
+    \caption{Arithmetic inconsistencies.}
+    \label{table:amount:arithmetic:inconsistencies}
 \endlastfoot
-{% for item in data.reserve_inconsistencies %}
-  \multicolumn{6}{l}{ {\tt {{ item.reserve_pub }} } } \\
-\nopagebreak
-  &
-  {{ item.expected.value }}.{{ item.expected.fraction }} &
-  {{ item.expected.currency }} &
-  {{ item.observed.value }}.{{ item.observed.fraction }} &
-  {{ item.observed.currency }} &
-  {{ item.diagnostic }} \\ \hline
+{% for item in data.amount_arithmetic_inconsistencies %}
+  {{ item.operation }} &
+  {{ item.rowid }} &
+  {{ item.exchange.value }}.{{ item.exchange.fraction }} &
+  {{ item.exchange.currency }} &
+  {{ item.auditor.value }}.{{ item.auditor.fraction }} &
+  {{ item.auditor.currency }} \\ \hline
 {% endfor %}
   \end{longtable}
 
@@ -172,7 +180,7 @@ compromise resulting in proportional financial losses to 
the exchange.
 {% endif %}
 
 
-\subsection{Claimed outgoing wire transfers}
+\subsection{Claimed outgoing wire transfer inconsistencies}
 
 This section is about the exchange's database containing a
 justification to make an outgoing wire transfer for an aggregated
@@ -217,12 +225,93 @@ would be reported separately in 
Section~\ref{sec:wire_check_out}.
 
 \subsection{Coin history inconsistencies}
 
-TODO.
+This section lists cases where the exchange made arithmetic errors found when
+looking at the transaction history of a coin.  The totals sum up the 
differences
+in amounts that matter for profit/loss calculations of the exchange. When an
+exchange merely shifted money from customers to merchants (or vice versa) 
without
+any effects on its own balance, those entries are excluded from the total.
+
+{% if data.coin_inconsistencies|length() == 0 %}
+  {\bf All coin histories were unproblematic.}
+{% else %}
+  \begin{longtable}{l|p{5.5cm}|rl|rl}
+  {\bf Operation} & {\bf Coin public key} & \multicolumn{2}{|c|}{ {\bf 
Exchange}} & \multicolumn{2}{|c|}{ {\bf Auditor}} \\
+  \hline \hline
+\endfirsthead
+  {\bf Operation} & {\bf Coin public key} & \ \multicolumn{2}{|c|}{ {\bf 
Exchange}} & \multicolumn{2}{|c|}{ {\bf Auditor}} \\ \hline \hline
+\endhead
+  \hline \hline
+  {\bf Operation} & {\bf Coin public key} & \ \multicolumn{2}{|c|}{ {\bf 
Exchange}} & \multicolumn{2}{|c|}{ {\bf Auditor}} \\
+\endfoot
+  \hline
+  {\bf Total} & &
+  {{ data.total_coin_delta_plus.value }}.{{ 
data.total_coin_delta_plus.fraction }} &
+  {{ data.total_coin_delta_plus.currency }} &
+  - {{ data.total_coin_delta_minus.value }}.{{ 
data.total_coin_delta_minus.fraction }} &
+  {{ data.total_coin_delta_minus.currency }} &
+    \caption{Arithmetic inconsistencies of amount calculations involving a 
coin.}
+    \label{table:amount:arithmetic:coin:inconsistencies}
+\endlastfoot
+{% for item in data.coin_inconsistencies %}
+  {{ item.operation }} &
+  \multicolumn{5}{l}{ {\tt {{ item.coin_pub }} } } \\
+\nopagebreak & &
+  {{ item.exchange.value }}.{{ item.exchange.fraction }} &
+  {{ item.exchange.currency }} &
+  {{ item.auditor.value }}.{{ item.auditor.fraction }} &
+  {{ item.auditor.currency }} \\ \hline
+{% endfor %}
+  \end{longtable}
+{% endif %}
+
+
+\subsection{Operations with bad signatures}
+
+This section lists operations that the exchange performed, but for
+which the signatures provided are invalid. Hence the operations were
+invalid and the amount involved should be considered lost.
+
+The key given is always the key for which the signature verification
+step failed. This is the reserve public key for ``withdraw''
+operations, the coin public key for ``deposit'' and ``melt''
+operations, the merchant's public key for ``melt'' operations,
+the (hash of the) denomination public key for
+``payback-verify'' and ``deposit-verify'' operations, and the master
+public key for ``payback-master'' operations.
+
+{% if data.reserve_wire_out_inconsistencies|length() == 0 %}
+  {\bf All signatures were valid.}
+{% else %}
+  \begin{longtable}{p{1.5cm}|c|l|rl}
+  {\bf Public key} & {\bf Operation type} & Database row & 
\multicolumn{2}{|c|}{ {\bf Loss amount}} \\
+  \hline \hline
+\endfirsthead
+  {\bf Public key} & {\bf Operation type} & Database row & 
\multicolumn{2}{|c|}{ {\bf Loss amount}} \\ \hline \hline
+\endhead
+  \hline \hline
+  {\bf Public key} & {\bf Operation type} & Database row & 
\multicolumn{2}{|c|}{ {\bf Loss amount}} \\
+\endfoot
+  \hline
+  {\bf Total losses}  & & &
+  {{ data.total_bad_sig_loss.value}}.{{ data.total_bad_sig_loss.fraction}} & 
{{ data.total_bad_sig_loss.currency}} \\
+  \caption{Losses from operations performed on coins without proper 
signatures.}
+  \label{table:bad_signature_losses}
+\endlastfoot
+{% for item in data.bad_sig_losses %}
+  \multicolumn{5}{l}{ {\tt {{ item.key_pub }} } } \\
+\nopagebreak
+  & {{ item.operation }} & {{ item.rowid }} &
+    {{ item.loss.value }}.{{ item.loss.fraction }} &
+    {{ item.loss.currency }} \\ \hline
+{% endfor %}
+  \end{longtable}
+{% endif %}
+
 
 
 \subsection{Actual incoming wire transfers}
 
-TBD. See bug 4958.
+TBD.  See bug 4958.
 
 \subsection{Actual outgoing wire transfers} \label{sec:wire_check_out}
 
@@ -269,6 +358,38 @@ translate into a financial loss (yet).
 {% endif %}
 
 
+\subsection{Other issues}
+
+This section describes issues found that do not have a clear financial
+impact.
+
+{% if data.row_inconsistencies|length() == 0 %}
+  {\bf No row inconsistencies found.}
+{% else %}
+  \begin{longtable}{p{1.5cm}|l|p{5.5}}
+  {\bf Table} & {\bf Row} & {\bf Diagnostic} \\
+  \hline \hline
+\endfirsthead
+  {\bf Table} & {\bf Row} & {\bf Diagnostic} \\
+  \hline \hline
+\endhead
+  \hline \hline
+  {\bf Table} & {\bf Row} & {\bf Diagnostic} \\
+\endfoot
+  \hline
+  {\bf Table} & {\bf Row} & {\bf Diagnostic} \\
+  \caption{Other issues found (by table and row).}
+  \label{table:misc}
+\endlastfoot
+{% for item in data.row_inconsistencies %}
+  {{ item.table }} &
+  {{ item.row }} &
+  {{ item.diagnostic }} \\ \hline
+{% endfor %}
+  \end{longtable}
+{% endif %}
+
+
 \section{Delays and timing}
 
 This section describes issues that are likely caused simply by
diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index 1190e5c..e801ec7 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -190,11 +190,37 @@ static struct TALER_Amount total_wire_out_delta_minus;
 static json_t *report_coin_inconsistencies;
 
 /**
+ * Profits the exchange made by bad amount calculations on coins.
+ */
+static struct TALER_Amount total_coin_delta_plus;
+
+/**
+ * Losses the exchange made by bad amount calculations on coins.
+ */
+static struct TALER_Amount total_coin_delta_minus;
+
+/**
  * Report about aggregate wire transfer fee profits.
  */
 static json_t *report_aggregation_fee_balances;
 
 /**
+ * Report about amount calculation differences (causing profit
+ * or loss at the exchange).
+ */
+static json_t *report_amount_arithmetic_inconsistencies;
+
+/**
+ * Profits the exchange made by bad amount calculations.
+ */
+static struct TALER_Amount total_arithmetic_delta_plus;
+
+/**
+ * Losses the exchange made by bad amount calculations.
+ */
+static struct TALER_Amount total_arithmetic_delta_minus;
+
+/**
  * Total amount reported in all calls to #report_emergency().
  */
 static struct TALER_Amount reported_emergency_sum;
@@ -234,6 +260,15 @@ static struct TALER_Amount total_refund_fee_income;
  */
 static struct TALER_Amount total_aggregation_fee_income;
 
+/**
+ * Array of reports about coin operations with bad signatures.
+ */
+static json_t *report_bad_sig_losses;
+
+/**
+ * Total amount lost by operations for which signatures were invalid.
+ */
+static struct TALER_Amount total_bad_sig_loss;
 
 
 /* ***************************** Report logic **************************** */
@@ -291,6 +326,128 @@ report_emergency (const struct 
TALER_EXCHANGEDB_DenominationKeyInformationP *dki
 
 
 /**
+ * Report a (serious) inconsistency in the exchange's database with
+ * respect to calculations involving amounts.
+ *
+ * @param operation what operation had the inconsistency
+ * @param rowid affected row, UINT64_MAX if row is missing
+ * @param exchange amount calculated by exchange
+ * @param auditor amount calculated by auditor
+ * @param proftable 1 if @a exchange being larger than @a auditor is
+ *           profitable for the exchange for this operation,
+ *           -1 if @a exchange being smaller than @a auditor is
+ *           profitable for the exchange, and 0 if it is unclear
+ */
+static void
+report_amount_arithmetic_inconsistency (const char *operation,
+                                        uint64_t rowid,
+                                        const struct TALER_Amount *exchange,
+                                        const struct TALER_Amount *auditor,
+                                        int profitable)
+{
+  struct TALER_Amount delta;
+  struct TALER_Amount *target;
+
+  if (0 < TALER_amount_cmp (exchange,
+                            auditor))
+  {
+    /* exchange > auditor */
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_subtract (&delta,
+                                         exchange,
+                                         auditor));
+  }
+  else
+  {
+    /* auditor < exchange */
+    profitable = - profitable;
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_subtract (&delta,
+                                         auditor,
+                                         exchange));
+  }
+  report (report_amount_arithmetic_inconsistencies,
+          json_pack ("{s:s, s:I, s:o, s:o, s:I}",
+                     "operation", operation,
+                     "rowid", (json_int_t) rowid,
+                     "exchange", TALER_JSON_from_amount (exchange),
+                     "auditor", TALER_JSON_from_amount (auditor),
+                     "profitable", (json_int_t) profitable));
+  if (0 != profitable)
+  {
+    target = profitable
+      ? &total_arithmetic_delta_plus
+      : &total_arithmetic_delta_minus;
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (target,
+                                    target,
+                                    &delta));
+  }
+}
+
+
+/**
+ * Report a (serious) inconsistency in the exchange's database with
+ * respect to calculations involving amounts of a coin.
+ *
+ * @param operation what operation had the inconsistency
+ * @param coin_pub affected coin
+ * @param exchange amount calculated by exchange
+ * @param auditor amount calculated by auditor
+ * @param proftable 1 if @a exchange being larger than @a auditor is
+ *           profitable for the exchange for this operation,
+ *           -1 if @a exchange being smaller than @a auditor is
+ *           profitable for the exchange, and 0 if it is unclear
+ */
+static void
+report_coin_arithmetic_inconsistency (const char *operation,
+                                      const struct TALER_CoinSpendPublicKeyP 
*coin_pub,
+                                      const struct TALER_Amount *exchange,
+                                      const struct TALER_Amount *auditor,
+                                      int profitable)
+{
+  struct TALER_Amount delta;
+  struct TALER_Amount *target;
+
+  if (0 < TALER_amount_cmp (exchange,
+                            auditor))
+  {
+    /* exchange > auditor */
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_subtract (&delta,
+                                         exchange,
+                                         auditor));
+  }
+  else
+  {
+    /* auditor < exchange */
+    profitable = - profitable;
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_subtract (&delta,
+                                         auditor,
+                                         exchange));
+  }
+  report (report_coin_inconsistencies,
+          json_pack ("{s:s, s:o, s:o, s:o, s:I}",
+                     "operation", operation,
+                     "coin_pub", GNUNET_JSON_from_data_auto (coin_pub),
+                     "exchange", TALER_JSON_from_amount (exchange),
+                     "auditor", TALER_JSON_from_amount (auditor),
+                     "profitable", (json_int_t) profitable));
+  if (0 != profitable)
+  {
+    target = profitable
+      ? &total_coin_delta_plus
+      : &total_coin_delta_minus;
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (target,
+                                    target,
+                                    &delta));
+  }
+}
+
+
+/**
  * Report a (serious) inconsistency in the exchange's database.
  *
  * @param table affected table
@@ -310,33 +467,6 @@ report_row_inconsistency (const char *table,
 }
 
 
-/**
- * Report a global inconsistency with respect to a coin's history.
- *
- * @param coin_pub the affected coin
- * @param expected expected amount
- * @param observed observed amount
- * @param diagnostic message explaining what @a expected and @a observed refer 
to
- */
-static void
-report_coin_inconsistency (const struct TALER_CoinSpendPublicKeyP *coin_pub,
-                           const struct TALER_Amount *expected,
-                           const struct TALER_Amount *observed,
-                           const char *diagnostic)
-{
-  report (report_coin_inconsistencies,
-         json_pack ("{s:o, s:o, s:o, s:s}",
-                    "coin_pub",
-                    GNUNET_JSON_from_data_auto (coin_pub),
-                    "expected",
-                    TALER_JSON_from_amount (expected),
-                    "observed",
-                    TALER_JSON_from_amount (observed),
-                    "diagnostic",
-                    diagnostic));
-}
-
-
 /* ************************* Transaction-global state ************************ 
*/
 
 /**
@@ -765,9 +895,16 @@ handle_reserve_out (void *cls,
                                   &reserve_sig->eddsa_signature,
                                   &reserve_pub->eddsa_pub))
   {
-    report_row_inconsistency ("withdraw",
-                              rowid,
-                              "invalid signature for withdrawal");
+    report (report_bad_sig_losses,
+            json_pack ("{s:s, s:I, s:o, s:o}",
+                       "operation", "withdraw",
+                       "row", (json_int_t) rowid,
+                       "loss", TALER_JSON_from_amount (amount_with_fee),
+                       "key_pub", GNUNET_JSON_from_data_auto (reserve_pub)));
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (&total_bad_sig_loss,
+                                    &total_bad_sig_loss,
+                                    amount_with_fee));
     return GNUNET_OK;
   }
 
@@ -860,19 +997,26 @@ handle_payback_by_reserve (void *cls,
   /* should be monotonically increasing */
   GNUNET_assert (rowid >= pp.last_reserve_payback_serial_id);
   pp.last_reserve_payback_serial_id = rowid + 1;
+  GNUNET_CRYPTO_rsa_public_key_hash (coin->denom_pub.rsa_public_key,
+                                     &pr.h_denom_pub);
 
   if (GNUNET_OK !=
       TALER_test_coin_valid (coin))
   {
-    report_row_inconsistency ("payback",
-                              rowid,
-                              "coin denomination signature invalid");
+    report (report_bad_sig_losses,
+            json_pack ("{s:s, s:I, s:o, s:o}",
+                       "operation", "payback-verify",
+                       "row", (json_int_t) rowid,
+                       "loss", TALER_JSON_from_amount (amount),
+                       "key_pub", GNUNET_JSON_from_data_auto 
(&pr.h_denom_pub)));
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (&total_bad_sig_loss,
+                                    &total_bad_sig_loss,
+                                    amount));
   }
   pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_PAYBACK);
   pr.purpose.size = htonl (sizeof (pr));
   pr.coin_pub = coin->coin_pub;
-  GNUNET_CRYPTO_rsa_public_key_hash (coin->denom_pub.rsa_public_key,
-                                     &pr.h_denom_pub);
   pr.coin_blind = *coin_blind;
   if (GNUNET_OK !=
       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_PAYBACK,
@@ -880,9 +1024,16 @@ handle_payback_by_reserve (void *cls,
                                   &coin_sig->eddsa_signature,
                                   &coin->coin_pub.eddsa_pub))
   {
-    report_row_inconsistency ("payback",
-                              rowid,
-                              "coin payback signature invalid");
+    report (report_bad_sig_losses,
+            json_pack ("{s:s, s:I, s:o, s:o}",
+                       "operation", "payback",
+                       "row", (json_int_t) rowid,
+                       "loss", TALER_JSON_from_amount (amount),
+                       "key_pub", GNUNET_JSON_from_data_auto 
(&coin->coin_pub)));
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (&total_bad_sig_loss,
+                                    &total_bad_sig_loss,
+                                    amount));
   }
 
   /* check that the coin was eligible for payback!*/
@@ -921,9 +1072,6 @@ handle_payback_by_reserve (void *cls,
                                      &msig.eddsa_signature,
                                      &master_pub.eddsa_pub))
       {
-       report_row_inconsistency ("denomination_revocations",
-                                 rev_rowid,
-                                 "master signature invalid");
        rev = "master signature invalid";
       }
       else
@@ -937,6 +1085,19 @@ handle_payback_by_reserve (void *cls,
                                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
     }
   }
+  if (0 == strcmp (rev, "master signature invalid"))
+  {
+    report (report_bad_sig_losses,
+            json_pack ("{s:s, s:I, s:o, s:o}",
+                       "operation", "payback-master",
+                       "row", (json_int_t) rev_rowid,
+                       "loss", TALER_JSON_from_amount (amount),
+                       "key_pub", GNUNET_JSON_from_data_auto (&master_pub)));
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (&total_bad_sig_loss,
+                                    &total_bad_sig_loss,
+                                    amount));
+  }
 
   GNUNET_CRYPTO_hash (reserve_pub,
                       sizeof (*reserve_pub),
@@ -1833,10 +1994,11 @@ check_transaction_history (const struct 
TALER_CoinSpendPublicKeyP *coin_pub,
                              &refunds))
   {
     /* refunds above expenditures? Bad! */
-    report_coin_inconsistency (coin_pub,
-                               &expenditures,
-                               &refunds,
-                               "could not subtract refunded amount from 
expenditures");
+    report_coin_arithmetic_inconsistency ("refund (balance)",
+                                          coin_pub,
+                                          &expenditures,
+                                          &refunds,
+                                          0);
     return GNUNET_SYSERR;
   }
 
@@ -1847,10 +2009,11 @@ check_transaction_history (const struct 
TALER_CoinSpendPublicKeyP *coin_pub,
                              &value))
   {
     /* spent > value */
-    report_coin_inconsistency (coin_pub,
-                               &spent,
-                               &value,
-                               "accepted deposits (minus refunds) exceeds 
denomination value");
+    report_coin_arithmetic_inconsistency ("spend",
+                                          coin_pub,
+                                          &spent,
+                                          &value,
+                                          -1);
     return GNUNET_SYSERR;
   }
 
@@ -1861,10 +2024,11 @@ check_transaction_history (const struct 
TALER_CoinSpendPublicKeyP *coin_pub,
                              &merchant_loss))
   {
     /* refunds above deposits? Bad! */
-    report_coin_inconsistency (coin_pub,
-                               merchant_gain,
-                               &merchant_loss,
-                               "merchant was granted more refunds than he 
deposited");
+    report_coin_arithmetic_inconsistency ("refund (merchant)",
+                                          coin_pub,
+                                          merchant_gain,
+                                          &merchant_loss,
+                                          0);
     return GNUNET_SYSERR;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1905,7 +2069,6 @@ wire_transfer_information_cb (void *cls,
 {
   struct WireCheckContext *wcc = cls;
   const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki;
-  struct TALER_Amount contribution;
   struct TALER_Amount computed_value;
   struct TALER_Amount computed_fees;
   struct TALER_Amount coin_value_without_fee;
@@ -1977,9 +2140,11 @@ wire_transfer_information_cb (void *cls,
                              coin_fee))
   {
     wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
-    report_row_inconsistency ("aggregation",
-                              rowid,
-                              "inconsistent coin value and fee claimed in 
aggregation");
+    report_amount_arithmetic_inconsistency ("aggregation (fee structure)",
+                                            rowid,
+                                            coin_value,
+                                            coin_fee,
+                                            -1);
     return;
   }
   if (0 !=
@@ -1987,18 +2152,22 @@ wire_transfer_information_cb (void *cls,
                         &coin_value_without_fee))
   {
     wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
-    report_row_inconsistency ("aggregation",
-                              rowid,
-                              "coin transaction history and aggregation 
disagree about coin's contribution");
+    report_amount_arithmetic_inconsistency ("aggregation (contribution)",
+                                            rowid,
+                                            &coin_value_without_fee,
+                                            &computed_value,
+                                            -1);
   }
   if (0 !=
       TALER_amount_cmp (&computed_fees,
                         coin_fee))
   {
     wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
-    report_row_inconsistency ("aggregation",
-                              rowid,
-                              "coin transaction history and aggregation 
disagree about applicable fees");
+    report_amount_arithmetic_inconsistency ("aggregation (fee)",
+                                            rowid,
+                                            coin_fee,
+                                            &computed_fees,
+                                            1);
   }
   edb->free_coin_transaction_list (edb->cls,
                                    tl);
@@ -2032,23 +2201,12 @@ wire_transfer_information_cb (void *cls,
                               "date given in aggregate does not match wire 
transfer date");
     return;
   }
-  if (GNUNET_SYSERR ==
-      TALER_amount_subtract (&contribution,
-                             coin_value,
-                             coin_fee))
-  {
-    wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
-    report_row_inconsistency ("aggregation",
-                              rowid,
-                              "could not calculate contribution of coin");
-    return;
-  }
 
   /* Add coin's contribution to total aggregate value */
   if (GNUNET_OK !=
       TALER_amount_add (&wcc->total_deposits,
                        &wcc->total_deposits,
-                       &contribution))
+                       &coin_value_without_fee))
   {
     GNUNET_break (0);
     wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
@@ -2229,6 +2387,7 @@ check_wire_out_cb (void *cls,
   }
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != wcc.qs)
   {
+    /* FIXME: can we provide a more detailed error report? */
     report_row_inconsistency ("wire_out",
                               rowid,
                               "audit of associated transactions failed");
@@ -2250,9 +2409,11 @@ check_wire_out_cb (void *cls,
                              &wcc.total_deposits,
                              wire_fee))
   {
-    report_row_inconsistency ("wire_out",
-                              rowid,
-                              "could not subtract wire fee from total amount");
+    report_amount_arithmetic_inconsistency ("wire out (fee structure)",
+                                            rowid,
+                                            &wcc.total_deposits,
+                                            wire_fee,
+                                            -1);
     return GNUNET_OK;
   }
 
@@ -2852,9 +3013,16 @@ refresh_session_cb (void *cls,
                                   &coin_sig->eddsa_signature,
                                   &coin_pub->eddsa_pub))
   {
-    report_row_inconsistency ("melt",
-                              rowid,
-                              "invalid signature for coin melt");
+    report (report_bad_sig_losses,
+            json_pack ("{s:s, s:I, s:o, s:o}",
+                       "operation", "melt",
+                       "row", (json_int_t) rowid,
+                       "loss", TALER_JSON_from_amount (amount_with_fee),
+                       "key_pub", GNUNET_JSON_from_data_auto (coin_pub)));
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (&total_bad_sig_loss,
+                                    &total_bad_sig_loss,
+                                    amount_with_fee));
     return GNUNET_OK;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2952,9 +3120,11 @@ refresh_session_cb (void *cls,
                                &amount_without_fee))
     {
       /* refresh_cost > amount_without_fee */
-      report_row_inconsistency ("melt",
-                                rowid,
-                                "refresh costs exceed value of melt");
+      report_amount_arithmetic_inconsistency ("melt (fee)",
+                                              rowid,
+                                              &amount_without_fee,
+                                              &refresh_cost,
+                                              -1);
       return GNUNET_OK;
     }
 
@@ -3160,9 +3330,16 @@ deposit_cb (void *cls,
                                   &coin_sig->eddsa_signature,
                                   &coin_pub->eddsa_pub))
   {
-    report_row_inconsistency ("deposit",
-                              rowid,
-                              "invalid signature for coin deposit");
+    report (report_bad_sig_losses,
+            json_pack ("{s:s, s:I, s:o, s:o}",
+                       "operation", "deposit",
+                       "row", (json_int_t) rowid,
+                       "loss", TALER_JSON_from_amount (amount_with_fee),
+                       "key_pub", GNUNET_JSON_from_data_auto (coin_pub)));
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (&total_bad_sig_loss,
+                                    &total_bad_sig_loss,
+                                    amount_with_fee));
     return GNUNET_OK;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -3293,9 +3470,16 @@ refund_cb (void *cls,
                                   &merchant_sig->eddsa_sig,
                                   &merchant_pub->eddsa_pub))
   {
-    report_row_inconsistency ("refund",
-                              rowid,
-                              "invalid signature for refund");
+    report (report_bad_sig_losses,
+            json_pack ("{s:s, s:I, s:o, s:o}",
+                       "operation", "refund",
+                       "row", (json_int_t) rowid,
+                       "loss", TALER_JSON_from_amount (amount_with_fee),
+                       "key_pub", GNUNET_JSON_from_data_auto (merchant_pub)));
+    GNUNET_break (GNUNET_OK ==
+                  TALER_amount_add (&total_bad_sig_loss,
+                                    &total_bad_sig_loss,
+                                    amount_with_fee));
     return GNUNET_OK;
   }
 
@@ -3306,9 +3490,11 @@ refund_cb (void *cls,
                              amount_with_fee,
                              &refund_fee))
   {
-    report_row_inconsistency ("refund",
-                              rowid,
-                              "refunded amount smaller than refund fee");
+    report_amount_arithmetic_inconsistency ("refund (fee)",
+                                            rowid,
+                                            &amount_without_fee,
+                                            &refund_fee,
+                                            -1);
     return GNUNET_OK;
   }
 
@@ -3825,7 +4011,22 @@ run (void *cls,
                                         &total_wire_out_delta_minus));
   GNUNET_assert (GNUNET_OK ==
                  TALER_amount_get_zero (currency,
+                                        &total_arithmetic_delta_plus));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &total_arithmetic_delta_minus));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &total_coin_delta_plus));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &total_coin_delta_minus));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
                                         &total_balance_reserve_not_closed));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &total_bad_sig_loss));
   GNUNET_assert (NULL !=
                 (report_emergencies = json_array ()));
   GNUNET_assert (NULL !=
@@ -3844,6 +4045,10 @@ run (void *cls,
                 (report_coin_inconsistencies = json_array ()));
   GNUNET_assert (NULL !=
                 (report_aggregation_fee_balances = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_amount_arithmetic_inconsistencies = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_bad_sig_losses = json_array ()));
   setup_sessions_and_run ();
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Audit complete\n");
@@ -3866,7 +4071,9 @@ run (void *cls,
                       " s:o, s:o, s:o, s:o, s:o,"
                       " s:o, s:o, s:o, s:o, s:o,"
                       " s:o, s:o, s:o, s:o, s:o,"
-                      " s:o, s:o, s:o }",
+                      " s:o, s:o, s:o, s:o, s:o,"
+                      " s:o, s:o, s:o, s:o, s:o,"
+                      " s:o}",
                       /* blocks of 5 for easier counting/matching to format 
string */
                       /* block */
                      "reserve_balance_insufficient_inconsistencies",
@@ -3911,12 +4118,28 @@ run (void *cls,
                       "total_wire_out_delta_minus",
                       TALER_JSON_from_amount (&total_wire_out_delta_minus),
                       /* block */
+                      "bad_sig_losses",
+                      report_bad_sig_losses,
+                      "total_bad_sig_loss",
+                      TALER_JSON_from_amount (&total_bad_sig_loss),
                      "row_inconsistencies",
                       report_row_inconsistencies,
                      "denomination_key_validity_withdraw_inconsistencies",
                       denomination_key_validity_withdraw_inconsistencies,
                      "coin_inconsistencies",
                       report_coin_inconsistencies,
+                      /* block */
+                      "total_coin_delta_plus",
+                      TALER_JSON_from_amount (&total_coin_delta_plus),
+                      "total_coin_delta_minus",
+                      TALER_JSON_from_amount (&total_coin_delta_minus),
+                      "amount_arithmetic_inconsistencies",
+                      report_amount_arithmetic_inconsistencies,
+                      "total_arithmetic_delta_plus",
+                      TALER_JSON_from_amount (&total_arithmetic_delta_plus),
+                      "total_arithmetic_delta_minus",
+                      TALER_JSON_from_amount (&total_arithmetic_delta_minus),
+                      /* block */
                      "total_aggregation_fee_income",
                       TALER_JSON_from_amount (&total_aggregation_fee_income)
                       );

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]