gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-exchange] branch master updated: more work on audito


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: more work on auditor, listing open TODOs
Date: Tue, 14 Mar 2017 17:58:27 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 296f919  more work on auditor, listing open TODOs
296f919 is described below

commit 296f919ce4dcd9123c402d52d18afae7e353b11a
Author: Christian Grothoff <address@hidden>
AuthorDate: Tue Mar 14 18:00:17 2017 +0100

    more work on auditor, listing open TODOs
---
 src/auditor/taler-auditor.c               | 537 ++++++++++++++++++++++++++++--
 src/auditordb/plugin_auditordb_postgres.c |  49 +++
 src/include/taler_auditordb_plugin.h      |  28 +-
 3 files changed, 576 insertions(+), 38 deletions(-)

diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index 51a4eda..cab44e4 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -22,7 +22,22 @@
  * - This auditor does not verify that 'reserves_in' actually matches
  *   the wire transfers from the bank. This needs to be checked separately!
  * - Similarly, we do not check that the outgoing wire transfers match those
- *   given in the XXX table. This needs to be checked separately!
+ *   given in the aggregation_tracking table. This needs to be checked 
separately!
+ *
+ * TODO:
+ * - initialize master_pub via command-line argument (URGENT!)
+ * - modify auditordb to allow multiple last serial IDs per table in progress 
tracking
+ * - modify auditordb to return row ID where we need it for diagnostics
+ * - implement coin/denomination audit
+ * - implement merchant deposit audit
+ *   - see if we need more tables there
+ * - write reporting logic to output nice report beyond GNUNET_log()
+ *
+ * EXTERNAL:
+ * - add tool to pay-back expired reserves (#4956), and support here
+ * - add tool to verify 'reserves_in' from wire transfer inspection
+ * - add tool to trigger computation of historic revenues
+ *   (move balances from 'current' revenue/profits to 'historic' tables)
  */
 #include "platform.h"
 #include <gnunet/gnunet_util_lib.h>
@@ -116,6 +131,28 @@ 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)
+{
+  // TODO: implement proper reporting logic writing to file.
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Minor inconsistency detected in table %s at row %llu: %s\n",
+              table,
+              (unsigned long long) rowid,
+              diagnostic);
+}
+
+
+/**
  * Report a global inconsistency with respect to a reserve.
  *
  * @param reserve_pub the affected reserve
@@ -137,6 +174,43 @@ report_reserve_inconsistency (const struct 
TALER_ReservePublicKeyP *reserve_pub,
 }
 
 
+/**
+ * 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).
+ * The reserve has made @a total_fee_balance in profit from withdrawal
+ * operations alone.
+ *
+ * Note that this is for the "ongoing" reporting period.  Historic
+ * revenue (as stored via the "insert_historic_reserve_revenue")
+ * is not included in the @a total_fee_balance.
+ *
+ * @param total_balance how much money (in total) is left in all of the
+ *        reserves (that has not been withdrawn)
+ * @param total_fee_balance how much money (in total) did the reserve
+ *        make from withdrawal fees
+ */
+static void
+report_reserve_balance (const struct TALER_Amount *total_balance,
+                        const struct TALER_Amount *total_fee_balance)
+{
+  char *balance;
+  char *fees;
+
+  balance = TALER_amount_to_string (total_balance);
+  fees = TALER_amount_to_string (total_fee_balance);
+  // TODO: implement proper reporting logic writing to file.
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+              "Total escrow balance to be held for reserves: %s\n",
+              balance);
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+              "Total profits made from reserves: %s\n",
+              fees);
+  GNUNET_free (fees);
+  GNUNET_free (balance);
+}
+
+
 /* ************************* Transaction-global state ************************ 
*/
 
 /**
@@ -236,6 +310,7 @@ clear_transaction_state_cache ()
 
 
 /* ***************************** Analyze reserves ************************ */
