implement #5177 (not yet tested)
This commit is contained in:
parent
8f48db8fdf
commit
11269125fa
@ -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}
|
\documentclass{article} % {acmart}
|
||||||
\usepackage{url}
|
\usepackage{url}
|
||||||
\usepackage[T1]{fontenc}
|
\usepackage[T1]{fontenc}
|
||||||
@ -7,7 +28,15 @@
|
|||||||
|
|
||||||
\begin{document}
|
\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
|
\maketitle
|
||||||
|
|
||||||
\section{Operations}
|
\section{Operations}
|
||||||
@ -569,6 +598,80 @@ have a clear financial impact.
|
|||||||
\end{longtable}
|
\end{longtable}
|
||||||
{% endif %}
|
{% 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}
|
\subsection{Other issues}
|
||||||
|
|
||||||
This section describes issues found that do not have a clear financial
|
This section describes issues found that do not have a clear financial
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
Copyright (C) 2016, 2017 Inria
|
Copyright (C) 2016, 2017 Inria
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
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.
|
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
|
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
|
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/>
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
@ -210,6 +210,11 @@ static json_t *report_aggregation_fee_balances;
|
|||||||
*/
|
*/
|
||||||
static json_t *report_amount_arithmetic_inconsistencies;
|
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.
|
* Profits the exchange made by bad amount calculations.
|
||||||
*/
|
*/
|
||||||
@ -2303,11 +2308,24 @@ get_wire_fee (struct AggregationContext *ac,
|
|||||||
pos->prev,
|
pos->prev,
|
||||||
wfi);
|
wfi);
|
||||||
/* Check non-overlaping fee invariant */
|
/* Check non-overlaping fee invariant */
|
||||||
/* TODO (#5177): report problems more nicely? */
|
if ( (NULL != wfi->prev) &&
|
||||||
if (NULL != wfi->prev)
|
(wfi->prev->end_date.abs_value_us > wfi->start_date.abs_value_us) )
|
||||||
GNUNET_break (wfi->prev->end_date.abs_value_us <= wfi->start_date.abs_value_us);
|
{
|
||||||
if (NULL != wfi->next)
|
report (report_fee_time_inconsistencies,
|
||||||
GNUNET_break (wfi->next->start_date.abs_value_us >= wfi->end_date.abs_value_us);
|
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;
|
return &wfi->wire_fee;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4085,6 +4103,8 @@ run (void *cls,
|
|||||||
(report_amount_arithmetic_inconsistencies = json_array ()));
|
(report_amount_arithmetic_inconsistencies = json_array ()));
|
||||||
GNUNET_assert (NULL !=
|
GNUNET_assert (NULL !=
|
||||||
(report_bad_sig_losses = json_array ()));
|
(report_bad_sig_losses = json_array ()));
|
||||||
|
GNUNET_assert (NULL !=
|
||||||
|
(report_fee_time_inconsistencies = json_array ()));
|
||||||
setup_sessions_and_run ();
|
setup_sessions_and_run ();
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"Audit complete\n");
|
"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, 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 */
|
/* blocks of 5 for easier counting/matching to format string */
|
||||||
/* block */
|
/* block */
|
||||||
"reserve_balance_insufficient_inconsistencies",
|
"reserve_balance_insufficient_inconsistencies",
|
||||||
@ -4175,9 +4196,10 @@ run (void *cls,
|
|||||||
"total_arithmetic_delta_minus",
|
"total_arithmetic_delta_minus",
|
||||||
TALER_JSON_from_amount (&total_arithmetic_delta_minus),
|
TALER_JSON_from_amount (&total_arithmetic_delta_minus),
|
||||||
"total_aggregation_fee_income",
|
"total_aggregation_fee_income",
|
||||||
TALER_JSON_from_amount (&total_aggregation_fee_income)
|
TALER_JSON_from_amount (&total_aggregation_fee_income),
|
||||||
/* block */
|
/* block */
|
||||||
);
|
"wire_fee_time_inconsistencies",
|
||||||
|
report_fee_time_inconsistencies);
|
||||||
GNUNET_break (NULL != report);
|
GNUNET_break (NULL != report);
|
||||||
json_dumpf (report,
|
json_dumpf (report,
|
||||||
stdout,
|
stdout,
|
||||||
|
@ -159,6 +159,12 @@ static json_t *report_missattribution_in_inconsistencies;
|
|||||||
*/
|
*/
|
||||||
static json_t *report_row_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.
|
* Array of reports about minor row inconcistencies.
|
||||||
*/
|
*/
|
||||||
@ -201,6 +207,11 @@ static struct TALER_Amount total_missattribution_in;
|
|||||||
*/
|
*/
|
||||||
static struct TALER_Amount total_amount_lag;
|
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.
|
* Amount of zero in our currency.
|
||||||
*/
|
*/
|
||||||
@ -324,7 +335,7 @@ do_shutdown (void *cls)
|
|||||||
GNUNET_assert (NULL != report_row_minor_inconsistencies);
|
GNUNET_assert (NULL != report_row_minor_inconsistencies);
|
||||||
report = json_pack ("{s:o, s:o, s:o, s:o, s:o,"
|
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, s:o }",
|
" s:o, s:o, s:o, s:o }",
|
||||||
/* blocks of 5 */
|
/* blocks of 5 */
|
||||||
"wire_out_amount_inconsistencies",
|
"wire_out_amount_inconsistencies",
|
||||||
report_wire_out_inconsistencies,
|
report_wire_out_inconsistencies,
|
||||||
@ -348,6 +359,10 @@ do_shutdown (void *cls)
|
|||||||
"row_minor_inconsistencies",
|
"row_minor_inconsistencies",
|
||||||
report_row_minor_inconsistencies,
|
report_row_minor_inconsistencies,
|
||||||
/* block */
|
/* block */
|
||||||
|
"total_wire_format_amount",
|
||||||
|
TALER_JSON_from_amount (&total_wire_format_amount),
|
||||||
|
"wire_format_inconsistencies",
|
||||||
|
report_wire_format_inconsistencies,
|
||||||
"total_amount_lag",
|
"total_amount_lag",
|
||||||
TALER_JSON_from_amount (&total_bad_amount_in_minus),
|
TALER_JSON_from_amount (&total_bad_amount_in_minus),
|
||||||
"lag_details",
|
"lag_details",
|
||||||
@ -363,6 +378,7 @@ do_shutdown (void *cls)
|
|||||||
report_row_minor_inconsistencies = NULL;
|
report_row_minor_inconsistencies = NULL;
|
||||||
report_missattribution_in_inconsistencies = NULL;
|
report_missattribution_in_inconsistencies = NULL;
|
||||||
report_lags = NULL;
|
report_lags = NULL;
|
||||||
|
report_wire_format_inconsistencies = NULL;
|
||||||
}
|
}
|
||||||
if (NULL != hh)
|
if (NULL != hh)
|
||||||
{
|
{
|
||||||
@ -846,18 +862,17 @@ history_debit_cb (void *cls,
|
|||||||
row_off_size,
|
row_off_size,
|
||||||
&rowh);
|
&rowh);
|
||||||
GNUNET_asprintf (&diagnostic,
|
GNUNET_asprintf (&diagnostic,
|
||||||
"malformed wire transfer subject `%s'",
|
"malformed subject `%8s...'",
|
||||||
details->wtid_s);
|
details->wtid_s);
|
||||||
report (report_row_inconsistencies,
|
GNUNET_break (GNUNET_OK ==
|
||||||
json_pack ("{s:s, s:I, s:o, s:o, s:s}",
|
TALER_amount_add (&total_wire_format_amount,
|
||||||
"table", "bank wire log",
|
&total_wire_format_amount,
|
||||||
"row", (json_int_t) 0,
|
&details->amount));
|
||||||
|
report (report_wire_format_inconsistencies,
|
||||||
|
json_pack ("{s:o, s:o, s:s}",
|
||||||
"amount", TALER_JSON_from_amount (&details->amount),
|
"amount", TALER_JSON_from_amount (&details->amount),
|
||||||
"wire_offset_hash", GNUNET_JSON_from_data_auto (&rowh),
|
"wire_offset_hash", GNUNET_JSON_from_data_auto (&rowh),
|
||||||
"diagnostic", diagnostic));
|
"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);
|
GNUNET_free (diagnostic);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
@ -881,18 +896,17 @@ history_debit_cb (void *cls,
|
|||||||
row_off_size,
|
row_off_size,
|
||||||
&rowh);
|
&rowh);
|
||||||
GNUNET_asprintf (&diagnostic,
|
GNUNET_asprintf (&diagnostic,
|
||||||
"duplicate wire transfer subject `%s'",
|
"duplicate subject hash `%8s...'",
|
||||||
TALER_B2S (&roi->subject_hash));
|
TALER_B2S (&roi->subject_hash));
|
||||||
report (report_row_inconsistencies,
|
GNUNET_break (GNUNET_OK ==
|
||||||
json_pack ("{s:s, s:I, s:o, s:o, s:s}",
|
TALER_amount_add (&total_wire_format_amount,
|
||||||
"table", "bank wire log",
|
&total_wire_format_amount,
|
||||||
"row", (json_int_t) 0,
|
&details->amount));
|
||||||
|
report (report_wire_format_inconsistencies,
|
||||||
|
json_pack ("{s:o, s:o, s:s}",
|
||||||
"amount", TALER_JSON_from_amount (&details->amount),
|
"amount", TALER_JSON_from_amount (&details->amount),
|
||||||
"wire_offset_hash", GNUNET_JSON_from_data_auto (&rowh),
|
"wire_offset_hash", GNUNET_JSON_from_data_auto (&rowh),
|
||||||
"diagnostic", diagnostic));
|
"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);
|
GNUNET_free (diagnostic);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
@ -1381,6 +1395,8 @@ run (void *cls,
|
|||||||
(report_reserve_in_inconsistencies = json_array ()));
|
(report_reserve_in_inconsistencies = json_array ()));
|
||||||
GNUNET_assert (NULL !=
|
GNUNET_assert (NULL !=
|
||||||
(report_row_minor_inconsistencies = json_array ()));
|
(report_row_minor_inconsistencies = json_array ()));
|
||||||
|
GNUNET_assert (NULL !=
|
||||||
|
(report_wire_format_inconsistencies = json_array ()));
|
||||||
GNUNET_assert (NULL !=
|
GNUNET_assert (NULL !=
|
||||||
(report_row_inconsistencies = json_array ()));
|
(report_row_inconsistencies = json_array ()));
|
||||||
GNUNET_assert (NULL !=
|
GNUNET_assert (NULL !=
|
||||||
@ -1405,6 +1421,9 @@ run (void *cls,
|
|||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_amount_get_zero (currency,
|
TALER_amount_get_zero (currency,
|
||||||
&total_amount_lag));
|
&total_amount_lag));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&total_wire_format_amount));
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_amount_get_zero (currency,
|
TALER_amount_get_zero (currency,
|
||||||
&zero));
|
&zero));
|
||||||
|
Loading…
Reference in New Issue
Block a user