aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-01-19 14:22:34 +0100
committerChristian Grothoff <christian@grothoff.org>2020-01-19 14:22:34 +0100
commit342cccc384148e93142ed9dca59ad23e58388564 (patch)
tree061b97a7a2bac66438ed4cf32a8b2ebb36fda518
parent52bdff78675dfce080f33414613b3cb441167def (diff)
do not rely on filetime, as Git does not preserve it
-rw-r--r--contrib/auditor-report.tex.j230
-rw-r--r--src/auditor/auditor-basedb.age1
-rwxr-xr-xsrc/auditor/generate-auditor-basedb.sh4
-rw-r--r--src/auditor/taler-auditor.c7
-rwxr-xr-xsrc/auditor/test-auditor.sh48
5 files changed, 66 insertions, 24 deletions
diff --git a/contrib/auditor-report.tex.j2 b/contrib/auditor-report.tex.j2
index 8f142402d..a21ded1c4 100644
--- a/contrib/auditor-report.tex.j2
+++ b/contrib/auditor-report.tex.j2
@@ -236,7 +236,7 @@ The total amount the exchange currently lags behind in reserve closures is
Note that some minimal lag may be normal as transactions may be in-flight.
-% Table generation tested by testcase #22 in test-auditor.sh
+% Table generation tested by testcase #21 in test-auditor.sh
{% if wire.reserve_lag_details|length() == 0 %}
{\bf No closure transfers that are lagging behind detected.}
@@ -295,7 +295,7 @@ The total amount the exchange currently lags behind is
Note that some lag is perfectly normal.
Below, we report {\em all} deposit confirmations that are lagging behind.
-% Table generation tested by testcase #25 in test-auditor.sh
+% Table generation tested by testcase #24 in test-auditor.sh
{% if data.deposit_confirmation_inconsistencies|length() == 0 %}
{\bf No deposit confirmations that are lagging behind detected.}
@@ -400,7 +400,13 @@ The total loss from emergencies detected by counting coins could be up to
\subsubsection{Emergencies by value deposited}
-% Table generation tested by testcase #18 in test-auditor.sh
+Note that emergencies by value deposited can {\em also} arise if the exchange
+fails to properly detect double spending (or simply fails to properly account
+for the remaining balance of a coin). So in combintation with arithmetic
+problems (Section~\ref{sec:arithmetic}) issues in this section are not a clear
+indicator that the exchange's private signing key was compromised.
+
+% Table generation tested by testcases #18, #25 in test-auditor.sh
{% if data.emergencies|length() == 0 %}
{\bf No emergencies by value detected.}
@@ -434,7 +440,7 @@ The total loss from emergencies detected by counting coins could be up to
{% endif %}
-\subsection{Arithmetic problems}
+\subsection{Arithmetic problems} \label{sec:arithmetic}
This section lists cases where the arithmetic of the exchange
involving amounts disagrees with the arithmetic of the auditor.
@@ -527,7 +533,7 @@ 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}.
-% Table generation tested by testcase #24 in test-auditor.sh
+% Table generation tested by testcase #23 in test-auditor.sh
{% if data.wire_out_inconsistencies|length() == 0 %}
{\bf All aggregations matched up.}
@@ -569,7 +575,7 @@ 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.
-% Table generation tested by testcase #XX in test-auditor.sh
+% Table generation tested by testcase #25 in test-auditor.sh
{% if data.coin_inconsistencies|length() == 0 %}
{\bf All coin histories were unproblematic.}
@@ -896,11 +902,9 @@ have a clear financial impact.
\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.
+relate to outgoing wire transfers subjects being duplicated.
-% Table generation tested by testcase #19 in test-auditor.sh
+% Table generation tested by testcase #XX in test-auditor.sh
{% if wire.wire_format_inconsistencies|length() == 0 %}
{\bf No wire format inconsistencies found.}
@@ -972,7 +976,7 @@ with respect to what wire fee it charges at what time.
This section describes issues found that do not have a clear financial
impact.
-% Table generation tested by testcase #13/#15 in test-auditor.sh
+% Table generation tested by testcase #13/#15/#25 in test-auditor.sh
{% if data.row_inconsistencies|length() == 0 %}
{\bf No row inconsistencies found.}
@@ -1013,7 +1017,7 @@ This section describes cases where the exchange did not
close a reserve and wire back the remaining funds when the
reserve expired.
-% Table generation tested by testcase #21 in test-auditor.sh
+% Table generation tested by testcase #20 in test-auditor.sh
{% if data.reserve_not_closed_inconsistencies|length() == 0 %}
{\bf All expired reserves were closed.}
@@ -1085,7 +1089,7 @@ 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.
-% Table generation tested by testcase #23 in test-auditor.sh
+% Table generation tested by testcase #22 in test-auditor.sh
{% if data.denomination_key_validity_withdraw_inconsistencies|length() == 0 %}
{\bf All denomination keys were valid at the time of withdrawals.}
diff --git a/src/auditor/auditor-basedb.age b/src/auditor/auditor-basedb.age
new file mode 100644
index 000000000..d81cc0710
--- /dev/null
+++ b/src/auditor/auditor-basedb.age
@@ -0,0 +1 @@
+42
diff --git a/src/auditor/generate-auditor-basedb.sh b/src/auditor/generate-auditor-basedb.sh
index 3f896b31f..d23b67431 100755
--- a/src/auditor/generate-auditor-basedb.sh
+++ b/src/auditor/generate-auditor-basedb.sh
@@ -3,7 +3,8 @@
# testing from a 'correct' interaction between exchange,
# wallet and merchant.
#
-# Creates $BASEDB.sql, $BASEDB.fees and $BASEDB.mpub.
+# Creates $BASEDB.sql, $BASEDB.fees, $BASEDB.mpub and
+# $BASEDB.age.
# Default $BASEDB is "auditor-basedb", override via $1.
#
# Currently must be run online as it interacts with
@@ -144,6 +145,7 @@ echo $MASTER_PUB > ${BASEDB}.mpub
WIRE_FEE_DIR=`taler-config -c $CONF -f -s exchangedb -o WIREFEE_BASE_DIR`
cp $WIRE_FEE_DIR/x-taler-bank.fee ${BASEDB}.fees
+date +%s > ${BASEDB}.age
# clean up
echo "Final clean up"
diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index 5f484d752..6752b34ab 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -2422,7 +2422,7 @@ check_transaction_history_for_deposit (const struct
return GNUNET_SYSERR;
}
- /* Now check that 'spent' is less or equal than total coin value */
+ /* Now check that 'spent' is less or equal than the total coin value */
TALER_amount_ntoh (&value,
&issue->value);
if (1 == TALER_amount_cmp (&spent,
@@ -4658,14 +4658,13 @@ analyze_coins (void *cls)
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsp)
{
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- _ (
- "First analysis using this auditor, starting audit from scratch\n"));
+ "First analysis using this auditor, starting from scratch\n");
}
else
{
ppc_start = ppc;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _ ("Resuming coin audit at %llu/%llu/%llu/%llu/%llu\n"),
+ "Resuming coin audit at %llu/%llu/%llu/%llu/%llu\n",
(unsigned long long) ppc.last_deposit_serial_id,
(unsigned long long) ppc.last_melt_serial_id,
(unsigned long long) ppc.last_refund_serial_id,
diff --git a/src/auditor/test-auditor.sh b/src/auditor/test-auditor.sh
index 832bfb836..06f1b3707 100755
--- a/src/auditor/test-auditor.sh
+++ b/src/auditor/test-auditor.sh
@@ -9,7 +9,7 @@ set -eu
# Set of numbers for all the testcases.
# When adding new tests, increase the last number:
-ALL_TESTS=`seq 0 24`
+ALL_TESTS=`seq 0 25`
# $TESTS determines which tests we should run.
# This construction is used to make it easy to
@@ -118,7 +118,7 @@ function run_audit () {
# Do a full reload of the (original) database
full_reload()
{
- echo "Doing full reload of the database..."
+ echo -n "Doing full reload of the database... "
dropdb $DB 2> /dev/null || true
createdb -T template0 $DB || exit_skip "could not create database"
# Import pre-generated database, -q(ietly) using single (-1) transaction
@@ -1382,14 +1382,50 @@ full_reload
}
+# Test for inconsistent coin history.
+function test_25() {
+
+echo "=========25: inconsistent coin history========="
+# Drop refund, so coin history is bogus.
+echo "DELETE FROM refunds WHERE refund_serial_id=1;" | psql -Aqt $DB
+
+run_audit aggregator
+
+echo -n "Testing inconsistency detection... "
+
+jq -e .coin_inconsistencies[0] < test-audit.json > /dev/null || exit_fail "Coin inconsistency NOT detected"
+
+jq -e .row_inconsistencies[0] < test-audit.json > /dev/null || exit_fail "Coin history verification failure NOT reported"
+
+# Note: if the wallet withdrew much more than it spent, this might indeed
+# go legitimately unnoticed.
+jq -e .emergencies[0] < test-audit.json > /dev/null || exit_fail "Denomination value emergency NOT reported"
+
+AMOUNT=`jq -er .total_coin_delta_minus < test-audit.json`
+if test x$AMOUNT = xTESTKUDOS:0
+then
+ exit_fail "Expected non-zero total inconsistency amount from coins"
+fi
+# Note: if the wallet withdrew much more than it spent, this might indeed
+# go legitimately unnoticed.
+COUNT=`jq -er .emergencies_risk_by_amount < test-audit.json`
+if test x$AMOUNT = xTESTKUDOS:0
+then
+ exit_fail "Expected non-zero emergency-by-amount"
+fi
+echo PASS
+
+# cannot easily undo DELETE, hence full reload
+full_reload
+}
+
+
# **************************************************
# FIXME: Add more tests here! :-)
# Specifically:
# - revocation (payback, accepting
# of coins despite denomination revocation)
-# - refunds
-# - arithmetic problems
# **************************************************
@@ -1413,8 +1449,8 @@ check_with_database()
cp ${BASEDB}.fees $WIRE_FEE_DIR/x-taler-bank.fee
# Determine database age
- echo "Calculating database age based on ${BASEDB}.fees"
- AGE=`stat -c %Y ${BASEDB}.fees`
+ echo "Calculating database age based on ${BASEDB}.age"
+ AGE=`cat ${BASEDB}.age`
NOW=`date +%s`
# NOTE: expr "fails" if the result is zero.
DATABASE_AGE=`expr ${NOW} - ${AGE} || true`