+/* This logic checks the reserves_in, reserves_out and reserves-tables */
 
 /**
  * Summary data we keep per reserve.
@@ -244,46 +319,62 @@ struct ReserveSummary
 {
   /**
    * Public key of the reserve.
+   * Always set when the struct is first initialized.
    */
   struct TALER_ReservePublicKeyP reserve_pub;
 
   /**
-   * Sum of all incoming transfers.
+   * Sum of all incoming transfers during this transaction.
+   * Updated only in #handle_reserve_in().
    */
   struct TALER_Amount total_in;
 
   /**
-   * Sum of all outgoing transfers.
+   * Sum of all outgoing transfers during this transaction (includes fees).
+   * Updated only in #handle_reserve_out().
    */
   struct TALER_Amount total_out;
 
   /**
+   * Sum of withdraw fees encountered during this transaction.
+   */
+  struct TALER_Amount total_fee;
+
+  /**
    * Previous balance of the reserve as remembered by the auditor.
+   * (updated based on @e total_in and @e total_out at the end).
    */
   struct TALER_Amount a_balance;
 
   /**
    * Previous withdraw fee balance of the reserve, as remembered by the 
auditor.
+   * (updated based on @e total_fee at the end).
    */
   struct TALER_Amount a_withdraw_fee_balance;
 
   /**
    * Previous reserve expiration data, as remembered by the auditor.
+   * (updated on-the-fly in #handle_reserve_in()).
    */
   struct GNUNET_TIME_Absolute a_expiration_date;
 
   /**
    * Previous last processed reserve_in serial ID, as remembered by the 
auditor.
+   * (updated on-the-fly in #handle_reserve_in()).
    */
   uint64_t a_last_reserve_in_serial_id;
 
   /**
    * Previous last processed reserve_out serial ID, as remembered by the 
auditor.
+   * (updated on-the-fly in #handle_reserve_out()).
    */
   uint64_t a_last_reserve_out_serial_id;
 
   /**
-   * Did we have a previous reserve info?
+   * Did we have a previous reserve info?  Used to decide between
+   * UPDATE and INSERT later.  Initialized in
+   * #load_auditor_reserve_summary() together with the a-* values
+   * (if available).
    */
   int had_ri;
 
@@ -292,6 +383,8 @@ struct ReserveSummary
 
 /**
  * Load the auditor's remembered state about the reserve into @a rs.
+ * The "total_in" and "total_out" amounts of @a rs must already be
+ * initialized (so we can determine the currency).
  *
  * @param[in|out] rs reserve summary to (fully) initialize
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors
@@ -318,19 +411,60 @@ load_auditor_reserve_summary (struct ReserveSummary *rs)
   if (GNUNET_NO == ret)
   {
     rs->had_ri = GNUNET_NO;
-    // FIXME: set rs->a-values to sane defaults!
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (rs->total_in.currency,
+                                          &rs->a_balance));
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (rs->total_in.currency,
+                                          &rs->a_withdraw_fee_balance));
     return GNUNET_OK;
   }
   rs->had_ri = GNUNET_YES;
-  /* TODO: check values we got are sane? */
+  if ( (GNUNET_YES !=
+        TALER_amount_cmp_currency (&rs->a_balance,
+                                   &rs->a_withdraw_fee_balance)) ||
+       (GNUNET_YES !=
+        TALER_amount_cmp_currency (&rs->total_in,
+                                   &rs->a_balance)) )
+  {
+    report_row_inconsistency ("auditor-reserve-info",
+                              UINT64_MAX, /* FIXME: modify API to get rowid! */
+                              "currencies for reserve differ");
+    /* TODO: find a sane way to continue... */
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
   return GNUNET_OK;
 }
 
 
 /**
+ * Closure to the various callbacks we make while checking a reserve.
+ */
+struct ReserveContext
+{
+  /**
+   * Map from hash of reserve's public key to a `struct ReserveSummary`.
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *reserves;
+
+  /**
+   * Total balance in all reserves (updated).
+   */
+  struct TALER_Amount total_balance;
+
+  /**
+   * Total withdraw fees gotten in all reserves (updated).
+   */
+  struct TALER_Amount total_fee_balance;
+
+};
+
+
+/**
  * Function called with details about incoming wire transfers.
  *
- * @param cls our `struct GNUNET_CONTAINER_MultiHashMap` with the reserves
+ * @param cls our `struct ReserveContext`
  * @param rowid unique serial ID for the refresh session in our DB
  * @param reserve_pub public key of the reserve (also the WTID)
  * @param credit amount that was received
@@ -348,16 +482,17 @@ handle_reserve_in (void *cls,
                    const json_t *transfer_details,
                    struct GNUNET_TIME_Absolute execution_date)
 {
-  struct GNUNET_CONTAINER_MultiHashMap *reserves = cls;
+  struct ReserveContext *rc = cls;
   struct GNUNET_HashCode key;
   struct ReserveSummary *rs;
+  struct GNUNET_TIME_Absolute expiry;
 
   GNUNET_assert (rowid >= reserve_in_serial_id); /* should be monotonically 
increasing */
   reserve_in_serial_id = rowid + 1;
   GNUNET_CRYPTO_hash (reserve_pub,
                       sizeof (*reserve_pub),
                       &key);
