aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/auditor/taler-auditor.c151
-rw-r--r--src/exchange/taler-exchange-httpd_db.c2
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c10
-rw-r--r--src/exchangedb/test_exchangedb.c2
-rw-r--r--src/include/taler_exchangedb_plugin.h2
5 files changed, 131 insertions, 36 deletions
diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index c57adb5a3..85eacfc65 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -25,16 +25,16 @@
* given in the 'wire_out' table. This needs to be checked separately!
*
* TODO:
- * - implement merchant deposit audit starting with 'wire_out'
- * - modify auditordb to allow multiple last serial IDs per table in progress tracking (needed?)
- * - modify auditordb to track risk with balances and fees (and rename callback
+ * - COMPLETE: implement misc. FIXMEs
+ * - COMPLETE: deal with risk / expired denomination keys in #sync_denomination
+ * - SANITY: modify auditordb to track risk with balances and fees (and rename callback
* to clarify what it is)
- * - modify auditordb to return DK when we inquire about deposit/refresh/refund,
+ * - SANITY: rename operations to better describe what they do!
+ * - OPTIMIZE/SIMPLIFY: modify auditordb to return DK when we inquire about deposit/refresh/refund,
* so we can avoid the costly #get_coin_summary with the transaction history building
* (at least during #analyze_coins); the logic may be partially useful in
* #analyze_merchants (but we won't need the cache!)
- * - deal with risk / expired denomination keys in #sync_denomination
- * - write reporting logic to output nice report beyond GNUNET_log()
+ * - BEAUTIFY: write reporting logic to output nice report beyond GNUNET_log()
* - write logic to deal with emergency (#3887) -- and emergency-related tables!
*/
#include "platform.h"
@@ -192,6 +192,49 @@ report_reserve_inconsistency (const struct TALER_ReservePublicKeyP *reserve_pub,
/**
+ * Report a global inconsistency with respect to a wire transfer.
+ *
+ * @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_wire_out_inconsistency (const json_t *destination,
+ uint64_t rowid,
+ const struct TALER_Amount *expected,
+ const struct TALER_Amount *observed,
+ const char *diagnostic)
+{
+ // TODO: implement proper reporting logic writing to file, include amounts.
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Wire out inconsistency detected: %s\n",
+ diagnostic);
+}
+
+
+/**
+ * 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)
+{
+ // TODO: implement proper reporting logic writing to file, include amounts.
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Coin inconsistency detected: %s\n",
+ diagnostic);
+}
+
+
+/**
* Report the final result on the reserve balances of the exchange.
* The reserve must have @a total_balance in its escrow account just
* to cover outstanding reserve funds (outstanding coins are on top).
@@ -1714,9 +1757,9 @@ deposit_cb (void *cls,
}
}
- /* TODO: *if* past pay_deadline, check that
- aggregation record exists for the deposit;
- if NOT, check that full _refund_ exists. */
+ /* TODO: *if* past pay_deadline, check that aggregation record
+ exists for the deposit, and if NOT, check that full _refund_
+ exists. */
return GNUNET_OK;
}
@@ -2114,11 +2157,6 @@ struct WireCheckContext
struct GNUNET_TIME_Absolute date;
/**
- * Set to error message of @e ok is #GNUNET_SYSERR.
- */
- const char *emsg;
-
- /**
* Wire method used for the transfer.
*/
const char *method;
@@ -2209,7 +2247,10 @@ check_transaction_history (const struct TALER_CoinSpendPublicKeyP *coin_pub,
{
/* overflow in history already!? inconceivable! Bad DB! */
GNUNET_break (0);
- // FIXME: report!
+ report_coin_inconsistency (coin_pub,
+ add_to,
+ amount_with_fee,
+ "could not add coin's contribution to total");
return GNUNET_SYSERR;
}
TALER_amount_ntoh (&tmp,
@@ -2220,7 +2261,10 @@ check_transaction_history (const struct TALER_CoinSpendPublicKeyP *coin_pub,
{
/* Disagreement in fee structure within DB! */
GNUNET_break (0);
- // FIXME: report!
+ report_coin_inconsistency (coin_pub,
+ &tmp,
+ fee,
+ "coin's fee in transaction and in denomination data differ");
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
@@ -2230,20 +2274,26 @@ check_transaction_history (const struct TALER_CoinSpendPublicKeyP *coin_pub,
{
/* overflow in fee total? inconceivable! Bad DB! */
GNUNET_break (0);
- // FIXME: report!
+ report_coin_inconsistency (coin_pub,
+ fee,
+ &fees,
+ "could not add coin's fee to total fees");
return GNUNET_SYSERR;
}
} /* for 'tl' */
/* Finally, calculate total balance change, i.e. expenditures minus refunds */
- if (GNUNET_OK !=
+ if (GNUNET_SYSERR ==
TALER_amount_subtract (final_expenditures,
&expenditures,
&refunds))
{
/* refunds above expenditures? inconceivable! Bad DB! */
GNUNET_break (0);
- // FIXME: report!
+ report_coin_inconsistency (coin_pub,
+ &expenditures,
+ &refunds,
+ "could not subtract refunded amount from expenditures");
return GNUNET_SYSERR;
}
return GNUNET_OK;
@@ -2255,6 +2305,7 @@ check_transaction_history (const struct TALER_CoinSpendPublicKeyP *coin_pub,
* transaction data associated with a wire transfer identifier.
*
* @param cls a `struct WireCheckContext`
+ * @param rowid which row in the table is the information from (for diagnostics)
* @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls)
* @param wire_method which wire plugin was used for the transfer?
* @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls)
@@ -2264,9 +2315,9 @@ check_transaction_history (const struct TALER_CoinSpendPublicKeyP *coin_pub,
* @param coin_value amount contributed by this coin in total (with fee)
* @param coin_fee applicable fee for this coin
*/
-// TODO: modify to have rowid to log errors in a more fine-grained way?
static void
wire_transfer_information_cb (void *cls,
+ uint64_t rowid,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *wire_method,
const struct GNUNET_HashCode *h_wire,
@@ -2291,7 +2342,9 @@ wire_transfer_information_cb (void *cls,
if (NULL == tl)
{
wcc->ok = GNUNET_SYSERR;
- wcc->emsg = "no transaction history for coin claimed in aggregation";
+ report_row_inconsistency ("aggregation",
+ rowid,
+ "no transaction history for coin claimed in aggregation");
return;
}
@@ -2315,11 +2368,14 @@ wire_transfer_information_cb (void *cls,
&dki,
NULL))
{
+ /* This should be impossible from database constraints */
GNUNET_break (0);
edb->free_coin_transaction_list (edb->cls,
tl);
wcc->ok = GNUNET_SYSERR;
- wcc->emsg = "could not find denomination key for coin claimed in aggregation";
+ report_row_inconsistency ("aggregation",
+ rowid,
+ "could not find denomination key for coin claimed in aggregation");
return;
}
@@ -2336,14 +2392,18 @@ wire_transfer_information_cb (void *cls,
coin_value))
{
wcc->ok = GNUNET_SYSERR;
- wcc->emsg = "coin transaction history and aggregation disagree about coin's contribution";
+ report_row_inconsistency ("aggregation",
+ rowid,
+ "coin transaction history and aggregation disagree about coin's contribution");
}
if (0 !=
TALER_amount_cmp (&computed_fees,
coin_fee))
{
wcc->ok = GNUNET_SYSERR;
- wcc->emsg = "coin transaction history and aggregation disagree about applicable fees";
+ report_row_inconsistency ("aggregation",
+ rowid,
+ "coin transaction history and aggregation disagree about applicable fees");
}
edb->free_coin_transaction_list (edb->cls,
tl);
@@ -2353,21 +2413,28 @@ wire_transfer_information_cb (void *cls,
wcc->method))
{
wcc->ok = GNUNET_SYSERR;
- wcc->emsg = "wire method of aggregate do not match wire transfer";
- return;
+ report_row_inconsistency ("aggregation",
+ rowid,
+ "wire method of aggregate do not match wire transfer");
}
if (0 != memcmp (h_wire,
&wcc->h_wire,
sizeof (struct GNUNET_HashCode)))
{
wcc->ok = GNUNET_SYSERR;
- wcc->emsg = "account details of aggregate do not match account details of wire transfer";
+ report_row_inconsistency ("aggregation",
+ rowid,
+ "account details of aggregate do not match account details of wire transfer");
return;
}
if (exec_time.abs_value_us != wcc->date.abs_value_us)
{
+ /* This should be impossible from database constraints */
+ GNUNET_break (0);
wcc->ok = GNUNET_SYSERR;
- wcc->emsg = "date given in aggregate does not match wire transfer date";
+ report_row_inconsistency ("aggregation",
+ rowid,
+ "date given in aggregate does not match wire transfer date");
return;
}
if (GNUNET_SYSERR ==
@@ -2376,7 +2443,9 @@ wire_transfer_information_cb (void *cls,
coin_fee))
{
wcc->ok = GNUNET_SYSERR;
- wcc->emsg = "could not calculate contribution of coin";
+ report_row_inconsistency ("aggregation",
+ rowid,
+ "could not calculate contribution of coin");
return;
}
@@ -2418,7 +2487,10 @@ check_wire_out_cb (void *cls,
if ( (NULL == method) ||
(! json_is_string (method)) )
{
- // TODO: bitch
+ report_row_inconsistency ("wire_out",
+ rowid,
+ "specified wire address lacks type");
+ return;
}
wcc.method = json_string_value (method);
wcc.ok = GNUNET_OK;
@@ -2434,24 +2506,35 @@ check_wire_out_cb (void *cls,
&wcc);
if (GNUNET_OK != wcc.ok)
{
- // TODO: bitch
+ report_row_inconsistency ("wire_out",
+ rowid,
+ "audit of associated transactions failed");
}
plugin = get_wire_plugin (mc,
wcc.method);
if (NULL == plugin)
{
- // TODO: bitch
+ report_row_inconsistency ("wire_out",
+ rowid,
+ "could not load required wire plugin to validate");
+ return;
}
if (GNUNET_OK !=
plugin->amount_round (plugin->cls,
&wcc.total_deposits))
{
- // TODO: bitch
+ report_row_minor_inconsistency ("wire_out",
+ rowid,
+ "wire plugin failed to round given amount");
}
if (0 != TALER_amount_cmp (amount,
&wcc.total_deposits))
{
- // TODO: bitch!
+ report_wire_out_inconsistency (wire,
+ rowid,
+ &wcc.total_deposits,
+ amount,
+ "computed amount inconsistent with wire amount");
}
}
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index cf142e0e7..78893d426 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -1912,6 +1912,7 @@ struct WtidTransactionContext
* transaction data for the given wire transfer identifier.
*
* @param cls our context for transmission
+ * @param rowid which row in the DB is the information from (for diagnostics)
* @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls)
* @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls)
* @param exec_time execution time of the wire transfer (should be same for all callbacks with the same @e cls)
@@ -1922,6 +1923,7 @@ struct WtidTransactionContext
*/
static void
handle_transaction_data (void *cls,
+ uint64_t rowid,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *wire_method,
const struct GNUNET_HashCode *h_wire,
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index f686a8c52..c975edcff 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -490,7 +490,8 @@ postgres_create_tables (void *cls)
/* Table for the tracking API, mapping from wire transfer identifiers
to transactions and back */
SQLEXEC("CREATE TABLE IF NOT EXISTS aggregation_tracking "
- "(deposit_serial_id INT8 PRIMARY KEY REFERENCES deposits (deposit_serial_id) ON DELETE CASCADE"
+ "(aggregation_serial_id BIGSERIAL"
+ ",deposit_serial_id INT8 PRIMARY KEY REFERENCES deposits (deposit_serial_id) ON DELETE CASCADE"
",wtid_raw BYTEA CONSTRAINT wire_out_ref REFERENCES wire_out(wtid_raw) ON DELETE CASCADE DEFERRABLE"
",execution_time INT8 NOT NULL"
")");
@@ -1235,7 +1236,8 @@ postgres_prepare (PGconn *db_conn)
/* Used in #postgres_lookup_wire_transfer */
PREPARE ("lookup_transactions",
"SELECT"
- " deposits.h_proposal_data"
+ " aggregation_serial_id"
+ ",deposits.h_proposal_data"
",deposits.wire"
",deposits.h_wire"
",deposits.coin_pub"
@@ -4067,6 +4069,7 @@ postgres_lookup_wire_transfer (void *cls,
}
for (i=0;i<nrows;i++)
{
+ uint64_t rowid;
struct GNUNET_HashCode h_proposal_data;
struct GNUNET_HashCode h_wire;
struct TALER_CoinSpendPublicKeyP coin_pub;
@@ -4078,6 +4081,7 @@ postgres_lookup_wire_transfer (void *cls,
json_t *t;
const char *wire_method;
struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("aggregation_serial_id", &rowid),
GNUNET_PQ_result_spec_auto_from_type ("h_proposal_data", &h_proposal_data),
TALER_PQ_result_spec_json ("wire", &wire),
GNUNET_PQ_result_spec_auto_from_type ("h_wire", &h_wire),
@@ -4088,6 +4092,7 @@ postgres_lookup_wire_transfer (void *cls,
TALER_PQ_result_spec_amount ("fee_deposit", &deposit_fee),
GNUNET_PQ_result_spec_end
};
+
if (GNUNET_OK !=
GNUNET_PQ_extract_result (result,
rs,
@@ -4112,6 +4117,7 @@ postgres_lookup_wire_transfer (void *cls,
return GNUNET_SYSERR;
}
cb (cb_cls,
+ rowid,
&merchant_pub,
wire_method,
&h_wire,
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index bfa1e6a23..93614ecb6 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -752,6 +752,7 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
*/
static void
cb_wt_never (void *cls,
+ uint64_t serial_id,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *wire_method,
const struct GNUNET_HashCode *h_wire,
@@ -795,6 +796,7 @@ static struct TALER_WireTransferIdentifierRawP wtid_wt;
*/
static void
cb_wt_check (void *cls,
+ uint64_t rowid,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *wire_method,
const struct GNUNET_HashCode *h_wire,
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 4ab3e4a54..3dae4896c 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -759,6 +759,7 @@ typedef void
* transaction data associated with a wire transfer identifier.
*
* @param cls closure
+ * @param rowid which row in the table is the information from (for diagnostics)
* @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls)
* @param wire_method which wire plugin was used for the transfer?
* @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls)
@@ -770,6 +771,7 @@ typedef void
*/
typedef void
(*TALER_EXCHANGEDB_WireTransferDataCallback)(void *cls,
+ uint64_t rowid,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *wire_method,
const struct GNUNET_HashCode *h_wire,