aboutsummaryrefslogtreecommitdiff
path: root/src/auditor/taler-helper-auditor-wire-credit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/auditor/taler-helper-auditor-wire-credit.c')
-rw-r--r--src/auditor/taler-helper-auditor-wire-credit.c1890
1 files changed, 26 insertions, 1864 deletions
diff --git a/src/auditor/taler-helper-auditor-wire-credit.c b/src/auditor/taler-helper-auditor-wire-credit.c
index c50d51fea..2731229b7 100644
--- a/src/auditor/taler-helper-auditor-wire-credit.c
+++ b/src/auditor/taler-helper-auditor-wire-credit.c
@@ -18,12 +18,8 @@
* @brief audits that wire transfers match those from an exchange database.
* @author Christian Grothoff
*
- * - First, this auditor verifies that 'reserves_in' actually matches
- * the incoming wire transfers from the bank.
- * - Second, we check that the outgoing wire transfers match those
- * given in the 'wire_out' and 'reserve_closures' tables
- * - Finally, we check that all wire transfers that should have been made,
- * were actually made
+ * This auditor verifies that 'reserves_in' actually matches
+ * the incoming wire transfers from the bank.
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
@@ -61,12 +57,6 @@
*/
static int test_mode;
-struct TALER_AUDITORDB_WireAccountProgressPoint
-{
- uint64_t last_reserve_in_serial_id;
- uint64_t last_wire_out_serial_id;
-};
-
/**
* Information we keep for each supported account.
*/
@@ -93,19 +83,14 @@ struct WireAccount
struct TALER_BANK_CreditHistoryHandle *chh;
/**
- * Active wire request for the transaction history.
- */
- struct TALER_BANK_DebitHistoryHandle *dhh;
-
- /**
* Progress point for this account.
*/
- struct TALER_AUDITORDB_WireAccountProgressPoint pp;
+ uint64_t last_reserve_in_serial_id;
/**
* Initial progress point for this account.
*/
- struct TALER_AUDITORDB_WireAccountProgressPoint start_pp;
+ uint64_t start_reserve_in_serial_id;
/**
* Where we are in the inbound transaction history.
@@ -113,31 +98,16 @@ struct WireAccount
uint64_t wire_off_in;
/**
- * Where we are in the outbound transaction history.
- */
- uint64_t wire_off_out;
-
- /**
* Label under which we store our pp's reserve_in_serial_id.
*/
char *label_reserve_in_serial_id;
/**
- * Label under which we store our pp's reserve_in_serial_id.
- */
- char *label_wire_out_serial_id;
-
- /**
* Label under which we store our wire_off_in.
*/
char *label_wire_off_in;
/**
- * Label under which we store our wire_off_out.
- */
- char *label_wire_off_out;
-
- /**
* Return value when we got this account's progress point.
*/
enum GNUNET_DB_QueryStatus qsx;
@@ -145,38 +115,6 @@ struct WireAccount
/**
- * Information we track for a reserve being closed.
- */
-struct ReserveClosure
-{
- /**
- * Row in the reserves_closed table for this action.
- */
- uint64_t rowid;
-
- /**
- * When was the reserve closed?
- */
- struct GNUNET_TIME_Timestamp execution_date;
-
- /**
- * Amount transferred (amount remaining minus fee).
- */
- struct TALER_Amount amount;
-
- /**
- * Target account where the money was sent.
- */
- char *receiver_account;
-
- /**
- * Wire transfer subject used.
- */
- struct TALER_WireTransferIdentifierRawP wtid;
-};
-
-
-/**
* Map from H(wtid,receiver_account) to `struct ReserveClosure` entries.
*/
static struct GNUNET_CONTAINER_MultiHashMap *reserve_closures;
@@ -193,13 +131,6 @@ static int global_ret;
static struct GNUNET_CONTAINER_MultiHashMap *in_map;
/**
- * Map with information about outgoing wire transfers.
- * Maps hashes of the wire subjects (in binary encoding)
- * to `struct ReserveOutInfo`s.
- */
-static struct GNUNET_CONTAINER_MultiHashMap *out_map;
-
-/**
* Head of list of wire accounts we still need to look at.
*/
static struct WireAccount *wa_head;
@@ -216,11 +147,9 @@ static struct WireAccount *wa_tail;
static enum GNUNET_DB_QueryStatus qsx_gwap;
/**
- * Last reserve_in / wire_out serial IDs seen.
+ * Last reserve_in seen.
*/
-static TALER_ARL_DEF_PP (wire_reserve_close_id);
-static TALER_ARL_DEF_PP (wire_batch_deposit_id);
-static TALER_ARL_DEF_PP (wire_aggregation_id);
+static TALER_ARL_DEF_PP (wire_reserve_in_id); // FIXME: new!
/**
* Amount that is considered "tiny"
@@ -228,16 +157,6 @@ static TALER_ARL_DEF_PP (wire_aggregation_id);
static struct TALER_Amount tiny_amount;
/**
- * Total amount that was transferred too much from the exchange.
- */
-static struct TALER_Amount total_bad_amount_out_plus;
-
-/**
- * Total amount that was transferred too little from the exchange.
- */
-static struct TALER_Amount total_bad_amount_out_minus;
-
-/**
* Total amount that was transferred too much to the exchange.
*/
static struct TALER_Amount total_bad_amount_in_plus;
@@ -255,52 +174,22 @@ static struct TALER_Amount total_bad_amount_in_minus;
static struct TALER_Amount total_misattribution_in;
/**
- * Total amount which the exchange did not transfer in time.
- */
-static struct TALER_Amount total_amount_lag;
-
-/**
- * Total amount of reserve closures which the exchange did not transfer in time.
- */
-static struct TALER_Amount total_closure_amount_lag;
-
-/**
- * Total amount affected by wire format trouble.s
+ * Total amount affected by wire format troubles.
*/
-static struct TALER_Amount total_wire_format_amount;
+static struct TALER_Amount total_wire_format_amount; // FIXME
/**
* Total amount credited to exchange accounts.
*/
-static struct TALER_Amount total_wire_in;
-
-/**
- * Total amount debited to exchange accounts.
- */
-static struct TALER_Amount total_wire_out;
-
-/**
- * Total amount of profits drained.
- */
-static TALER_ARL_DEF_AB (total_drained);
-
-/**
- * Final balance at the end of this iteration.
- */
-static TALER_ARL_DEF_AB (final_balance);
-
-/**
- * Starting balance at the beginning of this iteration.
- */
-static struct TALER_Amount start_balance;
+static TALER_ARL_DEF_AB (total_wire_in);
/**
- * True if #start_balance was initialized.
+ * True if #total_wire_in was initialized.
*/
static bool had_start_balance;
/**
- * True if #start_balance was initialized.
+ * True if #wire_reserve_in_id was initialized.
*/
static bool had_start_progress;
@@ -330,6 +219,7 @@ static int internal_checks;
*/
static int ignore_account_404;
+// FIXME: comment
static struct GNUNET_DB_EventHandler *eh;
/**
@@ -372,26 +262,6 @@ struct ReserveInInfo
/**
- * Entry in map with wire information we expect to obtain from the
- * #TALER_ARL_edb later.
- */
-struct ReserveOutInfo
-{
-
- /**
- * Hash of the wire transfer subject.
- */
- struct GNUNET_HashCode subject_hash;
-
- /**
- * Expected details about the wire transfer.
- */
- struct TALER_BANK_DebitDetails details;
-
-};
-
-
-/**
* Free entry in #in_map.
*
* @param cls NULL
@@ -417,57 +287,6 @@ free_rii (void *cls,
/**
- * Free entry in #out_map.
- *
- * @param cls NULL
- * @param key unused key
- * @param value the `struct ReserveOutInfo` to free
- * @return #GNUNET_OK
- */
-static enum GNUNET_GenericReturnValue
-free_roi (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- struct ReserveOutInfo *roi = value;
-
- (void) cls;
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (out_map,
- key,
- roi));
- GNUNET_free (roi);
- return GNUNET_OK;
-}
-
-
-/**
- * Free entry in #reserve_closures.
- *
- * @param cls NULL
- * @param key unused key
- * @param value the `struct ReserveClosure` to free
- * @return #GNUNET_OK
- */
-static enum GNUNET_GenericReturnValue
-free_rc (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- struct ReserveClosure *rc = value;
-
- (void) cls;
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (reserve_closures,
- key,
- rc));
- GNUNET_free (rc->receiver_account);
- GNUNET_free (rc);
- return GNUNET_OK;
-}
-
-
-/**
* Task run on shutdown.
*
* @param cls NULL
@@ -489,14 +308,6 @@ do_shutdown (void *cls)
db_plugin = NULL;
}
TALER_ARL_done (NULL);
- if (NULL != reserve_closures)
- {
- GNUNET_CONTAINER_multihashmap_iterate (reserve_closures,
- &free_rc,
- NULL);
- GNUNET_CONTAINER_multihashmap_destroy (reserve_closures);
- reserve_closures = NULL;
- }
if (NULL != in_map)
{
GNUNET_CONTAINER_multihashmap_iterate (in_map,
@@ -505,21 +316,8 @@ do_shutdown (void *cls)
GNUNET_CONTAINER_multihashmap_destroy (in_map);
in_map = NULL;
}
- if (NULL != out_map)
- {
- GNUNET_CONTAINER_multihashmap_iterate (out_map,
- &free_roi,
- NULL);
- GNUNET_CONTAINER_multihashmap_destroy (out_map);
- out_map = NULL;
- }
while (NULL != (wa = wa_head))
{
- if (NULL != wa->dhh)
- {
- TALER_BANK_debit_history_cancel (wa->dhh);
- wa->dhh = NULL;
- }
if (NULL != wa->chh)
{
TALER_BANK_credit_history_cancel (wa->chh);
@@ -529,9 +327,7 @@ do_shutdown (void *cls)
wa_tail,
wa);
GNUNET_free (wa->label_reserve_in_serial_id);
- GNUNET_free (wa->label_wire_out_serial_id);
GNUNET_free (wa->label_wire_off_in);
- GNUNET_free (wa->label_wire_off_out);
GNUNET_free (wa);
}
if (NULL != ctx)
@@ -550,133 +346,27 @@ do_shutdown (void *cls)
/**
- * Detect any entries in #reserve_closures that were not yet
- * observed on the wire transfer side and update the progress
- * point accordingly.
- *
- * @param cls NULL
- * @param key unused key
- * @param value the `struct ReserveClosure` to free
- * @return #GNUNET_OK
- */
-static enum GNUNET_GenericReturnValue
-check_pending_rc (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- struct ReserveClosure *rc = value;
- /*enum GNUNET_DB_QueryStatus qs;
- struct TALER_AUDITORDB_ClosureLags cl;*/
-
- (void) cls;
- (void) key;
- TALER_ARL_amount_add (&total_closure_amount_lag,
- &total_closure_amount_lag,
- &rc->amount);
- if (! TALER_amount_is_zero (&rc->amount))
- {
-#if FIXME
-
- cl.account = rc->receiver_account;
- cl.amount = &rc->amount;
- cl.deadline = rc->execution_date.abs_time;
- cl.wtid = &rc->wtid;
-
- qs = TALER_ARL_adb->insert_auditor_closure_lags (
- TALER_ARL_adb->cls,
- &cl);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }
-
- TALER_ARL_report (
- report_closure_lags,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("row",
- rc->rowid),
- TALER_JSON_pack_amount ("amount",
- &rc->amount),
- TALER_JSON_pack_time_abs_human ("deadline",
- rc->execution_date.abs_time),
- GNUNET_JSON_pack_data_auto ("wtid",
- &rc->wtid),
- GNUNET_JSON_pack_string ("account",
- rc->receiver_account)));
-#endif
- }
- TALER_ARL_USE_PP (wire_reserve_close_id)
- = GNUNET_MIN (TALER_ARL_USE_PP (wire_reserve_close_id),
- rc->rowid);
- return GNUNET_OK;
-}
-
-
-/**
- * Compute the key under which a reserve closure for a given
- * @a receiver_account and @a wtid would be stored.
- *
- * @param receiver_account payto://-URI of the account
- * @param wtid wire transfer identifier used
- * @param[out] key set to the key
- */
-static void
-hash_rc (const char *receiver_account,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- struct GNUNET_HashCode *key)
-{
- size_t slen = strlen (receiver_account);
- char buf[sizeof (struct TALER_WireTransferIdentifierRawP) + slen];
-
- GNUNET_memcpy (buf,
- wtid,
- sizeof (*wtid));
- GNUNET_memcpy (&buf[sizeof (*wtid)],
- receiver_account,
- slen);
- GNUNET_CRYPTO_hash (buf,
- sizeof (buf),
- key);
-}
-
-
-/**
* Commit the transaction, checkpointing our progress in the auditor DB.
*
* @param qs transaction status so far
- * @return transaction status code
*/
-static enum GNUNET_DB_QueryStatus
+static void
commit (enum GNUNET_DB_QueryStatus qs)
{
if (qs >= 0)
{
if (had_start_balance)
{
- struct TALER_Amount sum;
-
- TALER_ARL_amount_add (&sum,
- &total_wire_in,
- &start_balance);
- TALER_ARL_amount_subtract (&TALER_ARL_USE_AB (final_balance),
- &sum,
- &total_wire_out);
qs = TALER_ARL_adb->update_balance (
TALER_ARL_adb->cls,
- TALER_ARL_SET_AB (total_drained),
- TALER_ARL_SET_AB (final_balance),
+ TALER_ARL_SET_AB (total_wire_in),
NULL);
}
else
{
- TALER_ARL_amount_subtract (&TALER_ARL_USE_AB (final_balance),
- &total_wire_in,
- &total_wire_out);
qs = TALER_ARL_adb->insert_balance (
TALER_ARL_adb->cls,
- TALER_ARL_SET_AB (total_drained),
- TALER_ARL_SET_AB (final_balance),
+ TALER_ARL_SET_AB (total_wire_in),
NULL);
}
}
@@ -690,7 +380,7 @@ commit (enum GNUNET_DB_QueryStatus qs)
"Hard error, not recording progress\n");
TALER_ARL_adb->rollback (TALER_ARL_adb->cls);
TALER_ARL_edb->rollback (TALER_ARL_edb->cls);
- return qs;
+ return;
}
for (struct WireAccount *wa = wa_head;
NULL != wa;
@@ -702,63 +392,25 @@ commit (enum GNUNET_DB_QueryStatus qs)
TALER_ARL_adb->cls,
wa->label_reserve_in_serial_id,
wa->pp.last_reserve_in_serial_id,
- wa->label_wire_out_serial_id,
- wa->pp.last_wire_out_serial_id,
wa->label_wire_off_in,
wa->wire_off_in,
- wa->label_wire_off_out,
- wa->wire_off_out,
NULL);
else
qs = TALER_ARL_adb->insert_auditor_progress (
TALER_ARL_adb->cls,
wa->label_reserve_in_serial_id,
wa->pp.last_reserve_in_serial_id,
- wa->label_wire_out_serial_id,
- wa->pp.last_wire_out_serial_id,
wa->label_wire_off_in,
wa->wire_off_in,
- wa->label_wire_off_out,
- wa->wire_off_out,
NULL);
if (0 >= qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Failed to update auditor DB, not recording progress\n");
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
+ return;
}
}
- GNUNET_CONTAINER_multihashmap_iterate (reserve_closures,
- &check_pending_rc,
- NULL);
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsx_gwap && had_start_progress ==
- true)
- qs = TALER_ARL_adb->update_auditor_progress (
- TALER_ARL_adb->cls,
- TALER_ARL_SET_PP (wire_reserve_close_id),
- TALER_ARL_SET_PP (wire_batch_deposit_id),
- TALER_ARL_SET_PP (wire_aggregation_id),
- NULL);
- else
- qs = TALER_ARL_adb->insert_auditor_progress (
- TALER_ARL_adb->cls,
- TALER_ARL_SET_PP (wire_reserve_close_id),
- TALER_ARL_SET_PP (wire_batch_deposit_id),
- TALER_ARL_SET_PP (wire_aggregation_id),
- NULL);
- if (0 >= qs)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Failed to update auditor DB, not recording progress\n");
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Concluded audit step at %llu/%llu\n",
- (unsigned long long) TALER_ARL_USE_PP (wire_aggregation_id),
- (unsigned long long) TALER_ARL_USE_PP (wire_batch_deposit_id));
-
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
{
qs = TALER_ARL_edb->commit (TALER_ARL_edb->cls);
@@ -787,1313 +439,10 @@ commit (enum GNUNET_DB_QueryStatus qs)
TALER_ARL_adb->rollback (TALER_ARL_adb->cls);
TALER_ARL_edb->rollback (TALER_ARL_edb->cls);
}
- return qs;
-}
-
-
-/* ***************************** Analyze required transfers ************************ */
-
-/**
- * Closure for import_wire_missing_cb().
- */
-struct ImportMissingWireContext
-{
- /**
- * Set to maximum row ID encountered.
- */
- uint64_t max_batch_deposit_uuid;
-
- /**
- * Set to database errors in callback.
- */
- enum GNUNET_DB_QueryStatus err;
-};
-
-
-/**
- * Function called on deposits that need to be checked for their
- * wire transfer.
- *
- * @param cls closure, points to a `struct ImportMissingWireContext`
- * @param batch_deposit_serial_id serial of the entry in the batch deposits table
- * @param total_amount value of the missing deposits, including fee
- * @param wire_target_h_payto where should the funds be wired
- * @param deadline what was the earliest requested wire transfer deadline
- */
-static void
-import_wire_missing_cb (void *cls,
- uint64_t batch_deposit_serial_id,
- const struct TALER_Amount *total_amount,
- const struct TALER_PaytoHashP *wire_target_h_payto,
- struct GNUNET_TIME_Timestamp deadline)
-{
- struct ImportMissingWireContext *wc = cls;
- enum GNUNET_DB_QueryStatus qs;
-
- if (wc->err < 0)
- return; /* already failed */
- GNUNET_assert (batch_deposit_serial_id > wc->max_batch_deposit_uuid);
- wc->max_batch_deposit_uuid = batch_deposit_serial_id;
- qs = TALER_ARL_adb->insert_pending_deposit (
- TALER_ARL_adb->cls,
- batch_deposit_serial_id,
- wire_target_h_payto,
- total_amount,
- deadline);
- if (qs < 0)
- wc->err = qs;
-}
-
-
-/**
- * Information about a delayed wire transfer and the possible
- * reasons for the delay.
- */
-struct ReasonDetail
-{
- /**
- * Total amount that should have been transferred.
- */
- struct TALER_Amount total_amount;
-
- /**
- * Earliest deadline for an expected transfer to the account.
- */
- struct GNUNET_TIME_Timestamp deadline;
-
- /**
- * Target account, NULL if even that is not known (due to
- * exchange lacking required entry in wire_targets table).
- */
- char *payto_uri;
-
- /**
- * Account properties, possibly NULL.
- */
- json_t *properties;
-
- /**
- * Account KYC rules.
- */
- json_t *jrules;
-
-};
-
-/**
- * Closure for report_wire_missing_cb().
- */
-struct ReportMissingWireContext
-{
- /**
- * Map from wire_target_h_payto to `struct ReasonDetail`.
- */
- struct GNUNET_CONTAINER_MultiShortmap *map;
-
- /**
- * Set to database errors in callback.
- */
- enum GNUNET_DB_QueryStatus err;
-};
-
-
-/**
- * Closure for #clear_finished_transfer_cb().
- */
-struct AggregationContext
-{
- /**
- * Set to maximum row ID encountered.
- */
- uint64_t max_aggregation_serial;
-
- /**
- * Set to database errors in callback.
- */
- enum GNUNET_DB_QueryStatus err;
-};
-
-
-/**
- * Free memory allocated in @a value.
- *
- * @param cls unused
- * @param key unused
- * @param value must be a `struct ReasonDetail`
- * @return #GNUNET_YES if we should continue to
- * iterate,
- * #GNUNET_NO if not.
- */
-static enum GNUNET_GenericReturnValue
-free_report_entry (void *cls,
- const struct GNUNET_ShortHashCode *key,
- void *value)
-{
- struct ReasonDetail *rd = value;
-
- json_decref (rd->properties);
- json_decref (rd->jrules);
- GNUNET_free (rd->payto_uri);
- GNUNET_free (rd);
- return GNUNET_YES;
-}
-
-
-/**
- * We had an entry in our map of wire transfers that
- * should have been performed. Generate report.
- *
- * @param cls unused
- * @param key unused
- * @param value must be a `struct ReasonDetail`
- * @return #GNUNET_YES if we should continue to
- * iterate,
- * #GNUNET_NO if not.
- */
-static enum GNUNET_GenericReturnValue
-generate_report (void *cls,
- const struct GNUNET_ShortHashCode *key,
- void *value)
-{
- struct ReasonDetail *rd = value;
- // enum GNUNET_DB_QueryStatus qs;
- // struct TALER_AUDITORDB_KycLag kycl;
- // struct TALER_AUDITORDB_AmlLag amllag;
- // struct TALER_AUDITORDB_Lag lag;
-
- /* For now, we simplify and only check that the
- amount was tiny */
- if (0 > TALER_amount_cmp (&rd->total_amount,
- &tiny_amount))
- return free_report_entry (cls,
- key,
- value); /* acceptable, amount was tiny */
-
-#if FIXME
- // TODO: maybe split total_amount_lag up by category below?
- TALER_ARL_amount_add (&total_amount_lag,
- &total_amount_lag,
- &rd->total_amount);
- if (NULL != rd->kyc_pending)
- {
- json_t *rep;
-
- rep = GNUNET_JSON_PACK (
- TALER_JSON_pack_amount ("total_amount",
- &rd->total_amount),
- TALER_JSON_pack_time_abs_human ("deadline",
- rd->deadline.abs_time),
- GNUNET_JSON_pack_object_incref ("kyc_rules",
- rd->rules),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_object_incref ("properties",
- rd->properties)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("account",
- rd->payto_uri)));
- // TODO add kyc lag db entry
- /*rbiil.reserve_pub = rs->reserve_pub.eddsa_pub;
- rbiil.inconsistency_amount = loss;
- rbiil.inconsistency_gain = false;
-
- qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }*/
-
- TALER_ARL_report (report_kyc_lags,
- rep);
- }
- else if (TALER_AML_NORMAL != rd->status)
- {
- const char *sstatus = "<undefined>";
- json_t *rep;
-
- switch (rd->status)
- {
- case TALER_AML_NORMAL:
- GNUNET_assert (0);
- break;
- case TALER_AML_PENDING:
- sstatus = "pending";
- break;
- case TALER_AML_FROZEN:
- sstatus = "frozen";
- break;
- }
- rep = GNUNET_JSON_PACK (
- TALER_JSON_pack_amount ("total_amount",
- &rd->total_amount),
- GNUNET_JSON_pack_allow_null (
- TALER_JSON_pack_amount ("aml_limit",
- TALER_amount_is_valid (&rd->aml_limit)
- ? &rd->aml_limit
- : NULL)),
- TALER_JSON_pack_time_abs_human ("deadline",
- rd->deadline.abs_time),
- GNUNET_JSON_pack_string ("aml_status",
- sstatus),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("account",
- rd->payto_uri)));
- // TODO add aml lag db entry
- /*rbiil.reserve_pub = rs->reserve_pub.eddsa_pub;
- rbiil.inconsistency_amount = loss;
- rbiil.inconsistency_gain = false;
-
- qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }*/
- TALER_ARL_report (report_aml_lags,
- rep);
- }
- else
- {
- json_t *rep;
-
- rep = GNUNET_JSON_PACK (
- TALER_JSON_pack_amount ("total_amount",
- &rd->total_amount),
- TALER_JSON_pack_time_abs_human ("deadline",
- rd->deadline.abs_time),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("account",
- rd->payto_uri)));
- // TODO add lag
- /*rbiil.reserve_pub = rs->reserve_pub.eddsa_pub;
- rbiil.inconsistency_amount = loss;
- rbiil.inconsistency_gain = false;
-
- qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }*/
- TALER_ARL_report (report_lags,
- rep);
- }
-#endif
-
- return free_report_entry (cls,
- key,
- value);
-}
-
-
-/**
- * Function called on deposits that are past their due date
- * and have not yet seen a wire transfer.
- *
- * @param cls closure, points to a `struct ReportMissingWireContext`
- * @param batch_deposit_serial_id row in the database for which the wire transfer is missing
- * @param total_amount value of the missing deposits, including fee
- * @param wire_target_h_payto hash of payto-URI where the funds should have been wired
- * @param deadline what was the earliest requested wire transfer deadline
- */
-static void
-report_wire_missing_cb (void *cls,
- uint64_t batch_deposit_serial_id,
- const struct TALER_Amount *total_amount,
- const struct TALER_PaytoHashP *wire_target_h_payto,
- struct GNUNET_TIME_Timestamp deadline)
-{
- struct ReportMissingWireContext *rc = cls;
- struct ReasonDetail *rd;
-
- rd = GNUNET_CONTAINER_multishortmap_get (rc->map,
- &wire_target_h_payto->hash);
- if (NULL == rd)
- {
- rd = GNUNET_new (struct ReasonDetail);
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multishortmap_put (
- rc->map,
- &wire_target_h_payto->hash,
- rd,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- rc->err = TALER_ARL_edb->select_justification_for_missing_wire (
- TALER_ARL_edb->cls,
- wire_target_h_payto,
- &rd->payto_uri,
- &rd->properties,
- &rd->jrules);
- rd->total_amount = *total_amount;
- rd->deadline = deadline;
- }
- else
- {
- TALER_ARL_amount_add (&rd->total_amount,
- &rd->total_amount,
- total_amount);
- rd->deadline = GNUNET_TIME_timestamp_min (rd->deadline,
- deadline);
- }
-}
-
-
-/**
- * Function called on aggregations that were done for
- * a (batch) deposit.
- *
- * @param cls closure
- * @param tracking_serial_id where in the table are we
- * @param batch_deposit_serial_id which batch deposit was aggregated
- */
-static void
-clear_finished_transfer_cb (
- void *cls,
- uint64_t tracking_serial_id,
- uint64_t batch_deposit_serial_id)
-{
- struct AggregationContext *ac = cls;
- enum GNUNET_DB_QueryStatus qs;
-
- if (0 > ac->err)
- return; /* already failed */
- GNUNET_assert (ac->max_aggregation_serial < tracking_serial_id);
- ac->max_aggregation_serial = tracking_serial_id;
- qs = TALER_ARL_adb->delete_pending_deposit (
- TALER_ARL_adb->cls,
- batch_deposit_serial_id);
- if (0 == qs)
- {
- /* Aggregated something twice or other error, report! */
- GNUNET_break (0);
- // FIXME: report more nicely!
- }
- if (0 > qs)
- ac->err = qs;
-}
-
-
-/**
- * Checks that all wire transfers that should have happened
- * (based on deposits) have indeed happened.
- */
-static void
-check_for_required_transfers (void)
-{
- struct ImportMissingWireContext wc = {
- .max_batch_deposit_uuid = TALER_ARL_USE_PP (wire_batch_deposit_id),
- .err = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
- };
- struct GNUNET_TIME_Absolute deadline;
- enum GNUNET_DB_QueryStatus qs;
- struct ReportMissingWireContext rc = {
- .err = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
- };
- struct AggregationContext ac = {
- .max_aggregation_serial = TALER_ARL_USE_PP (wire_aggregation_id),
- .err = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
- };
-
- qs = TALER_ARL_edb->select_batch_deposits_missing_wire (
- TALER_ARL_edb->cls,
- TALER_ARL_USE_PP (wire_batch_deposit_id),
- &import_wire_missing_cb,
- &wc);
- if ((0 > qs) || (0 > wc.err))
- {
- GNUNET_break (0);
- GNUNET_break ((GNUNET_DB_STATUS_SOFT_ERROR == qs) ||
- (GNUNET_DB_STATUS_SOFT_ERROR == wc.err));
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- TALER_ARL_USE_PP (wire_batch_deposit_id) = wc.max_batch_deposit_uuid;
- qs = TALER_ARL_edb->select_aggregations_above_serial (
- TALER_ARL_edb->cls,
- TALER_ARL_USE_PP (wire_aggregation_id),
- &clear_finished_transfer_cb,
- &ac);
- if ((0 > qs) || (0 > ac.err))
- {
- GNUNET_break (0);
- GNUNET_break ((GNUNET_DB_STATUS_SOFT_ERROR == qs) ||
- (GNUNET_DB_STATUS_SOFT_ERROR == ac.err));
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- TALER_ARL_USE_PP (wire_aggregation_id) = ac.max_aggregation_serial;
- /* Subtract #GRACE_PERIOD, so we can be a bit behind in processing
- without immediately raising undue concern */
- deadline = GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (),
- GRACE_PERIOD);
- rc.map = GNUNET_CONTAINER_multishortmap_create (1024,
- GNUNET_NO);
- qs = TALER_ARL_adb->select_pending_deposits (
- TALER_ARL_adb->cls,
- deadline,
- &report_wire_missing_cb,
- &rc);
- if ((0 > qs) || (0 > rc.err))
- {
- GNUNET_break (0);
- GNUNET_break ((GNUNET_DB_STATUS_SOFT_ERROR == qs) ||
- (GNUNET_DB_STATUS_SOFT_ERROR == rc.err));
- GNUNET_CONTAINER_multishortmap_iterate (rc.map,
- &free_report_entry,
- NULL);
- GNUNET_CONTAINER_multishortmap_destroy (rc.map);
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GNUNET_CONTAINER_multishortmap_iterate (rc.map,
- &generate_report,
- NULL);
- GNUNET_CONTAINER_multishortmap_destroy (rc.map);
- /* conclude with success */
- commit (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT);
- GNUNET_SCHEDULER_shutdown ();
-}
-
-
-/* ***************************** Analyze reserves_out ************************ */
-
-/**
- * Clean up after processing wire out data.
- */
-static void
-conclude_wire_out (void)
-{
- GNUNET_CONTAINER_multihashmap_destroy (out_map);
- out_map = NULL;
- check_for_required_transfers ();
}
/**
- * Check that @a want is within #TIME_TOLERANCE of @a have.
- * Otherwise report an inconsistency in row @a rowid of @a table.
- *
- * @param table where is the inconsistency (if any)
- * @param rowid what is the row
- * @param want what is the expected time
- * @param have what is the time we got
- */
-static void
-check_time_difference (const char *table,
- uint64_t rowid,
- struct GNUNET_TIME_Timestamp want,
- struct GNUNET_TIME_Timestamp have)
-{
- struct GNUNET_TIME_Relative delta;
- char *details;
- // enum GNUNET_DB_QueryStatus qs;
- // struct TALER_AUDITORDB_RowMinorInconsistencies rmi;
-
- if (GNUNET_TIME_timestamp_cmp (have, >, want))
- delta = GNUNET_TIME_absolute_get_difference (want.abs_time,
- have.abs_time);
- else
- delta = GNUNET_TIME_absolute_get_difference (have.abs_time,
- want.abs_time);
- if (GNUNET_TIME_relative_cmp (delta,
- <=,
- TIME_TOLERANCE))
- return;
-
- GNUNET_asprintf (&details,
- "execution date mismatch (%s)",
- GNUNET_TIME_relative2s (delta,
- true));
-#if FIXME
-
- rmi.diagnostic = details;
- rmi.row_table = (char *) table;
-
- qs = TALER_ARL_adb->insert_row_minor_inconsistencies (
- TALER_ARL_adb->cls,
- &rmi);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }
- TALER_ARL_report (report_row_minor_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("table",
- table),
- GNUNET_JSON_pack_uint64 ("row",
- rowid),
- GNUNET_JSON_pack_string ("diagnostic",
- details)));
-#endif
- GNUNET_free (details);
-}
-
-
-/**
- * Function called with details about outgoing wire transfers
- * as claimed by the exchange DB.
- *
- * @param cls a `struct WireAccount`
- * @param rowid unique serial ID for the refresh session in our DB
- * @param date timestamp of the transfer (roughly)
- * @param wtid wire transfer subject
- * @param payto_uri wire transfer details of the receiver
- * @param amount amount that was wired
- * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
- */
-static enum GNUNET_GenericReturnValue
-wire_out_cb (void *cls,
- uint64_t rowid,
- struct GNUNET_TIME_Timestamp date,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const char *payto_uri,
- const struct TALER_Amount *amount)
-{
- struct WireAccount *wa = cls;
- struct GNUNET_HashCode key;
- struct ReserveOutInfo *roi;
- /*struct TALER_AUDITORDB_WireOutInconsistency woi;
- struct TALER_AUDITORDB_WireOutInconsistency woi2;
- struct TALER_AUDITORDB_WireOutInconsistency woi3;
- struct TALER_AUDITORDB_WireOutInconsistency woi4;
- enum GNUNET_DB_QueryStatus qs; */
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Exchange wire OUT at %s of %s with WTID %s\n",
- GNUNET_TIME_timestamp2s (date),
- TALER_amount2s (amount),
- TALER_B2S (wtid));
- TALER_ARL_amount_add (&total_wire_out,
- &total_wire_out,
- amount);
- GNUNET_CRYPTO_hash (wtid,
- sizeof (struct TALER_WireTransferIdentifierRawP),
- &key);
- roi = GNUNET_CONTAINER_multihashmap_get (out_map,
- &key);
- if (NULL == roi)
- {
- /* Wire transfer was not made (yet) at all (but would have been
- justified), so the entire amount is missing / still to be done.
- This is moderately harmless, it might just be that the aggregator
- has not yet fully caught up with the transfers it should do. */
-#if FIXME
-// TODO fix woi implementation
- /* woi.
-
- qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }*/
- TALER_ARL_report (
- report_wire_out_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("row",
- rowid),
- TALER_JSON_pack_amount ("amount_wired",
- &zero),
- TALER_JSON_pack_amount ("amount_justified",
- amount),
- GNUNET_JSON_pack_data_auto ("wtid",
- wtid),
- TALER_JSON_pack_time_abs_human ("timestamp",
- date.abs_time),
- GNUNET_JSON_pack_string ("diagnostic",
- "wire transfer not made (yet?)"),
- GNUNET_JSON_pack_string ("account_section",
- wa->ai->section_name)));
-#endif
- TALER_ARL_amount_add (&total_bad_amount_out_minus,
- &total_bad_amount_out_minus,
- amount);
- if (TALER_ARL_do_abort ())
- return GNUNET_SYSERR;
- return GNUNET_OK;
- }
- if (0 != strcasecmp (payto_uri,
- roi->details.credit_account_uri))
- {
- /* Destination bank account is wrong in actual wire transfer, so
- we should count the wire transfer as entirely spurious, and
- additionally consider the justified wire transfer as missing. */
-#if FIXME
- /* woi2.
-
- qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }*/
- TALER_ARL_report (
- report_wire_out_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("row",
- rowid),
- TALER_JSON_pack_amount ("amount_wired",
- &roi->details.amount),
- TALER_JSON_pack_amount ("amount_justified",
- &zero),
- GNUNET_JSON_pack_data_auto ("wtid",
- wtid),
- TALER_JSON_pack_time_abs_human ("timestamp",
- date.abs_time),
- GNUNET_JSON_pack_string ("diagnostic",
- "receiver account mismatch"),
- GNUNET_JSON_pack_string ("target",
- payto_uri),
- GNUNET_JSON_pack_string ("account_section",
- wa->ai->section_name)));
-#endif
- TALER_ARL_amount_add (&total_bad_amount_out_plus,
- &total_bad_amount_out_plus,
- &roi->details.amount);
-#if FIXME
- TALER_ARL_report (
- /* woi3.
-
-qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
-if (qs < 0)
-{
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
-}*/
- report_wire_out_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("row",
- rowid),
- TALER_JSON_pack_amount ("amount_wired",
- &zero),
- TALER_JSON_pack_amount ("amount_justified",
- amount),
- GNUNET_JSON_pack_data_auto ("wtid",
- wtid),
- TALER_JSON_pack_time_abs_human ("timestamp",
- date.abs_time),
- GNUNET_JSON_pack_string ("diagnostic",
- "receiver account mismatch"),
- GNUNET_JSON_pack_string ("target",
- roi->details.
- credit_account_uri),
- GNUNET_JSON_pack_string ("account_section",
- wa->ai->section_name)));
-#endif
- TALER_ARL_amount_add (&total_bad_amount_out_minus,
- &total_bad_amount_out_minus,
- amount);
- goto cleanup;
- }
- if (0 != TALER_amount_cmp (&roi->details.amount,
- amount))
- {
-#if FIXME
- TALER_ARL_report (
- /* woi4.
-
-qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
-if (qs < 0)
-{
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
-}*/
- report_wire_out_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("row",
- rowid),
- TALER_JSON_pack_amount ("amount_justified",
- amount),
- TALER_JSON_pack_amount ("amount_wired",
- &roi->details.amount),
- GNUNET_JSON_pack_data_auto ("wtid",
- wtid),
- TALER_JSON_pack_time_abs_human ("timestamp",
- date.abs_time),
- GNUNET_JSON_pack_string ("diagnostic",
- "wire amount does not match"),
- GNUNET_JSON_pack_string ("account_section",
- wa->ai->section_name)));
-#endif
- if (0 < TALER_amount_cmp (amount,
- &roi->details.amount))
- {
- /* amount > roi->details.amount: wire transfer was smaller than it should have been */
- struct TALER_Amount delta;
-
- TALER_ARL_amount_subtract (&delta,
- amount,
- &roi->details.amount);
- TALER_ARL_amount_add (&total_bad_amount_out_minus,
- &total_bad_amount_out_minus,
- &delta);
- }
- else
- {
- /* roi->details.amount < amount: wire transfer was larger than it should have been */
- struct TALER_Amount delta;
-
- TALER_ARL_amount_subtract (&delta,
- &roi->details.amount,
- amount);
- TALER_ARL_amount_add (&total_bad_amount_out_plus,
- &total_bad_amount_out_plus,
- &delta);
- }
- goto cleanup;
- }
-
- check_time_difference ("wire_out",
- rowid,
- date,
- roi->details.execution_date);
-cleanup:
- GNUNET_assert (GNUNET_OK ==
- free_roi (NULL,
- &key,
- roi));
- wa->pp.last_wire_out_serial_id = rowid + 1;
- if (TALER_ARL_do_abort ())
- return GNUNET_SYSERR;
- return GNUNET_OK;
-}
-
-
-/**
- * Closure for #check_rc_matches
- */
-struct CheckMatchContext
-{
-
- /**
- * Reserve operation looking for a match
- */
- const struct ReserveOutInfo *roi;
-
- /**
- * Set to true if we found a match.
- */
- bool found;
-};
-
-
-/**
- * Check if any of the reserve closures match the given wire transfer.
- *
- * @param[in,out] cls a `struct CheckMatchContext`
- * @param key key of @a value in #reserve_closures
- * @param value a `struct ReserveClosure`
- */
-static enum GNUNET_GenericReturnValue
-check_rc_matches (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- struct CheckMatchContext *ctx = cls;
- struct ReserveClosure *rc = value;
-
- if ((0 == GNUNET_memcmp (&ctx->roi->details.wtid,
- &rc->wtid)) &&
- (0 == strcasecmp (rc->receiver_account,
- ctx->roi->details.credit_account_uri)) &&
- (0 == TALER_amount_cmp (&rc->amount,
- &ctx->roi->details.amount)))
- {
- check_time_difference ("reserves_closures",
- rc->rowid,
- rc->execution_date,
- ctx->roi->details.execution_date);
- ctx->found = true;
- free_rc (NULL,
- key,
- rc);
- return GNUNET_NO;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Check whether the given transfer was justified by a reserve closure or
- * profit drain. If not, complain that we failed to match an entry from
- * #out_map. This means a wire transfer was made without proper
- * justification.
- *
- * @param cls a `struct WireAccount`
- * @param key unused key
- * @param value the `struct ReserveOutInfo` to report
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-complain_out_not_found (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- // struct WireAccount *wa = cls;
- struct ReserveOutInfo *roi = value;
- struct GNUNET_HashCode rkey;
- struct CheckMatchContext ctx = {
- .roi = roi,
- .found = false
- };
-
- (void) key;
- hash_rc (roi->details.credit_account_uri,
- &roi->details.wtid,
- &rkey);
- GNUNET_CONTAINER_multihashmap_get_multiple (reserve_closures,
- &rkey,
- &check_rc_matches,
- &ctx);
- if (ctx.found)
- return GNUNET_OK;
- /* check for profit drain */
- {
- enum GNUNET_DB_QueryStatus qs;
- uint64_t serial;
- char *account_section;
- char *payto_uri;
- struct GNUNET_TIME_Timestamp request_timestamp;
- struct TALER_Amount amount;
- struct TALER_MasterSignatureP master_sig;
- // struct TALER_AUDITORDB_RowInconsistency ri;
- // struct TALER_AUDITORDB_WireOutInconsistency woi;
- // struct TALER_AUDITORDB_WireOutInconsistency woi2;
- // struct TALER_AUDITORDB_WireOutInconsistency woi3;
-
- qs = TALER_ARL_edb->get_drain_profit (TALER_ARL_edb->cls,
- &roi->details.wtid,
- &serial,
- &account_section,
- &payto_uri,
- &request_timestamp,
- &amount,
- &master_sig);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return GNUNET_SYSERR;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- /* should fail on commit later ... */
- GNUNET_break (0);
- return GNUNET_NO;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* not a profit drain */
- break;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Profit drain of %s to %s found!\n",
- TALER_amount2s (&amount),
- payto_uri);
- if (GNUNET_OK !=
- TALER_exchange_offline_profit_drain_verify (
- &roi->details.wtid,
- request_timestamp,
- &amount,
- account_section,
- payto_uri,
- &TALER_ARL_master_pub,
- &master_sig))
- {
- GNUNET_break (0);
-#if FIXME
- ri.row_table = "profit_drains";
- ri.diagnostic = "invalid signature";
-
- qs = TALER_ARL_adb->insert_row_inconsistency (
- TALER_ARL_adb->cls,
- &ri);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }
- TALER_ARL_report (report_row_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("table",
- "profit_drains"),
- GNUNET_JSON_pack_uint64 ("row",
- serial),
- GNUNET_JSON_pack_data_auto ("id",
- &roi->details.wtid),
- GNUNET_JSON_pack_string ("diagnostic",
- "invalid signature")));
-#endif
- TALER_ARL_amount_add (&total_bad_amount_out_plus,
- &total_bad_amount_out_plus,
- &amount);
- }
- else if (0 !=
- strcasecmp (payto_uri,
- roi->details.credit_account_uri))
- {
-#if FIXME
- // TODO fix woi
- /* woi.
-
- qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }*/
- TALER_ARL_report (
- report_wire_out_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("row",
- serial),
- TALER_JSON_pack_amount ("amount_wired",
- &roi->details.amount),
- TALER_JSON_pack_amount ("amount_wired",
- &amount),
- GNUNET_JSON_pack_data_auto ("wtid",
- &roi->details.wtid),
- TALER_JSON_pack_time_abs_human ("timestamp",
- roi->details.execution_date.abs_time
- ),
- GNUNET_JSON_pack_string ("account",
- wa->ai->section_name),
- GNUNET_JSON_pack_string ("diagnostic",
- "wrong target account")));
-#endif
- TALER_ARL_amount_add (&total_bad_amount_out_plus,
- &total_bad_amount_out_plus,
- &amount);
- }
- else if (0 !=
- TALER_amount_cmp (&amount,
- &roi->details.amount))
- {
-#if FIXME
- // TODO fix woi
- /* woi.
-
- qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }*/
- TALER_ARL_report (
- report_wire_out_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("row",
- serial),
- TALER_JSON_pack_amount ("amount_justified",
- &roi->details.amount),
- TALER_JSON_pack_amount ("amount_wired",
- &amount),
- GNUNET_JSON_pack_data_auto ("wtid",
- &roi->details.wtid),
- TALER_JSON_pack_time_abs_human ("timestamp",
- roi->details.execution_date.abs_time
- ),
- GNUNET_JSON_pack_string ("account",
- wa->ai->section_name),
- GNUNET_JSON_pack_string ("diagnostic",
- "profit drain amount incorrect")));
-#endif
- TALER_ARL_amount_add (&total_bad_amount_out_minus,
- &total_bad_amount_out_minus,
- &roi->details.amount);
- TALER_ARL_amount_add (&total_bad_amount_out_plus,
- &total_bad_amount_out_plus,
- &amount);
- }
- GNUNET_free (account_section);
- GNUNET_free (payto_uri);
- /* profit drain was correct */
- TALER_ARL_amount_add (&TALER_ARL_USE_AB (total_drained),
- &TALER_ARL_USE_AB (total_drained),
- &amount);
- return GNUNET_OK;
- }
- }
-#if FIXME
- // TODO fix woi
- /* woi3.
-
- qs = TALER_ARL_adb->insert_reserve_balance_insufficient_inconsistency (
- TALER_ARL_adb->cls,
- &rbiil);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }*/
- TALER_ARL_report (
- report_wire_out_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("row",
- 0),
- TALER_JSON_pack_amount ("amount_wired",
- &roi->details.amount),
- TALER_JSON_pack_amount ("amount_justified",
- &zero),
- GNUNET_JSON_pack_data_auto ("wtid",
- &roi->details.wtid),
- TALER_JSON_pack_time_abs_human ("timestamp",
- roi->details.execution_date.abs_time),
- GNUNET_JSON_pack_string ("account_section",
- wa->ai->section_name),
- GNUNET_JSON_pack_string ("diagnostic",
- "justification for wire transfer not found")));
-#endif
- TALER_ARL_amount_add (&total_bad_amount_out_plus,
- &total_bad_amount_out_plus,
- &roi->details.amount);
- return GNUNET_OK;
-}
-
-
-/**
- * Main function for processing 'reserves_out' data. We start by going over
- * the DEBIT transactions this time, and then verify that all of them are
- * justified by 'reserves_out'.
- *
- * @param cls `struct WireAccount` with a wire account list to process
- */
-static void
-process_debits (void *cls);
-
-
-/**
- * Go over the "wire_out" table of the exchange and
- * verify that all wire outs are in that table.
- *
- * @param wa wire account we are processing
- */
-static void
-check_exchange_wire_out (struct WireAccount *wa)
-{
- enum GNUNET_DB_QueryStatus qs;
-
- GNUNET_assert (NULL == wa->dhh);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Analyzing exchange's wire OUT table for account `%s'\n",
- wa->ai->section_name);
- qs = TALER_ARL_edb->select_wire_out_above_serial_id_by_account (
- TALER_ARL_edb->cls,
- wa->ai->section_name,
- wa->pp.last_wire_out_serial_id,
- &wire_out_cb,
- wa);
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GNUNET_CONTAINER_multihashmap_iterate (out_map,
- &complain_out_not_found,
- wa);
- /* clean up */
- GNUNET_CONTAINER_multihashmap_iterate (out_map,
- &free_roi,
- NULL);
- process_debits (wa->next);
-}
-
-
-/**
- * This function is called for all transactions that
- * are debited from the exchange's account (outgoing
- * transactions).
- *
- * @param cls `struct WireAccount` with current wire account to process
- * @param dhr HTTP response details
- */
-static void
-history_debit_cb (void *cls,
- const struct TALER_BANK_DebitHistoryResponse *dhr)
-{
- struct WireAccount *wa = cls;
- struct ReserveOutInfo *roi;
- size_t slen;
- // struct TALER_AUDITORDB_WireFormatInconsistency wfi;
-
- wa->dhh = NULL;
- switch (dhr->http_status)
- {
- case MHD_HTTP_OK:
- for (unsigned int i = 0; i < dhr->details.ok.details_length; i++)
- {
- const struct TALER_BANK_DebitDetails *dd
- = &dhr->details.ok.details[i];
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Analyzing bank DEBIT at %s of %s with WTID %s\n",
- GNUNET_TIME_timestamp2s (dd->execution_date),
- TALER_amount2s (&dd->amount),
- TALER_B2S (&dd->wtid));
- /* Update offset */
- wa->wire_off_out = dd->serial_id;
- slen = strlen (dd->credit_account_uri) + 1;
- roi = GNUNET_malloc (sizeof (struct ReserveOutInfo)
- + slen);
- GNUNET_CRYPTO_hash (&dd->wtid,
- sizeof (dd->wtid),
- &roi->subject_hash);
- roi->details.amount = dd->amount;
- roi->details.execution_date = dd->execution_date;
- roi->details.wtid = dd->wtid;
- roi->details.credit_account_uri = (const char *) &roi[1];
- GNUNET_memcpy (&roi[1],
- dd->credit_account_uri,
- slen);
- if (GNUNET_OK !=
- GNUNET_CONTAINER_multihashmap_put (out_map,
- &roi->subject_hash,
- roi,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
- {
- char *diagnostic;
-
- GNUNET_asprintf (&diagnostic,
- "duplicate subject hash `%s'",
- TALER_B2S (&roi->subject_hash));
- TALER_ARL_amount_add (&total_wire_format_amount,
- &total_wire_format_amount,
- &dd->amount);
-#if FIXME
- wfi.diagnostic = diagnostic;
- wfi.amount = &dd->amount;
- wfi.wire_offset = dd->serial_id;
-
- qs = TALER_ARL_adb->insert_wire_format_inconsistency (
- TALER_ARL_adb->cls,
- &wfi);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }
- TALER_ARL_report (report_wire_format_inconsistencies,
- GNUNET_JSON_PACK (
- TALER_JSON_pack_amount ("amount",
- &dd->amount),
- GNUNET_JSON_pack_uint64 ("wire_offset",
- dd->serial_id),
- GNUNET_JSON_pack_string ("diagnostic",
- diagnostic)));
-#endif
- GNUNET_free (diagnostic);
- }
- }
- check_exchange_wire_out (wa);
- return;
- case MHD_HTTP_NO_CONTENT:
- check_exchange_wire_out (wa);
- return;
- case MHD_HTTP_NOT_FOUND:
- if (ignore_account_404)
- {
- check_exchange_wire_out (wa);
- return;
- }
- break;
- default:
- break;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error fetching debit history of account %s: %u/%u!\n",
- wa->ai->section_name,
- dhr->http_status,
- (unsigned int) dhr->ec);
- commit (GNUNET_DB_STATUS_HARD_ERROR);
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
-}
-
-
-/**
- * Main function for processing 'reserves_out' data. We start by going over
- * the DEBIT transactions this time, and then verify that all of them are
- * justified by 'reserves_out'.
- *
- * @param cls `struct WireAccount` with a wire account list to process
- */
-static void
-process_debits (void *cls)
-{
- struct WireAccount *wa = cls;
-
- /* skip accounts where DEBIT is not enabled */
- while ((NULL != wa) &&
- (GNUNET_NO == wa->ai->debit_enabled))
- wa = wa->next;
- if (NULL == wa)
- {
- /* end of iteration, now check wire_out to see
- if it matches #out_map */
- conclude_wire_out ();
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Checking bank DEBIT records of account `%s'\n",
- wa->ai->section_name);
- GNUNET_assert (NULL == wa->dhh);
- // FIXME: handle the case where more than INT32_MAX transactions exist.
- // (CG: used to be INT64_MAX, changed by MS to INT32_MAX, why? To be discussed with him!)
- wa->dhh = TALER_BANK_debit_history (ctx,
- wa->ai->auth,
- wa->wire_off_out,
- INT32_MAX,
- GNUNET_TIME_UNIT_ZERO,
- &history_debit_cb,
- wa);
- if (NULL == wa->dhh)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to obtain bank transaction history for `%s'\n",
- wa->ai->section_name);
- commit (GNUNET_DB_STATUS_HARD_ERROR);
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-}
-
-
-/**
- * Begin analyzing wire_out.
- */
-static void
-begin_debit_audit (void)
-{
- GNUNET_assert (NULL == out_map);
- out_map = GNUNET_CONTAINER_multihashmap_create (1024,
- true);
- process_debits (wa_head);
-}
-
-
-/* ***************************** Analyze reserves_in ************************ */
-
-/**
* Conclude the credit history check by logging entries that
* were not found and freeing resources. Then move on to
* processing debits.
@@ -2106,8 +455,7 @@ conclude_credit_history (void)
GNUNET_CONTAINER_multihashmap_destroy (in_map);
in_map = NULL;
}
- /* credit done, now check debits */
- begin_debit_audit ();
+ commit (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT);
}
@@ -2705,98 +1053,6 @@ begin_credit_audit (void)
/**
- * Function called about reserve closing operations the aggregator triggered.
- *
- * @param cls closure
- * @param rowid row identifier used to uniquely identify the reserve closing operation
- * @param execution_date when did we execute the close operation
- * @param amount_with_fee how much did we debit the reserve
- * @param closing_fee how much did we charge for closing the reserve
- * @param reserve_pub public key of the reserve
- * @param receiver_account where did we send the funds, in payto://-format
- * @param wtid identifier used for the wire transfer
- * @param close_request_row which close request triggered the operation?
- * 0 if it was a timeout (not used)
- * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
- */
-static enum GNUNET_GenericReturnValue
-reserve_closed_cb (void *cls,
- uint64_t rowid,
- struct GNUNET_TIME_Timestamp execution_date,
- const struct TALER_Amount *amount_with_fee,
- const struct TALER_Amount *closing_fee,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const char *receiver_account,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- uint64_t close_request_row)
-{
- struct ReserveClosure *rc;
- struct GNUNET_HashCode key;
- // enum GNUNET_DB_QueryStatus qs;
- // struct TALER_AUDITORDB_RowInconsistency ri;
-
- (void) cls;
- (void) close_request_row;
- rc = GNUNET_new (struct ReserveClosure);
- if (TALER_ARL_SR_INVALID_NEGATIVE ==
- TALER_ARL_amount_subtract_neg (&rc->amount,
- amount_with_fee,
- closing_fee))
- {
-#if FIXME
-// TODO fix, something seems not right
- ri.row_table = "reserves_closures";
- ri.diagnostic = "closing fee above total amount";
-
- qs = TALER_ARL_adb->insert_row_inconsistency (
- TALER_ARL_adb->cls,
- &ri);
-
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- }
- TALER_ARL_report (report_row_inconsistencies,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("table",
- "reserves_closures"),
- GNUNET_JSON_pack_uint64 ("row",
- rowid),
- GNUNET_JSON_pack_data_auto ("id",
- reserve_pub),
- TALER_JSON_pack_amount ("amount_with_fee",
- amount_with_fee),
- TALER_JSON_pack_amount ("closing_fee",
- closing_fee),
- GNUNET_JSON_pack_string ("diagnostic",
- "closing fee above total amount")));
-#endif
- GNUNET_free (rc);
- if (TALER_ARL_do_abort ())
- return GNUNET_SYSERR;
- return GNUNET_OK;
- }
- TALER_ARL_USE_PP (wire_reserve_close_id)
- = GNUNET_MAX (TALER_ARL_USE_PP (wire_reserve_close_id),
- rowid + 1);
- rc->receiver_account = GNUNET_strdup (receiver_account);
- rc->wtid = *wtid;
- rc->execution_date = execution_date;
- rc->rowid = rowid;
- hash_rc (receiver_account,
- wtid,
- &key);
- (void) GNUNET_CONTAINER_multihashmap_put (reserve_closures,
- &key,
- rc,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- if (TALER_ARL_do_abort ())
- return GNUNET_SYSERR;
- return GNUNET_OK;
-}
-
-
-/**
* Start the database transactions and begin the audit.
*
* @return transaction status code
@@ -2836,12 +1092,6 @@ begin_transaction (void)
}
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
- &total_bad_amount_out_plus));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
- &total_bad_amount_out_minus));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
&total_bad_amount_in_plus));
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
@@ -2851,12 +1101,6 @@ begin_transaction (void)
&total_misattribution_in));
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
- &total_amount_lag));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
- &total_closure_amount_lag));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
&total_wire_format_amount));
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
@@ -2864,13 +1108,9 @@ begin_transaction (void)
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
&total_wire_in));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
- &total_wire_out));
qs = TALER_ARL_adb->get_balance (
TALER_ARL_adb->cls,
- TALER_ARL_GET_AB (total_drained),
- TALER_ARL_GET_AB (final_balance),
+ TALER_ARL_GET_AB (total_wire_in),
NULL);
switch (qs)
{
@@ -2883,10 +1123,7 @@ begin_transaction (void)
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
- &TALER_ARL_USE_AB (total_drained)));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
- &TALER_ARL_USE_AB (final_balance)));
+ &TALER_ARL_USE_AB (total_wire_in)));
had_start_balance = false;
break;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
@@ -2901,78 +1138,23 @@ begin_transaction (void)
"wire-%s-%s",
wa->ai->section_name,
"reserve_in_serial_id");
- GNUNET_asprintf (&wa->label_wire_out_serial_id,
- "wire-%s-%s",
- wa->ai->section_name,
- "wire_out_serial_id");
GNUNET_asprintf (&wa->label_wire_off_in,
"wire-%s-%s",
wa->ai->section_name,
"wire_off_in");
- GNUNET_asprintf (&wa->label_wire_off_out,
- "wire-%s-%s",
- wa->ai->section_name,
- "wire_off_out");
wa->qsx = TALER_ARL_adb->get_auditor_progress (
TALER_ARL_adb->cls,
wa->label_reserve_in_serial_id,
- &wa->pp.last_reserve_in_serial_id,
- wa->label_wire_out_serial_id,
- &wa->pp.last_wire_out_serial_id,
+ &wa->last_reserve_in_serial_id,
wa->label_wire_off_in,
&wa->wire_off_in,
- wa->label_wire_off_out,
- &wa->wire_off_out,
NULL);
if (0 > wa->qsx)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == wa->qsx);
return GNUNET_DB_STATUS_HARD_ERROR;
}
- wa->start_pp = wa->pp;
- }
- qsx_gwap = TALER_ARL_adb->get_auditor_progress (
- TALER_ARL_adb->cls,
- TALER_ARL_GET_PP (wire_reserve_close_id),
- TALER_ARL_GET_PP (wire_batch_deposit_id),
- TALER_ARL_GET_PP (wire_aggregation_id),
- NULL);
- if (0 > qsx_gwap)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx_gwap);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx_gwap)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "First analysis of with wire auditor, starting audit from scratch\n");
- }
- else
- {
- if (TALER_ARL_USE_PP (wire_reserve_close_id) == 0)
- had_start_progress = false;
- else
- had_start_progress = true;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Resuming wire audit at %llu / %llu / %llu\n",
- (unsigned long long) TALER_ARL_USE_PP (wire_reserve_close_id),
- (unsigned long long) TALER_ARL_USE_PP (wire_batch_deposit_id),
- (unsigned long long) TALER_ARL_USE_PP (wire_aggregation_id));
- }
-
- {
- enum GNUNET_DB_QueryStatus qs;
-
- qs = TALER_ARL_edb->select_reserve_closed_above_serial_id (
- TALER_ARL_edb->cls,
- TALER_ARL_USE_PP (wire_reserve_close_id),
- &reserve_closed_cb,
- NULL);
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
+ wa->start_reserve_in_serial_id = wa->last_reserve_in_serial_id;
}
begin_credit_audit ();
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
@@ -3035,8 +1217,6 @@ db_notify (void *cls,
global_ret = EXIT_FAILURE;
GNUNET_SCHEDULER_shutdown ();
}
-
-
}
@@ -3059,7 +1239,7 @@ run (void *cls,
(void) cfgfile;
cfg = c;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Launching wire auditor\n");
+ "Launching wire-credit auditor\n");
if (GNUNET_OK !=
TALER_ARL_init (c))
{
@@ -3067,9 +1247,6 @@ run (void *cls,
return;
}
- reserve_closures
- = GNUNET_CONTAINER_multihashmap_create (1024,
- GNUNET_NO);
if (NULL ==
(db_plugin = TALER_AUDITORDB_plugin_load (cfg)))
{
@@ -3107,14 +1284,6 @@ run (void *cls,
global_ret = EXIT_FAILURE;
return;
}
- reserve_closures = GNUNET_CONTAINER_multihashmap_create (1024,
- GNUNET_NO);
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
- &total_bad_amount_out_plus));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
- &total_bad_amount_out_minus));
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
&total_bad_amount_in_plus));
@@ -3126,20 +1295,13 @@ run (void *cls,
&total_misattribution_in));
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
- &total_amount_lag));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
- &total_closure_amount_lag));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (TALER_ARL_currency,
&total_wire_format_amount));
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TALER_ARL_currency,
&zero));
if (GNUNET_OK !=
TALER_EXCHANGEDB_load_accounts (TALER_ARL_cfg,
- TALER_EXCHANGEDB_ALO_DEBIT
- | TALER_EXCHANGEDB_ALO_CREDIT
+ TALER_EXCHANGEDB_ALO_CREDIT
| TALER_EXCHANGEDB_ALO_AUTHDATA))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -3218,7 +1380,7 @@ main (int argc,
ret = GNUNET_PROGRAM_run (
argc,
argv,
- "taler-helper-auditor-wire",
+ "taler-helper-auditor-wire-credit",
gettext_noop (
"Audit exchange database for consistency with the bank's wire transfers"),
options,
@@ -3233,4 +1395,4 @@ main (int argc,
}
-/* end of taler-helper-auditor-wire.c */
+/* end of taler-helper-auditor-wire-credit.c */