-  rs = GNUNET_CONTAINER_multihashmap_get (reserves,
+  rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
                                           &key);
   if (NULL == rs)
   {
@@ -367,6 +502,9 @@ handle_reserve_in (void *cls,
     GNUNET_assert (GNUNET_OK ==
                    TALER_amount_get_zero (credit->currency,
                                           &rs->total_out));
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (credit->currency,
+                                          &rs->total_fee));
     if (GNUNET_OK !=
         load_auditor_reserve_summary (rs))
     {
@@ -375,7 +513,7 @@ handle_reserve_in (void *cls,
       return GNUNET_SYSERR;
     }
     GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CONTAINER_multihashmap_put (reserves,
+                   GNUNET_CONTAINER_multihashmap_put (rc->reserves,
                                                       &key,
                                                       rs,
                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
@@ -387,6 +525,12 @@ handle_reserve_in (void *cls,
                                      &rs->total_in,
                                      credit));
   }
+  GNUNET_assert (rowid >= rs->a_last_reserve_in_serial_id);
+  rs->a_last_reserve_in_serial_id = rowid + 1;
+  expiry = GNUNET_TIME_absolute_add (execution_date,
+                                     TALER_IDLE_RESERVE_EXPIRATION_TIME);
+  rs->a_expiration_date = GNUNET_TIME_absolute_max (rs->a_expiration_date,
+                                                    expiry);
   return GNUNET_OK;
 }
 
@@ -394,7 +538,7 @@ handle_reserve_in (void *cls,
 /**
  * Function called with details about withdraw operations.
  *
- * @param cls our `struct GNUNET_CONTAINER_MultiHashMap` with the reserves
+ * @param cls our `struct ReserveContext`
  * @param rowid unique serial ID for the refresh session in our DB
  * @param h_blind_ev blinded hash of the coin's public key
  * @param denom_pub public denomination key of the deposited coin
@@ -416,11 +560,14 @@ handle_reserve_out (void *cls,
                     struct GNUNET_TIME_Absolute execution_date,
                     const struct TALER_Amount *amount_with_fee)
 {
-  struct GNUNET_CONTAINER_MultiHashMap *reserves = cls;
+  struct ReserveContext *rc = cls;
   struct TALER_WithdrawRequestPS wsrd;
   struct GNUNET_HashCode key;
   struct ReserveSummary *rs;
   const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki;
+  struct TALER_Amount withdraw_fee;
+  struct GNUNET_TIME_Absolute valid_start;
+  struct GNUNET_TIME_Absolute expire_withdraw;
   int ret;
 
   /* should be monotonically increasing */
@@ -444,7 +591,16 @@ handle_reserve_out (void *cls,
     return GNUNET_OK;
   }
 
-  /* check that execution date is within withdraw range for denom_pub (?) */
+  /* check that execution date is within withdraw range for denom_pub  */
+  valid_start = GNUNET_TIME_absolute_ntoh (dki->properties.start);
+  expire_withdraw = GNUNET_TIME_absolute_ntoh 
(dki->properties.expire_withdraw);
+  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 ("reserve_out",
+                                    rowid,
+                                    "denomination key not valid at time of 
withdrawal");
+  }
 
   /* check reserve_sig */
   wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
@@ -468,7 +624,7 @@ handle_reserve_out (void *cls,
   GNUNET_CRYPTO_hash (reserve_pub,
                       sizeof (*reserve_pub),
                       &key);
-  rs = GNUNET_CONTAINER_multihashmap_get (reserves,
+  rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
                                           &key);
   if (NULL == rs)
   {
@@ -478,6 +634,9 @@ handle_reserve_out (void *cls,
     GNUNET_assert (GNUNET_OK ==
                    TALER_amount_get_zero (amount_with_fee->currency,
                                           &rs->total_in));
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (amount_with_fee->currency,
+                                          &rs->total_fee));
     if (GNUNET_OK !=
         load_auditor_reserve_summary (rs))
     {
@@ -486,7 +645,7 @@ handle_reserve_out (void *cls,
       return GNUNET_SYSERR;
     }
     GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CONTAINER_multihashmap_put (reserves,
+                   GNUNET_CONTAINER_multihashmap_put (rc->reserves,
                                                       &key,
                                                       rs,
                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
@@ -498,6 +657,16 @@ handle_reserve_out (void *cls,
                                      &rs->total_out,
                                      amount_with_fee));
   }
+  GNUNET_assert (rowid >= rs->a_last_reserve_out_serial_id);
+  rs->a_last_reserve_out_serial_id = rowid + 1;
+
+  TALER_amount_ntoh (&withdraw_fee,
+                     &dki->properties.fee_withdraw);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_add (&rs->total_fee,
+                                   &rs->total_fee,
+                                   &withdraw_fee));
+
   return GNUNET_OK;
 }
 
@@ -508,7 +677,7 @@ handle_reserve_out (void *cls,
  *
  * Remove all reserves that we are happy with from the DB.
  *
- * @param cls our `struct GNUNET_CONTAINER_MultiHashMap` with the reserves
+ * @param cls our `struct ReserveContext`
  * @param key hash of the reserve public key
  * @param value a `struct ReserveSummary`
  * @return #GNUNET_OK to process more entries
@@ -518,7 +687,7 @@ verify_reserve_balance (void *cls,
                         const struct GNUNET_HashCode *key,
                         void *value)
 {
-  struct GNUNET_CONTAINER_MultiHashMap *reserves = cls;
+  struct ReserveContext *rc = cls;
   struct ReserveSummary *rs = value;
   struct TALER_EXCHANGEDB_Reserve reserve;
   struct TALER_Amount balance;
@@ -542,13 +711,22 @@ verify_reserve_balance (void *cls,
     GNUNET_free (diag);
     return GNUNET_OK;
   }
-  /* TODO: check reserve.expiry */
 
-  /* FIXME: simplified computation as we have no previous reserve state yet */
-  /* FIXME: actually update withdraw fee balance, expiration data and serial 
IDs! */
+  if (GNUNET_OK !=
+      TALER_amount_add (&balance,
+                        &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");
+    goto cleanup;
+  }
+
   if (GNUNET_SYSERR ==
       TALER_amount_subtract (&balance,
-                             &rs->total_in,
+                             &balance,
                              &rs->total_out))
   {
     report_reserve_inconsistency (&rs->reserve_pub,
@@ -567,12 +745,55 @@ verify_reserve_balance (void *cls,
     goto cleanup;
   }
 
-  /* FIXME: if balance is zero, create reserve summary and drop reserve 
details! */
+  if (0 == GNUNET_TIME_absolute_get_remaining 
(rs->a_expiration_date).rel_value_us)
+  {
+    /* TODO: handle case where reserve is expired! (#4956) */
+    /* NOTE: we may or may not have seen the wire-back transfer at this time,
+       as the expiration may have just now happened.
+       (That is, after we add the table structures and the logic to track
+       such transfers...) */
+  }
+
+  if ( (0ULL == balance.value) &&
+       (0U == balance.fraction) )
+  {
+    /* TODO: balance is zero, drop reserve details (and then do not 
update/insert) */
+    if (rs->had_ri)
+    {
+      ret = adb->del_reserve_info (adb->cls,
+                                   asession,
+                                   &rs->reserve_pub,
+                                   &master_pub);
+      if (GNUNET_SYSERR == ret)
+      {
+        GNUNET_break (0);
+        goto cleanup;
+      }
+      if (GNUNET_NO == ret)
+      {
+        GNUNET_break (0);
+        ret = GNUNET_SYSERR;
+        goto cleanup;
+      }
+    }
+    ret = GNUNET_OK;
+    goto cleanup;
+  }
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Reserve balance `%s' OK\n",
               TALER_B2S (&rs->reserve_pub));
 
+  /* Add withdraw fees we encountered to totals */
+  if (GNUNET_YES !=
+      TALER_amount_add (&rs->a_withdraw_fee_balance,
+                        &rs->a_withdraw_fee_balance,
+                        &rs->total_fee))
+  {
+    GNUNET_break (0);
+    ret = GNUNET_SYSERR;
+    goto cleanup;
+  }
   if (rs->had_ri)
     ret = adb->update_reserve_info (adb->cls,
                                     asession,
@@ -594,10 +815,28 @@ verify_reserve_balance (void *cls,
                                     rs->a_last_reserve_in_serial_id,
                                     rs->a_last_reserve_out_serial_id);
 
+  if ( (GNUNET_YES !=
+        TALER_amount_add (&rc->total_balance,
+                          &rc->total_balance,
+                          &rs->total_in)) ||
+       (GNUNET_SYSERR ==
+        TALER_amount_subtract (&rc->total_balance,
+                               &rc->total_balance,
+                               &rs->total_out)) ||
+       (GNUNET_YES !=
+        TALER_amount_add (&rc->total_fee_balance,
+                          &rc->total_fee_balance,
+                          &rs->total_fee)) )
+  {
+    GNUNET_break (0);
+    ret = GNUNET_SYSERR;
+    goto cleanup;
+  }
+
 
  cleanup:
   GNUNET_assert (GNUNET_YES ==
-                 GNUNET_CONTAINER_multihashmap_remove (reserves,
+                 GNUNET_CONTAINER_multihashmap_remove (rc->reserves,
                                                        key,
                                                        rs));
   GNUNET_free (rs);
@@ -614,18 +853,29 @@ verify_reserve_balance (void *cls,
 static int
 analyze_reserves (void *cls)
 {
-  /* Map from hash of reserve's public key to a `struct ReserveSummary`. */
-  struct GNUNET_CONTAINER_MultiHashMap *reserves;
+  struct ReserveContext rc;
+  int ret;
+
+  ret = adb->get_reserve_summary (adb->cls,
+                                  asession,
+                                  &master_pub,
+                                  &rc.total_balance,
+                                  &rc.total_fee_balance);
+  if (GNUNET_SYSERR == ret)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
 
-  reserves = GNUNET_CONTAINER_multihashmap_create (512,
-                                                   GNUNET_NO);
+  rc.reserves = GNUNET_CONTAINER_multihashmap_create (512,
+                                                      GNUNET_NO);
 
   if (GNUNET_OK !=
       edb->select_reserves_in_above_serial_id (edb->cls,
                                                esession,
                                                reserve_in_serial_id,
                                                &handle_reserve_in,
-                                               reserves))
+                                               &rc))
     {
       GNUNET_break (0);
       return GNUNET_SYSERR;
@@ -635,18 +885,234 @@ analyze_reserves (void *cls)
                                                 esession,
                                                 reserve_out_serial_id,
                                                 &handle_reserve_out,
-                                                reserves))
+                                                &rc))
     {
       GNUNET_break (0);
       return GNUNET_SYSERR;
     }
-  GNUNET_CONTAINER_multihashmap_iterate (reserves,
+  /* TODO: iterate over table for reserve expiration refunds! (#4956) */
+
+  GNUNET_CONTAINER_multihashmap_iterate (rc.reserves,
                                          &verify_reserve_balance,
-                                         reserves);
+                                         &rc);
   GNUNET_break (0 ==
-                GNUNET_CONTAINER_multihashmap_size (reserves));
-  GNUNET_CONTAINER_multihashmap_destroy (reserves);
+                GNUNET_CONTAINER_multihashmap_size (rc.reserves));
+  GNUNET_CONTAINER_multihashmap_destroy (rc.reserves);
+
 
+  if (GNUNET_NO == ret)
+  {
+    ret = adb->insert_reserve_summary (adb->cls,
+                                       asession,
+                                       &master_pub,
+                                       &rc.total_balance,
+                                       &rc.total_fee_balance);
+  }
+  else
+  {
+    ret = adb->update_reserve_summary (adb->cls,
+                                       asession,
+                                       &master_pub,
+                                       &rc.total_balance,
+                                       &rc.total_fee_balance);
+  }
+  report_reserve_balance (&rc.total_balance,
+                          &rc.total_fee_balance);
+  return GNUNET_OK;
+}
+
+
+/* ************************* Analyze coins ******************** */
+/* This logic checks that the exchange did the right thing for each
+   coin, checking deposits, refunds, refresh* and known_coins
+   tables */
+
+/* TODO! */
+/**
+ * Summary data we keep per coin.
+ */
+struct CoinSummary
+{
+  /**
+   * Denomination of the coin with fee structure.
+   */
+  struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki;
+
+  /**
+   * Public key of the coin.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * Total value lost of the coin (deposits, refreshs and fees minus refunds).
+   * Must be smaller than the coin's total (origional) value.
+   */
+  struct TALER_Amount spent;
+
+};
+
+
+/**
+ * Summary data we keep per denomination.
+ */
+struct DenominationSummary
+{
+  /**
+   * Total value of coins issued with this denomination key.
+   */
+  struct TALER_Amount denom_balance;
+
+  /**
+   * Total amount of deposit fees made.
+   */
+  struct TALER_Amount deposit_fee_balance;
+
+  /**
+   * Total amount of melt fees made.
+   */
+  struct TALER_Amount melt_fee_balance;
+
+  /**
+   * Total amount of refund fees made.
+   */
+  struct TALER_Amount refund_fee_balance;
+
+  /**
+   * Up to which point have we processed reserves_out?
+   */
+  uint64_t last_reserve_out_serial_id;
+
+  /**
+   * Up to which point have we processed deposits?
+   */
+  uint64_t last_deposit_serial_id;
+
+  /**
+   * Up to which point have we processed melts?
+   */
+  uint64_t last_melt_serial_id;
+
+  /**
+   * Up to which point have we processed refunds?
+   */
+  uint64_t last_refund_serial_id;
+};
+
+
+/**
+ * Closure for callbacks during #analyze_coins().
+ */
+struct CoinContext
+{
+
+  /**
+   * Map for tracking information about coins.
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *coins;
+
+  /**
+   * Map for tracking information about denominations.
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *denominations;
+
+};
+
+
+/**
+ * Analyze the exchange's processing of coins.
+ *
+ * @param cls closure
+ * @param int #GNUNET_OK on success, #GNUNET_SYSERR on hard errors
+ */
+static int
+analyze_coins (void *cls)
+{
+  struct CoinContext cc;
+
+  cc.coins = GNUNET_CONTAINER_multihashmap_create (1024,
+                                                   GNUNET_YES);
+  cc.denominations = GNUNET_CONTAINER_multihashmap_create (256,
+                                                           GNUNET_YES);
+
+
+  GNUNET_CONTAINER_multihashmap_destroy (cc.denominations);
+  GNUNET_CONTAINER_multihashmap_destroy (cc.coins);
+
+  return GNUNET_OK;
+}
+
+
+/* ************************* Analyze merchants ******************** */
+/* This logic checks that the aggregator did the right thing
+   paying each merchant what they were due (and on time). */
+
+
+/**
+ * Summary data we keep per merchant.
+ */
+struct MerchantSummary
+{
+
+  /**
+   * Which account were we supposed to pay?
+   */
+  struct GNUNET_HashCode h_wire;
+
+  /**
+   * Total due to be paid to @e h_wire.
+   */
+  struct TALER_Amount total_due;
+
+  /**
+   * Total paid to @e h_wire.
+   */
+  struct TALER_Amount total_paid;
+
+  /**
+   * Total wire fees charged.
+   */
+  struct TALER_Amount total_fees;
+
+  /**
+   * Last (expired) refund deadline of all the transactions totaled
+   * up in @e due.
+   */
+  struct GNUNET_TIME_Absolute last_refund_deadline;
+
+};
+
+
+/**
+ * Closure for callbacks during #analyze_merchants().
+ */
+struct MerchantContext
+{
+
+  /**
+   * Map for tracking information about merchants.
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *merchants;
+
+};
+
+
+/**
+ * Analyze the exchange aggregator's payment processing.
+ *
+ * @param cls closure
+ * @param int #GNUNET_OK on success, #GNUNET_SYSERR on hard errors
+ */
+static int
+analyze_merchants (void *cls)
+{
+  struct MerchantContext mc;
+
+  mc.merchants = GNUNET_CONTAINER_multihashmap_create (1024,
+                                                       GNUNET_YES);
+
+  // TODO
+
+  GNUNET_CONTAINER_multihashmap_destroy (mc.merchants);
   return GNUNET_OK;
 }
 
@@ -835,7 +1301,10 @@ setup_sessions_and_run ()
 
   transact (&analyze_reserves,
             NULL);
-  // NOTE: add other 'transact (&analyze_*)'-calls here as they are 
implemented.
+  transact (&analyze_coins,
+            NULL);
+  transact (&analyze_merchants,
+            NULL);
 }
 
 
diff --git a/src/auditordb/plugin_auditordb_postgres.c 
b/src/auditordb/plugin_auditordb_postgres.c
index 81c1b43..65da0bf 100644
--- a/src/auditordb/plugin_auditordb_postgres.c
+++ b/src/auditordb/plugin_auditordb_postgres.c
@@ -649,6 +649,13 @@ postgres_prepare (PGconn *db_conn)
            " WHERE reserve_pub=$1 AND master_pub=$2;",
            2, NULL);
 
+  /* Used in #postgres_del_reserve_info() */
+  PREPARE ("auditor_reserves_delete",
+           "DELETE"
+           " FROM auditor_reserves"
+           " WHERE reserve_pub=$1 AND master_pub=$2;",
+           2, NULL);
+
   /* Used in #postgres_insert_reserve_summary() */
   PREPARE ("auditor_reserve_balance_insert",
            "INSERT INTO auditor_reserve_balance"
@@ -1651,6 +1658,47 @@ postgres_update_reserve_info (void *cls,
 
 
 /**
+ * Delete information about a reserve.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param session connection to use
+ * @param reserve_pub public key of the reserve
+ * @param master_pub master public key of the exchange
+ * @return #GNUNET_OK on success; #GNUNET_NO if there is no known
+ *         record about this reserve; #GNUNET_SYSERR on failure
+ */
+static int
+postgres_del_reserve_info (void *cls,
+                           struct TALER_AUDITORDB_Session *session,
+                           const struct TALER_ReservePublicKeyP *reserve_pub,
+                           const struct TALER_MasterPublicKeyP *master_pub)
+{
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (reserve_pub),
+    GNUNET_PQ_query_param_auto_from_type (master_pub),
+    GNUNET_PQ_query_param_end
+  };
+  PGresult *result;
+  int ret;
+
+  result = GNUNET_PQ_exec_prepared (session->conn,
+                                    "auditor_reserves_delete",
+                                    params);
+  ret = PQresultStatus (result);
+  if (PGRES_COMMAND_OK != ret)
+  {
+    BREAK_DB_ERR (result);
+    PQclear (result);
+    return GNUNET_SYSERR;
+  }
+  if (0 == strcmp ("0",
+                   PQcmdTuples (result)))
+    return GNUNET_NO;
+  return GNUNET_OK;
+}
+
+
+/**
  * Get information about a reserve.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
@@ -3110,6 +3158,7 @@ libtaler_plugin_auditordb_postgres_init (void *cls)
   plugin->update_auditor_progress = &postgres_update_auditor_progress;
   plugin->insert_auditor_progress = &postgres_insert_auditor_progress;
 
+  plugin->del_reserve_info = &postgres_del_reserve_info;
   plugin->get_reserve_info = &postgres_get_reserve_info;
   plugin->update_reserve_info = &postgres_update_reserve_info;
   plugin->insert_reserve_info = &postgres_insert_reserve_info;
diff --git a/src/include/taler_auditordb_plugin.h 
b/src/include/taler_auditordb_plugin.h
index c27295a..fa5f9e8 100644
--- a/src/include/taler_auditordb_plugin.h
+++ b/src/include/taler_auditordb_plugin.h
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2016 GNUnet e.V.
+  Copyright (C) 2014-2017 Inria and GNUnet e.V.
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -252,6 +252,10 @@ struct TALER_AUDITORDB_Plugin
                               void *cb_cls);
 
 
+  // FIXME: this does not quite work, as independent transactions
+  // touch certain tables (i.e. reserves_out), so we need some of
+  // these counters more than once!
+  // ALSO: put all of these counters into a struct, this is very ugly...
   /**
    * Insert information about the auditor's progress with an exchange's
    * data.
@@ -420,6 +424,22 @@ struct TALER_AUDITORDB_Plugin
                       uint64_t *last_reserve_out_serial_id);
 
 
+  /**
+   * Delete information about a reserve.
+   *
+   * @param cls the @e cls of this struct with the plugin-specific state
+   * @param session connection to use
+   * @param reserve_pub public key of the reserve
+   * @param master_pub master public key of the exchange
+   * @return #GNUNET_OK on success; #GNUNET_NO if there is no known
+   *         record about this reserve; #GNUNET_SYSERR on failure
+   */
+  int
+  (*del_reserve_info)(void *cls,
+                      struct TALER_AUDITORDB_Session *session,
+                      const struct TALER_ReservePublicKeyP *reserve_pub,
+                      const struct TALER_MasterPublicKeyP *master_pub);
+
 
   /**
    * Insert information about all reserves.  There must not be an
@@ -488,7 +508,7 @@ struct TALER_AUDITORDB_Plugin
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param session connection to use
    * @param denom_pub_hash hash of the denomination public key
-   * @param denom_balance value of coins outstanding with this denomination key
+   * @param denom_balance value of coins outstanding (or issued?) with this 
denomination key
    * @param deposit_fee_balance total deposit fees collected for this DK
    * @param melt_fee_balance total melt fees collected for this DK
    * @param refund_fee_balance total refund fees collected for this DK
@@ -523,7 +543,7 @@ struct TALER_AUDITORDB_Plugin
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param session connection to use
    * @param denom_pub_hash hash of the denomination public key
-   * @param denom_balance value of coins outstanding with this denomination key
+   * @param denom_balance value of coins outstanding (or issued?) with this 
denomination key
    * @param deposit_fee_balance total deposit fees collected for this DK
    * @param melt_fee_balance total melt fees collected for this DK
    * @param refund_fee_balance total refund fees collected for this DK
@@ -557,7 +577,7 @@ struct TALER_AUDITORDB_Plugin
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param session connection to use
    * @param denom_pub_hash hash of the denomination public key
-   * @param[out] denom_balance value of coins outstanding with this 
denomination key
+   * @param[out] denom_balance value of coins outstanding (or issued?) with 
this denomination key
    * @param[out] deposit_fee_balance total deposit fees collected for this DK
    * @param[out] melt_fee_balance total melt fees collected for this DK
    * @param[out] refund_fee_balance total refund fees collected for this DK

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]