diff options
| -rw-r--r-- | contrib/auditor-report.tex.j2 | 105 | ||||
| -rw-r--r-- | src/auditor/taler-auditor.c | 44 | ||||
| -rw-r--r-- | src/auditor/taler-wire-auditor.c | 53 | 
3 files changed, 173 insertions, 29 deletions
| diff --git a/contrib/auditor-report.tex.j2 b/contrib/auditor-report.tex.j2 index 921daabc..ab5a1610 100644 --- a/contrib/auditor-report.tex.j2 +++ b/contrib/auditor-report.tex.j2 @@ -1,3 +1,24 @@ +% This file is part of TALER +% Copyright (C) 2016, 2017 Taler Systems SA +% +% TALER is free software; you can redistribute it and/or modify it under the +% terms of the GNU Affero General Public License as published by the Free Software +% Foundation; either version 3, or (at your option) any later version. +% +% TALER is distributed in the hope that it will be useful, but WITHOUT ANY +% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +% A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details. +% +% You should have received a copy of the GNU Affero General Public License along with +% TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> +% +% +% With respect to this file, our interpretation of the license is +% that publishing an audit report (i.e. in TeX or PDF) requires +% publishing the corresponding j2 template sources under AGPL, and +% linking to them from the report. (This file _is_ source code, +% the generated PDF is the service under definition of the AGPL.) +%  \documentclass{article} % {acmart}  \usepackage{url}  \usepackage[T1]{fontenc} @@ -7,7 +28,15 @@  \begin{document} -\title{Taler Auditor Report} +% If you update this template, complying with the license requires +% publishing the J2 source and linking to it from the generated PDF. +% So if you change this outside of the Taler Git repository, you must +% update this link (and the link must remain available to the receiver +% of the result from the generated TeX, PDF or other format). +\title{Taler Auditor Report\footnote{Template available at \url{https://git.taler.net/}}} + +% You must also credit the original author. +\author{Christian Grothoff}  \maketitle  \section{Operations} @@ -569,6 +598,80 @@ have a clear financial impact.    \end{longtable}  {% endif %} + +\subsection{Outgoing wire transfer subject issues} + +This section describes issues found by the wire auditor that +relate to outgoing wire transfers being malformed. +This happens if the exchange somehow creates wire transfers +with duplicate or malformed wire transfer subjects. + +{% if wire.wire_format_inconsistencies|length() == 0 %} +  {\bf No wire format inconsistencies found.} +{% else %} +  \begin{longtable}{p{4.5cm}|rl} +  \multicolumn{3}{c}{ {\bf Row hash} } \\ +  {\bf Diagnostic} & \multicolumn{2}{c|}{ {\bf Amount} } \\ +  \hline \hline +\endfirsthead +  \multicolumn{3}{c}{ {\bf Row hash} } \\ +  {\bf Diagnostic} & \multicolumn{2}{c|}{ {\bf Amount} } \\ +  \hline \hline +\endhead +  \hline +  \multicolumn{3}{c}{ {\bf Row hash} } \\ +  {\bf Diagnostic} & \multicolumn{2}{c|}{ {\bf Amount} } \\ +\endfoot +  \hline +  \hline +  {\bf Total} & +  {{ wire.total_wire_format_amount.value }}.{{ wire.total_wire_format_amount.fraction }} & +  {{ wire.total_wire_format_amount.currency }} \\ +  \caption{Outgoing wire transfer subject issues found.} +  \label{table:outgoing:wtid} +\endlastfoot +{% for item in wire.wire_format_inconsistencies %} +  \multicolumn{3}{l}{ \verb! {{ item.wire_offset_hash }} ! } \\ +\nopagebreak +  {{ item.diagnostic }} & +  {{ item.amount.value }}.{{ item.amount.fraction }} & +  {{ item.amount.currency }} \\ +{% endfor %} +  \end{longtable} +{% endif %} + + +\subsection{Wire fee structure inconsistencies} + +This section lists cases where the exchange's database may be ambiguous +with respect to what wire fee it charges at what time. + +{% if data.wire_fee_time_inconsistencies|length() == 0 %} +  {\bf No wire fee timing issues detected.} +{% else %} +  \begin{longtable}{p{1.5cm}|r|p{5.5}} +  {\bf Wire format} & {\bf Timestamp} & {\bf Diagnostic} +  \\ \hline \hline +\endfirsthead +  {\bf Wire format} & {\bf Timestamp} & {\bf Diagnostic} +  \\ \hline \hline +\endhead +  \hline \hline +  {\bf Wire format} & {\bf Timestamp} & {\bf Diagnostic} \\ +\endfoot +  \hline \hline +  {\bf Wire format} & {\bf Timestamp} & {\bf Diagnostic} \\ +  \caption{Wire fees with ambiguous timestamps.} +  \label{table:wire_fee:ambiguity} +\endlastfoot +{% for item in data.wire_fee_time_inconsistencies %} +  {\tt {{ item.type }} } & {{ item.time }} & {{ item.diagnostic }} \\ \hline +{% endfor %} +  \end{longtable} +{% endif %} + + +  \subsection{Other issues}  This section describes issues found that do not have a clear financial diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c index 7016dc70..cd1ee0d2 100644 --- a/src/auditor/taler-auditor.c +++ b/src/auditor/taler-auditor.c @@ -3,14 +3,14 @@    Copyright (C) 2016, 2017 Inria    TALER is free software; you can redistribute it and/or modify it under the -  terms of the GNU General Public License as published by the Free Software +  terms of the GNU Affero Public License as published by the Free Software    Foundation; either version 3, or (at your option) any later version.    TALER is distributed in the hope that it will be useful, but WITHOUT ANY    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -  A PARTICULAR PURPOSE.  See the GNU General Public License for more details. +  A PARTICULAR PURPOSE.  See the GNU Affero Public License for more details. -  You should have received a copy of the GNU General Public License along with +  You should have received a copy of the GNU Affero Public License along with    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>  */  /** @@ -211,6 +211,11 @@ static json_t *report_aggregation_fee_balances;  static json_t *report_amount_arithmetic_inconsistencies;  /** + * Array of reports about wire fees being ambiguous in terms of validity periods. + */ +static json_t *report_fee_time_inconsistencies; + +/**   * Profits the exchange made by bad amount calculations.   */  static struct TALER_Amount total_arithmetic_delta_plus; @@ -2303,11 +2308,24 @@ get_wire_fee (struct AggregationContext *ac,                                         pos->prev,                                         wfi);    /* Check non-overlaping fee invariant */ -  /* TODO (#5177): report problems more nicely? */ -  if (NULL != wfi->prev) -    GNUNET_break (wfi->prev->end_date.abs_value_us <= wfi->start_date.abs_value_us); -  if (NULL != wfi->next) -    GNUNET_break (wfi->next->start_date.abs_value_us >= wfi->end_date.abs_value_us); +  if ( (NULL != wfi->prev) && +       (wfi->prev->end_date.abs_value_us > wfi->start_date.abs_value_us) ) +  { +    report (report_fee_time_inconsistencies, +            json_pack ("{s:s, s:s, s:s}", +                       "type", type, +                       "diagnostic", "start date before previous end date", +                       "time", GNUNET_STRINGS_absolute_time_to_string (wfi->start_date))); +  } +  if ( (NULL != wfi->next) && +       (wfi->next->start_date.abs_value_us >= wfi->end_date.abs_value_us) ) +  { +    report (report_fee_time_inconsistencies, +            json_pack ("{s:s, s:s, s:s}", +                       "type", type, +                       "diagnostic", "end date date after next start date", +                       "time", GNUNET_STRINGS_absolute_time_to_string (wfi->end_date))); +  }    return &wfi->wire_fee;  } @@ -4085,6 +4103,8 @@ run (void *cls,  		 (report_amount_arithmetic_inconsistencies = json_array ()));    GNUNET_assert (NULL !=  		 (report_bad_sig_losses = json_array ())); +  GNUNET_assert (NULL != +		 (report_fee_time_inconsistencies = json_array ()));    setup_sessions_and_run ();    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,                "Audit complete\n"); @@ -4108,7 +4128,8 @@ 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 }",                        /* blocks of 5 for easier counting/matching to format string */                        /* block */  		      "reserve_balance_insufficient_inconsistencies", @@ -4175,9 +4196,10 @@ run (void *cls,                        "total_arithmetic_delta_minus",                        TALER_JSON_from_amount (&total_arithmetic_delta_minus),  		      "total_aggregation_fee_income", -                      TALER_JSON_from_amount (&total_aggregation_fee_income) +                      TALER_JSON_from_amount (&total_aggregation_fee_income),                        /* block */ -                      ); +                      "wire_fee_time_inconsistencies", +                      report_fee_time_inconsistencies);    GNUNET_break (NULL != report);    json_dumpf (report,  	      stdout, diff --git a/src/auditor/taler-wire-auditor.c b/src/auditor/taler-wire-auditor.c index a9a4e8c8..9f16794d 100644 --- a/src/auditor/taler-wire-auditor.c +++ b/src/auditor/taler-wire-auditor.c @@ -160,6 +160,12 @@ static json_t *report_missattribution_in_inconsistencies;  static json_t *report_row_inconsistencies;  /** + * Array of reports about inconcistencies in the database about + * the incoming wire transfers (exchange is not exactly to blame). + */ +static json_t *report_wire_format_inconsistencies; + +/**   * Array of reports about minor row inconcistencies.   */  static json_t *report_row_minor_inconsistencies; @@ -202,6 +208,11 @@ static struct TALER_Amount total_missattribution_in;  static struct TALER_Amount total_amount_lag;  /** + * Total amount affected by wire format trouble.s + */ +static struct TALER_Amount total_wire_format_amount; + +/**   * Amount of zero in our currency.   */  static struct TALER_Amount zero; @@ -324,7 +335,7 @@ do_shutdown (void *cls)      GNUNET_assert (NULL != report_row_minor_inconsistencies);      report = json_pack ("{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 */  			"wire_out_amount_inconsistencies",                          report_wire_out_inconsistencies, @@ -348,6 +359,10 @@ do_shutdown (void *cls)  			"row_minor_inconsistencies",                          report_row_minor_inconsistencies,                          /* block */ +                        "total_wire_format_amount", +                        TALER_JSON_from_amount (&total_wire_format_amount), +                        "wire_format_inconsistencies", +                        report_wire_format_inconsistencies,                          "total_amount_lag",                          TALER_JSON_from_amount (&total_bad_amount_in_minus),                          "lag_details", @@ -363,6 +378,7 @@ do_shutdown (void *cls)      report_row_minor_inconsistencies = NULL;      report_missattribution_in_inconsistencies = NULL;      report_lags = NULL; +    report_wire_format_inconsistencies = NULL;    }    if (NULL != hh)    { @@ -846,18 +862,17 @@ history_debit_cb (void *cls,                          row_off_size,                          &rowh);      GNUNET_asprintf (&diagnostic, -                     "malformed wire transfer subject `%s'", +                     "malformed subject `%8s...'",                       details->wtid_s); -    report (report_row_inconsistencies, -            json_pack ("{s:s, s:I, s:o, s:o, s:s}", -                       "table", "bank wire log", -                       "row", (json_int_t) 0, +    GNUNET_break (GNUNET_OK == +                  TALER_amount_add (&total_wire_format_amount, +                                    &total_wire_format_amount, +                                    &details->amount)); +    report (report_wire_format_inconsistencies, +            json_pack ("{s:o, s:o, s:s}",                         "amount", TALER_JSON_from_amount (&details->amount),                         "wire_offset_hash", GNUNET_JSON_from_data_auto (&rowh),                         "diagnostic", diagnostic)); -    /* TODO (#5177): report generator currently ignores 'amount' for this -       table, maybe use a different table to report this issue! */ -    /* TODO: add 'amount' to some total amount that was badly wired! */      GNUNET_free (diagnostic);      return GNUNET_SYSERR;    } @@ -881,18 +896,17 @@ history_debit_cb (void *cls,                          row_off_size,                          &rowh);      GNUNET_asprintf (&diagnostic, -                     "duplicate wire transfer subject `%s'", +                     "duplicate subject hash `%8s...'",                       TALER_B2S (&roi->subject_hash)); -    report (report_row_inconsistencies, -            json_pack ("{s:s, s:I, s:o, s:o, s:s}", -                       "table", "bank wire log", -                       "row", (json_int_t) 0, +    GNUNET_break (GNUNET_OK == +                  TALER_amount_add (&total_wire_format_amount, +                                    &total_wire_format_amount, +                                    &details->amount)); +    report (report_wire_format_inconsistencies, +            json_pack ("{s:o, s:o, s:s}",                         "amount", TALER_JSON_from_amount (&details->amount),                         "wire_offset_hash", GNUNET_JSON_from_data_auto (&rowh),                         "diagnostic", diagnostic)); -    /* TODO (#5177): report generator currently ignores 'amount' for this -       table, maybe use a different table to report this issue! */ -    /* TODO: add 'amount' to some total amount that was badly wired! */      GNUNET_free (diagnostic);      return GNUNET_SYSERR;    } @@ -1382,6 +1396,8 @@ run (void *cls,    GNUNET_assert (NULL !=  		 (report_row_minor_inconsistencies = json_array ()));    GNUNET_assert (NULL != +		 (report_wire_format_inconsistencies = json_array ())); +  GNUNET_assert (NULL !=  		 (report_row_inconsistencies = json_array ()));    GNUNET_assert (NULL !=  		 (report_missattribution_in_inconsistencies = json_array ())); @@ -1407,6 +1423,9 @@ run (void *cls,                                          &total_amount_lag));    GNUNET_assert (GNUNET_OK ==                   TALER_amount_get_zero (currency, +                                        &total_wire_format_amount)); +  GNUNET_assert (GNUNET_OK == +                 TALER_amount_get_zero (currency,                                          &zero));    qsx = adb->get_wire_auditor_progress (adb->cls, | 
