summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/auditor-report.tex.j2227
-rw-r--r--src/auditor/taler-auditor.c391
2 files changed, 459 insertions, 159 deletions
diff --git a/contrib/auditor-report.tex.j2 b/contrib/auditor-report.tex.j2
index ff31e7b05..9f454ffe6 100644
--- a/contrib/auditor-report.tex.j2
+++ b/contrib/auditor-report.tex.j2
@@ -58,11 +58,11 @@ This section analyzes the income of the exchange operator from fees.
\end{table}
-\section{Irregularities}
+\section{Major irregularities}
-This section describes the possible irregularities that the auditor
-has checked, and lists all of the actual irregularities encountered
-in detail.
+This section describes the possible major irregularities that the
+auditor has checked, and lists all of the actual irregularities
+encountered in detail.
\subsection{Emergencies}
@@ -108,11 +108,8 @@ compromise.
{% endif %}
-\subsection{Reserve inconsistencies}
-{% if data.reserve_inconsistencies|length() == 0 %}
- {\bf No reserve inconsistencies detected.}
-{% else %}
+
\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
\endfirsthead
@@ -138,6 +135,220 @@ compromise.
{{ item.diagnostic }} \\ \hline
{% endfor %}
\end{longtable}
+
+
+\subsection{Reserve withdrawals exceeding balance}
+
+This section highlights cases where more coins were withdrawn from a
+reserve than the reserve contained funding for. This is a serious
+compromise resulting in proportional financial losses to the exchange.
+
+
+{% if data.reserve_balance_insufficient_inconsistencies|length() == 0 %}
+ {\bf All withdrawals were covered by sufficient reserve funding.}
+{% else %}
+ \begin{longtable}{p{4.5cm}|rl}
+ {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Loss}} \\ \hline \hline
+\endfirsthead
+ {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Loss}} \\ \hline \hline
+\endhead
+ \hline \hline
+ {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Loss}}
+\endfoot
+ \hline
+ {\bf Total loss} & &
+ {{ data.total_loss_balance_insufficient.value}}.{{ data.total_loss_balance_insufficient.fraction}} & {{ data.total_loss_balance_insufficient.currency}} \\
+ \caption{Reserves with withdrawals higher than reserve funding.}
+ \label{table:reserve:balance_insufficient}
+\endlastfoot
+{% for item in data.reserve_balance_insufficient_inconsistencies %}
+ \multicolumn{3}{l}{ {\tt {{ item.reserve_pub }} } } \\
+\nopagebreak
+ &
+ {{ item.loss.value }}.{{ item.loss.fraction }} &
+ {{ item.loss.currency }} \\ \hline
+{% endfor %}
+ \end{longtable}
+{% endif %}
+
+
+\subsection{Claimed outgoing wire transfers}
+
+This section is about the exchange's database containing a
+justification to make an outgoing wire transfer for an aggregated
+amount for various deposits. It is reported as an inconsistency if the
+amount claimed for the wire transfer does not match up the deposits
+aggregated. This is about a {\em claimed} outgoing wire transfer as
+violations do not imply that the wire transfer was actually made (as
+that is a separate check). Note that not making the wire transfer
+would be reported separately in Section~\ref{sec:wire_check_out}.
+
+
+{% if data.reserve_wire_out_inconsistencies|length() == 0 %}
+ {\bf All aggregations matched up.}
+{% else %}
+ \begin{longtable}{p{1.5cm}|l|rl|rl}
+ {\bf Destination account} & {\bf Database row} & \multicolumn{2}{|c|}{ {\bf Expected}} & \multicolumn{2}{|c|}{ {\bf Claimed}} \\ \hline \hline
+\endfirsthead
+ {\bf Destination account} & {\bf Database row} & \multicolumn{2}{|c|}{ {\bf Expected}} & \multicolumn{2}{|c|}{ {\bf Claimed}} \\ \hline \hline
+\endhead
+ \hline \hline
+ {\bf Destination account} & {\bf Database row} & \multicolumn{2}{|c|}{ {\bf Expected}} & \multicolumn{2}{|c|}{ {\bf Claimed}} \\
+\endfoot
+ \hline
+ {\bf Total deltas} & &
+ {{ data.total_wire_out_delta_plus.value}}.{{ data.total_wire_out_delta_plus.fraction}} & {{ data.total_wire_out_delta_plus.currency}} &
+ - {{ data.total_wire_out_delta_minus.value}}.{{ data.total_wire_out_delta_minus.fraction}} & {{ data.total_wire_out_delta_minus.currency}} \\
+ \caption{Claimed wire out aggregate totals not matching up.}
+ \label{table:reserve:wire_out_balance_inconsistencies}
+\endlastfoot
+{% for item in data.wire_out_inconsistencies %}
+ \multicolumn{6}{l}{ {\tt {{ item.destination_account }} } } \\
+\nopagebreak
+ & {{ item.rowid }} &
+ {{ item.expected.value }}.{{ item.expected.fraction }} &
+ {{ item.expected.currency }} &
+ {{ item.claimed.value }}.{{ item.claimed.fraction }} &
+ {{ item.claimed.currency }} \\ \hline
+{% endfor %}
+ \end{longtable}
+{% endif %}
+
+
+\subsection{Coin history inconsistencies}
+
+TODO.
+
+
+\subsection{Actual incoming wire transfers}
+
+TBD. See bug 4958.
+
+\subsection{Actual outgoing wire transfers} \label{sec:wire_check_out}
+
+TBD. See bug 4958.
+
+\section{Minor irregularities}
+
+\subsection{Incorrect reserve balance summary in database}
+
+This section highlights cases where the reserve balance summary
+in the database does not match the calculations made by the auditor.
+Deltas may indicate a corrupt database, but do not necessarily
+translate into a financial loss (yet).
+
+
+{% if data.reserve_balance_summary_wrong_inconsistencies|length() == 0 %}
+ {\bf All balances matched up.}
+{% else %}
+ \begin{longtable}{p{1.5cm}|rl|rl}
+ {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Auditor}} & \multicolumn{2}{|c|}{ {\bf Exchange}} \\ \hline \hline
+\endfirsthead
+ {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Auditor}} & \multicolumn{2}{|c|}{ {\bf Exchange}} \\ \hline \hline
+\endhead
+ \hline \hline
+ {\bf Reserve} & \multicolumn{2}{|c|}{ {\bf Auditor}} & \multicolumn{2}{|c|}{ {\bf Exchange}}
+\endfoot
+ \hline
+ {\bf Total deltas} & &
+ {{ data.total_balance_summary_delta_plus.value}}.{{ data.total_balance_summary_delta_plus.fraction}} & {{ data.total_balance_summary_delta_plus.currency}} &
+ - {{ data.total_balance_summary_delta_minus.value}}.{{ data.total_balance_summary_delta_minus.fraction}} & {{ data.total_balance_summary_delta_minus.currency}} \\
+ \caption{Reserves balances not matching up.}
+ \label{table:reserve:balance_inconsistencies}
+\endlastfoot
+{% for item in data.reserve_balance_summary_wrong_inconsistencies %}
+ \multicolumn{5}{l}{ {\tt {{ item.reserve_pub }} } } \\
+\nopagebreak
+ &
+ {{ item.auditor.value }}.{{ item.auditor.fraction }} &
+ {{ item.auditor.currency }} &
+ {{ item.exchange.value }}.{{ item.exchange.fraction }} &
+ {{ item.exchange.currency }} \\ \hline
+{% endfor %}
+ \end{longtable}
+{% endif %}
+
+
+\section{Delays and timing}
+
+This section describes issues that are likely caused simply by
+some job process of the exchange not running properly or not having
+caught up with the work load yet.
+
+\subsection{Delayed closure of reserves}
+
+This section describes cases where the exchange did not
+close a reserve and wire back the remaining funds when the
+reserve expired.
+
+
+{% if data.reserve_not_closed_inconsistencies|length() == 0 %}
+ {\bf All expired reserves were closed.}
+{% else %}
+ \begin{longtable}{p{1.5cm}|c|rl}
+ {\bf Reserve} & {\bf Expired} & \multicolumn{2}{|c|}{ {\bf Balance}} \\ \hline \hline
+\endfirsthead
+ {\bf Reserve} & {\bf Expired} & \multicolumn{2}{|c|}{ {\bf Balance}} \\ \hline \hline
+\endhead
+ \hline \hline
+ {\bf Reserve} & {\bf Expired} & \multicolumn{2}{|c|}{ {\bf Balance}}
+\endfoot
+ \hline
+ {\bf Sum} & &
+ {{ data.total_balance_reserve_not_closed.value}}.{{ data.total_balance_reserve_not_closed.fraction}} & {{ data.total_balance_reserve_not_closed.currency}} \\
+ \caption{Reserves not closed on time.}
+ \label{table:reserve:not_closed}
+\endlastfoot
+{% for item in data.reserve_not_closed_inconsistencies %}
+ \multicolumn{4}{l}{ {\tt {{ item.reserve_pub }} } } \\
+\nopagebreak
+ &
+ {{ item.expiration_time }} &
+ {{ item.balance.value }}.{{ item.balance.fraction }} &
+ {{ item.balance.currency }} \\ \hline
+{% endfor %}
+ \end{longtable}
{% endif %}
+
+\subsection{Denomination key invalid at time of withdrawal}
+
+This section lists cases where a denomination key was not valid for
+withdrawal at the time when the exchange claims to have signed a coin
+with it. This would be irregular, but has no obvious financial
+implications.
+
+
+{% if data.denomination_key_validity_withdraw_inconsistencies|length() == 0 %}
+ {\bf All denomination keys were valid at the time of withdrawals.}
+{% else %}
+ \begin{longtable}{p{7.5cm}|c}
+ {\bf Reserve} & {\bf Table row} \\
+ {\bf Denomination key hash} & {\bf Execution time} \\ \hline \hline
+\endfirsthead
+ {\bf Reserve} & {\bf Table row} \\
+ {\bf Denomination key hash} & {\bf Execution time} \\ \hline \hline
+\endhead
+ \hline \hline
+ {\bf Reserve} & {\bf Table row} \\
+ {\bf Denomination key hash} & {\bf Execution time} \\
+\endfoot
+ \hline
+ {\bf Reserve} & {\bf Table row} \\
+ {\bf Denomination key hash} & {\bf Execution time} \\
+ \caption{Execution times not matching denomination key validity period.}
+ \label{table:withdraw:bad_time}
+\endlastfoot
+{% for item in data.denomination_key_validity_withdraw_inconsistencies %}
+ {\tt {{ item.reserve_pub }} } & {{ item.row }} \\
+\nopagebreak
+ &
+ {\tt {{ item.denompub_h }} } & {{ item.execution_date }} \\ \hline
+{% endfor %}
+ \end{longtable}
+{% endif %}
+
+
+
+
\end{document}
diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index 4dbcaea89..1190e5c34 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -125,14 +125,47 @@ static json_t *report_emergencies;
static json_t *report_row_inconsistencies;
/**
- * Array of reports about minor row inconcistencies.
+ * Array of reports about the denomination key not being
+ * valid at the time of withdrawal.
*/
-static json_t *report_row_minor_inconsistencies;
+static json_t *denomination_key_validity_withdraw_inconsistencies;
/**
- * Array of reports about reserve inconsitencies.
+ * Array of reports about reserve balance insufficient inconsitencies.
*/
-static json_t *report_reserve_inconsistencies;
+static json_t *report_reserve_balance_insufficient_inconsistencies;
+
+/**
+ * Total amount reserves were charged beyond their balance.
+ */
+static struct TALER_Amount total_balance_insufficient_loss;
+
+/**
+ * Array of reports about reserve balance summary wrong in database.
+ */
+static json_t *report_reserve_balance_summary_wrong_inconsistencies;
+
+/**
+ * Total delta between expected and stored reserve balance summaries,
+ * for positive deltas.
+ */
+static struct TALER_Amount total_balance_summary_delta_plus;
+
+/**
+ * Total delta between expected and stored reserve balance summaries,
+ * for negative deltas.
+ */
+static struct TALER_Amount total_balance_summary_delta_minus;
+
+/**
+ * Array of reports about reserve's not being closed inconsitencies.
+ */
+static json_t *report_reserve_not_closed_inconsistencies;
+
+/**
+ * Total amount affected by reserves not having been closed on time.
+ */
+static struct TALER_Amount total_balance_reserve_not_closed;
/**
* Array of reports about irregular wire out entries.
@@ -140,6 +173,18 @@ static json_t *report_reserve_inconsistencies;
static json_t *report_wire_out_inconsistencies;
/**
+ * Total delta between calculated and stored wire out transfers,
+ * for positive deltas.
+ */
+static struct TALER_Amount total_wire_out_delta_plus;
+
+/**
+ * Total delta between calculated and stored wire out transfers
+ * for negative deltas.
+ */
+static struct TALER_Amount total_wire_out_delta_minus;
+
+/**
* Array of reports about inconsistencies about coins.
*/
static json_t *report_coin_inconsistencies;
@@ -266,85 +311,6 @@ report_row_inconsistency (const char *table,
/**
- * Report a minor inconsistency in the exchange's database (i.e. something
- * relating to timestamps that should have no financial implications).
- *
- * @param table affected table
- * @param rowid affected row, UINT64_MAX if row is missing
- * @param diagnostic message explaining the problem
- */
-static void
-report_row_minor_inconsistency (const char *table,
- uint64_t rowid,
- const char *diagnostic)
-{
- report (report_row_minor_inconsistencies,
- json_pack ("{s:s, s:I, s:s}",
- "table", table,
- "row", (json_int_t) rowid,
- "diagnostic", diagnostic));
-}
-
-
-/**
- * Report a global inconsistency with respect to a reserve.
- *
- * @param reserve_pub the affected reserve
- * @param expected expected amount
- * @param observed observed amount
- * @param diagnostic message explaining what @a expected and @a observed refer to
- */
-static void
-report_reserve_inconsistency (const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_Amount *expected,
- const struct TALER_Amount *observed,
- const char *diagnostic)
-{
- report (report_reserve_inconsistencies,
- json_pack ("{s:o, s:o, s:o, s:s}",
- "reserve_pub",
- GNUNET_JSON_from_data_auto (reserve_pub),
- "expected",
- TALER_JSON_from_amount (expected),
- "observed",
- TALER_JSON_from_amount (observed),
- "diagnostic",
- diagnostic));
-}
-
-
-/**
- * Report a global inconsistency with respect to a wire transfer.
- *
- * @param destination wire transfer target account
- * @param rowid which row is the inconsitency in
- * @param expected expected amount
- * @param observed observed amount
- * @param diagnostic message explaining what @a expected and @a observed refer to
- */
-static void
-report_wire_out_inconsistency (const json_t *destination,
- uint64_t rowid,
- const struct TALER_Amount *expected,
- const struct TALER_Amount *observed,
- const char *diagnostic)
-{
- report (report_wire_out_inconsistencies,
- json_pack ("{s:O, s:I, s:o, s:o, s:s}",
- "destination_account",
- destination,
- "rowid",
- (json_int_t) rowid,
- "expected",
- TALER_JSON_from_amount (expected),
- "observed",
- TALER_JSON_from_amount (observed),
- "diagnostic",
- diagnostic));
-}
-
-
-/**
* Report a global inconsistency with respect to a coin's history.
*
* @param coin_pub the affected coin
@@ -594,10 +560,6 @@ load_auditor_reserve_summary (struct ReserveSummary *rs)
TALER_amount_cmp_currency (&rs->total_in,
&rs->a_balance)) )
{
- report_row_inconsistency ("auditor-reserve-info",
- rowid,
- "currencies for reserve differ");
- /* TODO: find a sane way to continue... */
GNUNET_break (0);
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -781,9 +743,12 @@ handle_reserve_out (void *cls,
if ( (valid_start.abs_value_us > execution_date.abs_value_us) ||
(expire_withdraw.abs_value_us < execution_date.abs_value_us) )
{
- report_row_minor_inconsistency ("withdraw",
- rowid,
- "denomination key not valid at time of withdrawal");
+ report (denomination_key_validity_withdraw_inconsistencies,
+ json_pack ("{s:I, s:s, s:o, s:o}",
+ "row", (json_int_t) rowid,
+ "execution_date", GNUNET_STRINGS_absolute_time_to_string (execution_date),
+ "reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub),
+ "denompub_h", GNUNET_JSON_from_data_auto (&wsrd.h_denomination_pub)));
}
/* check reserve_sig */
@@ -1155,10 +1120,7 @@ verify_reserve_balance (void *cls,
&rs->total_in,
&rs->a_balance))
{
- report_reserve_inconsistency (&rs->reserve_pub,
- &rs->total_in,
- &rs->a_balance,
- "could not add old balance to new balance");
+ GNUNET_break (0);
goto cleanup;
}
@@ -1167,19 +1129,62 @@ verify_reserve_balance (void *cls,
&balance,
&rs->total_out))
{
- report_reserve_inconsistency (&rs->reserve_pub,
- &rs->total_in,
- &rs->total_out,
- "available balance insufficient to cover transfers");
+ struct TALER_Amount loss;
+
+ GNUNET_break (GNUNET_SYSERR !=
+ TALER_amount_subtract (&loss,
+ &rs->total_out,
+ &balance));
+ GNUNET_break (GNUNET_OK ==
+ TALER_amount_add (&total_balance_insufficient_loss,
+ &total_balance_insufficient_loss,
+ &loss));
+ report (report_reserve_balance_insufficient_inconsistencies,
+ json_pack ("{s:o, s:o, s:o, s:s}",
+ "reserve_pub",
+ GNUNET_JSON_from_data_auto (&rs->reserve_pub),
+ "loss",
+ TALER_JSON_from_amount (&loss)));
goto cleanup;
}
if (0 != TALER_amount_cmp (&balance,
&reserve.balance))
{
- report_reserve_inconsistency (&rs->reserve_pub,
- &balance,
- &reserve.balance,
- "computed balance does not match stored balance");
+ struct TALER_Amount delta;
+
+ if (0 < TALER_amount_cmp (&balance,
+ &reserve.balance))
+ {
+ /* balance > reserve.balance */
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_subtract (&delta,
+ &balance,
+ &reserve.balance));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_add (&total_balance_summary_delta_plus,
+ &total_balance_summary_delta_plus,
+ &delta));
+ }
+ else
+ {
+ /* balance < reserve.balance */
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_subtract (&delta,
+ &reserve.balance,
+ &balance));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_add (&total_balance_summary_delta_minus,
+ &total_balance_summary_delta_minus,
+ &delta));
+ }
+ report (report_reserve_balance_summary_wrong_inconsistencies,
+ json_pack ("{s:o, s:o, s:o}",
+ "reserve_pub",
+ GNUNET_JSON_from_data_auto (&rs->reserve_pub),
+ "exchange",
+ TALER_JSON_from_amount (&reserve.balance),
+ "auditor",
+ TALER_JSON_from_amount (&balance)));
goto cleanup;
}
@@ -1189,16 +1194,18 @@ verify_reserve_balance (void *cls,
( (0 != balance.value) ||
(0 != balance.fraction) ) )
{
- struct TALER_Amount zero;
-
GNUNET_assert (GNUNET_OK ==
- TALER_amount_get_zero (balance.currency,
- &zero));
-
- report_reserve_inconsistency (&rs->reserve_pub,
- &balance,
- &zero,
- "expired reserve needs to be closed");
+ TALER_amount_add (&total_balance_reserve_not_closed,
+ &total_balance_reserve_not_closed,
+ &balance));
+ report (report_reserve_not_closed_inconsistencies,
+ json_pack ("{s:o, s:o, s:s}",
+ "reserve_pub",
+ GNUNET_JSON_from_data_auto (&rs->reserve_pub),
+ "balance",
+ TALER_JSON_from_amount (&balance),
+ "expiration_time",
+ GNUNET_STRINGS_absolute_time_to_string (rs->a_expiration_date)));
}
/* Add withdraw fees we encountered to totals */
@@ -2206,10 +2213,8 @@ check_wire_out_cb (void *cls,
TALER_JSON_hash (wire,
&wcc.h_wire))
{
- report_row_inconsistency ("wire_out",
- rowid,
- "could not hash wire address");
- return GNUNET_OK;
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
qs = edb->lookup_wire_transfer (edb->cls,
esession,
@@ -2256,20 +2261,13 @@ check_wire_out_cb (void *cls,
wcc.method);
if (NULL == plugin)
{
- report_row_inconsistency ("wire_out",
- rowid,
- "could not load required wire plugin to validate");
- return GNUNET_OK;
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
- if (GNUNET_SYSERR ==
- plugin->amount_round (plugin->cls,
- &final_amount))
- {
- report_row_minor_inconsistency ("wire_out",
- rowid,
- "wire plugin failed to round given amount");
- }
+ GNUNET_break (GNUNET_SYSERR !=
+ plugin->amount_round (plugin->cls,
+ &final_amount));
/* Calculate the exchange's gain as the fees plus rounding differences! */
if (GNUNET_OK !=
@@ -2297,11 +2295,44 @@ check_wire_out_cb (void *cls,
if (0 != TALER_amount_cmp (amount,
&final_amount))
{
- report_wire_out_inconsistency (wire,
- rowid,
- &final_amount,
- amount,
- "computed amount inconsistent with wire amount");
+ struct TALER_Amount delta;
+
+ if (0 < TALER_amount_cmp (amount,
+ &final_amount))
+ {
+ /* amount > final_amount */
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_subtract (&delta,
+ amount,
+ &final_amount));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_add (&total_wire_out_delta_plus,
+ &total_wire_out_delta_plus,
+ &delta));
+ }
+ else
+ {
+ /* amount < final_amount */
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_subtract (&delta,
+ &final_amount,
+ amount));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_add (&total_wire_out_delta_minus,
+ &total_wire_out_delta_minus,
+ &delta));
+ }
+
+ report (report_wire_out_inconsistencies,
+ json_pack ("{s:O, s:I, s:o, s:o}",
+ "destination_account",
+ wire,
+ "rowid",
+ (json_int_t) rowid,
+ "expected",
+ TALER_JSON_from_amount (&final_amount),
+ "claimed",
+ TALER_JSON_from_amount (amount)));
return GNUNET_OK;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -3777,14 +3808,36 @@ run (void *cls,
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency,
&total_aggregation_fee_income));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (currency,
+ &total_balance_insufficient_loss));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (currency,
+ &total_balance_summary_delta_plus));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (currency,
+ &total_balance_summary_delta_minus));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (currency,
+ &total_wire_out_delta_plus));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (currency,
+ &total_wire_out_delta_minus));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (currency,
+ &total_balance_reserve_not_closed));
GNUNET_assert (NULL !=
(report_emergencies = json_array ()));
GNUNET_assert (NULL !=
(report_row_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
- (report_row_minor_inconsistencies = json_array ()));
+ (denomination_key_validity_withdraw_inconsistencies = json_array ()));
+ GNUNET_assert (NULL !=
+ (report_reserve_balance_summary_wrong_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
- (report_reserve_inconsistencies = json_array ()));
+ (report_reserve_balance_insufficient_inconsistencies = json_array ()));
+ GNUNET_assert (NULL !=
+ (report_reserve_not_closed_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
(report_wire_out_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
@@ -3810,26 +3863,62 @@ run (void *cls,
&income_fee_total,
&total_aggregation_fee_income));
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, 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 */
- "emergencies", report_emergencies,
- "emergencies_risk_total", TALER_JSON_from_amount (&reported_emergency_sum),
- "row_inconsistencies", report_row_inconsistencies,
- "row_minor_inconsistencies", report_row_minor_inconsistencies,
- "reserve_inconsistencies", report_reserve_inconsistencies,
/* block */
- "wire_out_inconsistencies", report_wire_out_inconsistencies,
- "coin_inconsistencies", report_coin_inconsistencies,
- "total_aggregation_fee_income", TALER_JSON_from_amount (&total_aggregation_fee_income),
- "total_escrow_balance", TALER_JSON_from_amount (&total_escrow_balance),
- "total_active_risk", TALER_JSON_from_amount (&total_risk),
+ "reserve_balance_insufficient_inconsistencies",
+ report_reserve_balance_insufficient_inconsistencies,
+ "total_loss_balance_insufficient",
+ TALER_JSON_from_amount (&total_balance_insufficient_loss),
+ "reserve_balance_summary_wrong_inconsistencies",
+ report_reserve_balance_summary_wrong_inconsistencies,
+ "total_balance_summary_delta_plus",
+ TALER_JSON_from_amount (&total_balance_summary_delta_plus),
+ "total_balance_summary_delta_minus",
+ TALER_JSON_from_amount (&total_balance_summary_delta_minus),
+ /* block */
+ "total_escrow_balance",
+ TALER_JSON_from_amount (&total_escrow_balance),
+ "total_active_risk",
+ TALER_JSON_from_amount (&total_risk),
+ "total_withdraw_fee_income",
+ TALER_JSON_from_amount (&total_withdraw_fee_income),
+ "total_deposit_fee_income",
+ TALER_JSON_from_amount (&total_deposit_fee_income),
+ "total_melt_fee_income",
+ /* block */
+ TALER_JSON_from_amount (&total_melt_fee_income),
+ "total_refund_fee_income",
+ TALER_JSON_from_amount (&total_refund_fee_income),
+ "income_fee_total",
+ TALER_JSON_from_amount (&income_fee_total),
+ "emergencies",
+ report_emergencies,
+ "emergencies_risk_total",
+ TALER_JSON_from_amount (&reported_emergency_sum),
+ /* block */
+ "reserve_not_closed_inconsistencies",
+ report_reserve_not_closed_inconsistencies,
+ "total_balance_reserve_not_closed",
+ TALER_JSON_from_amount (&total_balance_reserve_not_closed),
+ "wire_out_inconsistencies",
+ report_wire_out_inconsistencies,
+ "total_wire_out_delta_plus",
+ TALER_JSON_from_amount (&total_wire_out_delta_plus),
+ "total_wire_out_delta_minus",
+ TALER_JSON_from_amount (&total_wire_out_delta_minus),
/* block */
- "total_withdraw_fee_income", TALER_JSON_from_amount (&total_withdraw_fee_income),
- "total_deposit_fee_income", TALER_JSON_from_amount (&total_deposit_fee_income),
- "total_melt_fee_income", TALER_JSON_from_amount (&total_melt_fee_income),
- "total_refund_fee_income", TALER_JSON_from_amount (&total_refund_fee_income),
- "income_fee_total", TALER_JSON_from_amount (&income_fee_total)
+ "row_inconsistencies",
+ report_row_inconsistencies,
+ "denomination_key_validity_withdraw_inconsistencies",
+ denomination_key_validity_withdraw_inconsistencies,
+ "coin_inconsistencies",
+ report_coin_inconsistencies,
+ "total_aggregation_fee_income",
+ TALER_JSON_from_amount (&total_aggregation_fee_income)
);
json_dumpf (report,
stdout,