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: handle /payback in


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: handle /payback in auditor when checking reserves
Date: Tue, 04 Apr 2017 15:39:01 +0200

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 4b82a59  handle /payback in auditor when checking reserves
4b82a59 is described below

commit 4b82a591c54bec9720181358c8230caa3759363f
Author: Christian Grothoff <address@hidden>
AuthorDate: Tue Apr 4 15:38:58 2017 +0200

    handle /payback in auditor when checking reserves
---
 src/auditor/taler-auditor.c                 | 118 +++++++++++-
 src/auditordb/plugin_auditordb_postgres.c   |  55 ++++--
 src/exchangedb/plugin_exchangedb_postgres.c | 282 +++++++++++++++++++++-------
 src/exchangedb/test_exchangedb.c            |   4 +-
 src/include/taler_auditordb_plugin.h        |  12 ++
 src/include/taler_exchangedb_plugin.h       |  50 ++++-
 6 files changed, 418 insertions(+), 103 deletions(-)

diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index c58a8b1..b884e64 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -800,6 +800,89 @@ handle_reserve_out (void *cls,
 
 
 /**
+ * Function called with details about withdraw operations.  Verifies
+ * the signature and updates the reserve's balance.
+ *
+ * @param cls our `struct ReserveContext`
+ * @param rowid unique serial ID for the refresh session in our DB
+ * @param timestamp when did we receive the payback request
+ * @param amount how much should be added back to the reserve
+ * @param reserve_pub public key of the reserve
+ * @param coin_pub public key of the coin
+ * @param coin_sig signature with @e coin_pub of type 
#TALER_SIGNATURE_WALLET_COIN_PAYBACK
+ * @param h_denom_pub hash of the denomination key of the coin
+ * @param coin_blind blinding factor used to blind the coin
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+static int
+handle_payback_by_reserve (void *cls,
+                           uint64_t rowid,
+                           struct GNUNET_TIME_Absolute timestamp,
+                           const struct TALER_Amount *amount,
+                           const struct TALER_ReservePublicKeyP *reserve_pub,
+                           const struct TALER_CoinSpendPublicKeyP *coin_pub,
+                           const struct TALER_CoinSpendSignatureP *coin_sig,
+                           const struct GNUNET_HashCode *h_denom_pub,
+                           const struct TALER_DenominationBlindingKeyP 
*coin_blind)
+{
+  struct ReserveContext *rc = cls;
+  struct GNUNET_HashCode key;
+  struct ReserveSummary *rs;
+  struct GNUNET_TIME_Absolute expiry;
+
+  /* should be monotonically increasing */
+  GNUNET_assert (rowid >= pp.last_reserve_payback_serial_id);
+  pp.last_reserve_payback_serial_id = rowid + 1;
+
+  GNUNET_CRYPTO_hash (reserve_pub,
+                      sizeof (*reserve_pub),
+                      &key);
+  rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
+                                          &key);
+  if (NULL == rs)
+  {
+    rs = GNUNET_new (struct ReserveSummary);
+    rs->reserve_pub = *reserve_pub;
+    rs->total_in = *amount;
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (amount->currency,
+                                          &rs->total_out));
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (amount->currency,
+                                          &rs->total_fee));
+    if (GNUNET_OK !=
+        load_auditor_reserve_summary (rs))
+    {
+      GNUNET_break (0);
+      GNUNET_free (rs);
+      return GNUNET_SYSERR;
+    }
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CONTAINER_multihashmap_put (rc->reserves,
+                                                      &key,
+                                                      rs,
+                                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+  }
+  else
+  {
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_add (&rs->total_in,
+                                     &rs->total_in,
+                                     amount));
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Additional /payback value to for reserve `%s' of %s\n",
+              TALER_B2S (reserve_pub),
+              TALER_amount2s (amount));
+  expiry = GNUNET_TIME_absolute_add (timestamp,
+                                     TALER_IDLE_RESERVE_EXPIRATION_TIME);
+  rs->a_expiration_date = GNUNET_TIME_absolute_max (rs->a_expiration_date,
+                                                    expiry);
+  return GNUNET_OK;
+}
+
+
+/**
  * Check that the reserve summary matches what the exchange database
  * thinks about the reserve, and update our own state of the reserve.
  *
@@ -1041,7 +1124,20 @@ analyze_reserves (void *cls)
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-  /* TODO: iterate over table for reserve expiration refunds! (#4956) */
+  if (GNUNET_SYSERR ==
+      edb->select_payback_above_serial_id (edb->cls,
+                                           esession,
+                                           pp.last_reserve_payback_serial_id,
+                                           &handle_payback_by_reserve,
+                                           &rc))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+
+
+  /* TODO: iterate over table for reserve expiration refunds! (#4956);
+     should use pp.last_reserve_close_serial_id */
 
   GNUNET_CONTAINER_multihashmap_iterate (rc.reserves,
                                          &verify_reserve_balance,
@@ -1774,8 +1870,9 @@ get_wire_fee (struct AggregationContext *ac,
  * @param wtid wire transfer subject
  * @param wire wire transfer details of the receiver
  * @param amount amount that was wired
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration
  */
-static void
+static int
 check_wire_out_cb (void *cls,
                    uint64_t rowid,
                    struct GNUNET_TIME_Absolute date,
@@ -1809,7 +1906,7 @@ check_wire_out_cb (void *cls,
     report_row_inconsistency ("wire_out",
                               rowid,
                               "specified wire address lacks type");
-    return;
+    return GNUNET_OK;
   }
   wcc.method = json_string_value (method);
   wcc.ok = GNUNET_OK;
@@ -1828,7 +1925,7 @@ check_wire_out_cb (void *cls,
     report_row_inconsistency ("wire_out",
                               rowid,
                               "audit of associated transactions failed");
-    return;
+    return GNUNET_OK;
   }
 
   /* Subtract aggregation fee from total */
@@ -1839,7 +1936,7 @@ check_wire_out_cb (void *cls,
   {
     GNUNET_break (0);
     ac->ret = GNUNET_SYSERR;
-    return;
+    return GNUNET_SYSERR;
   }
   if (GNUNET_SYSERR ==
       TALER_amount_subtract (&final_amount,
@@ -1849,7 +1946,7 @@ check_wire_out_cb (void *cls,
     report_row_inconsistency ("wire_out",
                               rowid,
                               "could not subtract wire fee from total amount");
-    return;
+    return GNUNET_OK;
   }
 
   /* Round down to amount supported by wire method */
@@ -1860,7 +1957,7 @@ check_wire_out_cb (void *cls,
     report_row_inconsistency ("wire_out",
                               rowid,
                               "could not load required wire plugin to 
validate");
-    return;
+    return GNUNET_OK;
   }
 
   if (GNUNET_SYSERR ==
@@ -1880,7 +1977,7 @@ check_wire_out_cb (void *cls,
   {
     GNUNET_break (0);
     ac->ret = GNUNET_SYSERR;
-    return;
+    return GNUNET_SYSERR;
   }
 
   /* Sum up aggregation fees (we simply include the rounding gains) */
@@ -1891,7 +1988,7 @@ check_wire_out_cb (void *cls,
   {
     GNUNET_break (0);
     ac->ret = GNUNET_SYSERR;
-    return;
+    return GNUNET_SYSERR;
   }
 
   /* Check that calculated amount matches actual amount */
@@ -1903,11 +2000,12 @@ check_wire_out_cb (void *cls,
                                    &final_amount,
                                    amount,
                                    "computed amount inconsistent with wire 
amount");
-    return;
+    return GNUNET_OK;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Wire transfer %s is OK\n",
               TALER_B2S (wtid));
+  return GNUNET_OK;
 }
 
 
diff --git a/src/auditordb/plugin_auditordb_postgres.c 
b/src/auditordb/plugin_auditordb_postgres.c
index 3807639..b68708f 100644
--- a/src/auditordb/plugin_auditordb_postgres.c
+++ b/src/auditordb/plugin_auditordb_postgres.c
@@ -301,6 +301,8 @@ postgres_create_tables (void *cls)
           "(master_pub BYTEA PRIMARY KEY CHECK (LENGTH(master_pub)=32)"
           ",last_reserve_in_serial_id INT8 NOT NULL"
            ",last_reserve_out_serial_id INT8 NOT NULL"
+           ",last_reserve_payback_serial_id INT8 NOT NULL"
+           ",last_reserve_close_serial_id INT8 NOT NULL"
            ",last_withdraw_serial_id INT8 NOT NULL"
           ",last_deposit_serial_id INT8 NOT NULL"
            ",last_melt_serial_id INT8 NOT NULL"
@@ -575,32 +577,38 @@ postgres_prepare (PGconn *db_conn)
           "(master_pub"
           ",last_reserve_in_serial_id"
            ",last_reserve_out_serial_id"
+           ",last_reserve_payback_serial_id"
+           ",last_reserve_close_serial_id"
           ",last_withdraw_serial_id"
           ",last_deposit_serial_id"
            ",last_melt_serial_id"
           ",last_refund_serial_id"
           ",last_wire_out_serial_id"
-           ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8);",
-           8, NULL);
+           ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);",
+           10, NULL);
 
   /* Used in #postgres_update_auditor_progress() */
   PREPARE ("auditor_progress_update",
            "UPDATE auditor_progress SET "
           " last_reserve_in_serial_id=$1"
            ",last_reserve_out_serial_id=$2"
-          ",last_withdraw_serial_id=$3"
-          ",last_deposit_serial_id=$4"
-           ",last_melt_serial_id=$5"
-          ",last_refund_serial_id=$6"
-          ",last_wire_out_serial_id=$7"
-           " WHERE master_pub=$8",
-           8, NULL);
+           ",last_reserve_payback_serial_id=$3"
+           ",last_reserve_close_serial_id=$4"
+          ",last_withdraw_serial_id=$5"
+          ",last_deposit_serial_id=$6"
+           ",last_melt_serial_id=$7"
+          ",last_refund_serial_id=$8"
+          ",last_wire_out_serial_id=$9"
+           " WHERE master_pub=$10",
+           10, NULL);
 
   /* Used in #postgres_get_auditor_progress() */
   PREPARE ("auditor_progress_select",
            "SELECT"
           " last_reserve_in_serial_id"
            ",last_reserve_out_serial_id"
+           ",last_reserve_payback_serial_id"
+           ",last_reserve_close_serial_id"
           ",last_withdraw_serial_id"
           ",last_deposit_serial_id"
            ",last_melt_serial_id"
@@ -1310,6 +1318,8 @@ postgres_insert_auditor_progress (void *cls,
     GNUNET_PQ_query_param_auto_from_type (master_pub),
     GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id),
     GNUNET_PQ_query_param_uint64 (&pp->last_reserve_out_serial_id),
+    GNUNET_PQ_query_param_uint64 (&pp->last_reserve_payback_serial_id),
+    GNUNET_PQ_query_param_uint64 (&pp->last_reserve_close_serial_id),
     GNUNET_PQ_query_param_uint64 (&pp->last_withdraw_serial_id),
     GNUNET_PQ_query_param_uint64 (&pp->last_deposit_serial_id),
     GNUNET_PQ_query_param_uint64 (&pp->last_melt_serial_id),
@@ -1356,6 +1366,8 @@ postgres_update_auditor_progress (void *cls,
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id),
     GNUNET_PQ_query_param_uint64 (&pp->last_reserve_out_serial_id),
+    GNUNET_PQ_query_param_uint64 (&pp->last_reserve_payback_serial_id),
+    GNUNET_PQ_query_param_uint64 (&pp->last_reserve_close_serial_id),
     GNUNET_PQ_query_param_uint64 (&pp->last_withdraw_serial_id),
     GNUNET_PQ_query_param_uint64 (&pp->last_deposit_serial_id),
     GNUNET_PQ_query_param_uint64 (&pp->last_melt_serial_id),
@@ -1405,13 +1417,24 @@ postgres_get_auditor_progress (void *cls,
   };
   PGresult *result;
   struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_uint64 ("last_reserve_in_serial_id", 
&pp->last_reserve_in_serial_id),
-    GNUNET_PQ_result_spec_uint64 ("last_reserve_out_serial_id", 
&pp->last_reserve_out_serial_id),
-    GNUNET_PQ_result_spec_uint64 ("last_withdraw_serial_id", 
&pp->last_withdraw_serial_id),
-    GNUNET_PQ_result_spec_uint64 ("last_deposit_serial_id", 
&pp->last_deposit_serial_id),
-    GNUNET_PQ_result_spec_uint64 ("last_melt_serial_id", 
&pp->last_melt_serial_id),
-    GNUNET_PQ_result_spec_uint64 ("last_refund_serial_id", 
&pp->last_refund_serial_id),
-    GNUNET_PQ_result_spec_uint64 ("last_wire_out_serial_id", 
&pp->last_wire_out_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_reserve_in_serial_id",
+                                  &pp->last_reserve_in_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_reserve_out_serial_id",
+                                  &pp->last_reserve_out_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_reserve_payback_serial_id",
+                                  &pp->last_reserve_payback_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_reserve_close_serial_id",
+                                  &pp->last_reserve_out_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_withdraw_serial_id",
+                                  &pp->last_withdraw_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_deposit_serial_id",
+                                  &pp->last_deposit_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_melt_serial_id",
+                                  &pp->last_melt_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_refund_serial_id",
+                                  &pp->last_refund_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_wire_out_serial_id",
+                                  &pp->last_wire_out_serial_id),
     GNUNET_PQ_result_spec_end
   };
 
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index e869bcd..498b848 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -515,7 +515,8 @@ postgres_create_tables (void *cls)
 
   /* Table for /payback information */
   SQLEXEC("CREATE TABLE IF NOT EXISTS payback "
-          "(reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON 
DELETE CASCADE"
+          "(payback_uuid BIGSERIAL"
+          ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON 
DELETE CASCADE"
           ",coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)"
           ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)"
           ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)"
@@ -1418,6 +1419,26 @@ postgres_prepare (PGconn *db_conn)
            "($1, $2, $3, $4, $5, $6, $7, $8, $9)",
            9, NULL);
 
+  /* Used in #postgres_select_payback_above_serial_id() to obtain payback 
transactions */
+  PREPARE ("payback_get_incr",
+           "SELECT"
+           " payback_uuid"
+           ",timestamp"
+           ",reserve_pub"
+           ",coin_pub"
+           ",coin_sig"
+           ",coin_blind"
+           ",h_blind_ev"
+           ",denom.denom_pub"
+           ",amount_val"
+           ",amount_frac"
+           ",amount_curr"
+           " FROM payback"
+           "    JOIN reserves_out denom USING (reserve_pub,h_blind_ev)"
+           " WHERE payback_uuid>=$1"
+           " ORDER BY payback_uuid ASC",
+           1, NULL);
+
   /* Used in #postgres_get_reserve_history() to obtain payback transactions
      for a reserve */
   PREPARE ("payback_by_reserve",
@@ -5057,7 +5078,7 @@ postgres_select_deposits_above_serial_id (void *cls,
     return GNUNET_SYSERR;
   }
   int nrows;
-  int i;
+  int ret;
 
   nrows = PQntuples (result);
   if (0 == nrows)
@@ -5067,7 +5088,7 @@ postgres_select_deposits_above_serial_id (void *cls,
     PQclear (result);
     return GNUNET_NO;
   }
-  for (i=0;i<nrows;i++)
+  for (int i=0;i<nrows;i++)
   {
     struct TALER_EXCHANGEDB_Deposit deposit;
     struct TALER_DenominationPublicKey denom_pub;
@@ -5109,20 +5130,22 @@ postgres_select_deposits_above_serial_id (void *cls,
       PQclear (result);
       return GNUNET_SYSERR;
     }
-    cb (cb_cls,
-        rowid,
-        deposit.timestamp,
-        &deposit.merchant_pub,
-        &denom_pub,
-        &deposit.coin.coin_pub,
-        &deposit.csig,
-        &deposit.amount_with_fee,
-        &deposit.h_proposal_data,
-        deposit.refund_deadline,
-        deposit.wire_deadline,
-        deposit.receiver_wire_account,
-        done);
+    ret = cb (cb_cls,
+              rowid,
+              deposit.timestamp,
+              &deposit.merchant_pub,
+              &denom_pub,
+              &deposit.coin.coin_pub,
+              &deposit.csig,
+              &deposit.amount_with_fee,
+              &deposit.h_proposal_data,
+              deposit.refund_deadline,
+              deposit.wire_deadline,
+              deposit.receiver_wire_account,
+              done);
     GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
   }
   PQclear (result);
   return GNUNET_OK;
@@ -5153,6 +5176,10 @@ postgres_select_refreshs_above_serial_id (void *cls,
     GNUNET_PQ_query_param_end
   };
   PGresult *result;
+  int nrows;
+  int i;
+  int ret;
+
   result = GNUNET_PQ_exec_prepared (session->conn,
                                     "audit_get_refresh_sessions_incr",
                                     params);
@@ -5164,8 +5191,6 @@ postgres_select_refreshs_above_serial_id (void *cls,
     PQclear (result);
     return GNUNET_SYSERR;
   }
-  int nrows;
-  int i;
 
   nrows = PQntuples (result);
   if (0 == nrows)
@@ -5215,16 +5240,18 @@ postgres_select_refreshs_above_serial_id (void *cls,
       PQclear (result);
       return GNUNET_SYSERR;
     }
-    cb (cb_cls,
-        rowid,
-        &denom_pub,
-        &coin_pub,
-        &coin_sig,
-        &amount_with_fee,
-        num_newcoins,
-        noreveal_index,
-        &session_hash);
+    ret = cb (cb_cls,
+              rowid,
+              &denom_pub,
+              &coin_pub,
+              &coin_sig,
+              &amount_with_fee,
+              num_newcoins,
+              noreveal_index,
+              &session_hash);
     GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
   }
   PQclear (result);
   return GNUNET_OK;
@@ -5255,6 +5282,9 @@ postgres_select_refunds_above_serial_id (void *cls,
     GNUNET_PQ_query_param_end
   };
   PGresult *result;
+  int nrows;
+  int ret;
+
   result = GNUNET_PQ_exec_prepared (session->conn,
                                     "audit_get_refunds_incr",
                                     params);
@@ -5265,8 +5295,6 @@ postgres_select_refunds_above_serial_id (void *cls,
     PQclear (result);
     return GNUNET_SYSERR;
   }
-  int nrows;
-  int i;
 
   nrows = PQntuples (result);
   if (0 == nrows)
@@ -5276,7 +5304,7 @@ postgres_select_refunds_above_serial_id (void *cls,
     PQclear (result);
     return GNUNET_NO;
   }
-  for (i=0;i<nrows;i++)
+  for (int i=0;i<nrows;i++)
   {
     struct TALER_EXCHANGEDB_Refund refund;
     struct TALER_DenominationPublicKey denom_pub;
@@ -5310,16 +5338,18 @@ postgres_select_refunds_above_serial_id (void *cls,
       PQclear (result);
       return GNUNET_SYSERR;
     }
-    cb (cb_cls,
-        rowid,
-        &denom_pub,
-        &refund.coin.coin_pub,
-        &refund.merchant_pub,
-        &refund.merchant_sig,
-        &refund.h_proposal_data,
-        refund.rtransaction_id,
-        &refund.refund_amount);
+    ret = cb (cb_cls,
+              rowid,
+              &denom_pub,
+              &refund.coin.coin_pub,
+              &refund.merchant_pub,
+              &refund.merchant_sig,
+              &refund.h_proposal_data,
+              refund.rtransaction_id,
+              &refund.refund_amount);
     GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
   }
   PQclear (result);
   return GNUNET_OK;
@@ -5361,7 +5391,7 @@ postgres_select_reserves_in_above_serial_id (void *cls,
     return GNUNET_SYSERR;
   }
   int nrows;
-  int i;
+  int ret;
 
   nrows = PQntuples (result);
   if (0 == nrows)
@@ -5372,7 +5402,7 @@ postgres_select_reserves_in_above_serial_id (void *cls,
     return GNUNET_NO;
   }
 
-  for (i=0;i<nrows;i++)
+  for (int i=0;i<nrows;i++)
   {
     struct TALER_ReservePublicKeyP reserve_pub;
     struct TALER_Amount credit;
@@ -5406,14 +5436,16 @@ postgres_select_reserves_in_above_serial_id (void *cls,
       PQclear (result);
       return GNUNET_SYSERR;
     }
-    cb (cb_cls,
-        rowid,
-        &reserve_pub,
-        &credit,
-        sender_account_details,
-        transfer_details,
-        execution_date);
+    ret = cb (cb_cls,
+              rowid,
+              &reserve_pub,
+              &credit,
+              sender_account_details,
+              transfer_details,
+              execution_date);
     GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
   }
 
   PQclear (result);
@@ -5457,7 +5489,7 @@ postgres_select_reserves_out_above_serial_id (void *cls,
     return GNUNET_SYSERR;
   }
   int nrows;
-  int i;
+  int ret;
 
   nrows = PQntuples (result);
   if (0 == nrows)
@@ -5467,7 +5499,7 @@ postgres_select_reserves_out_above_serial_id (void *cls,
     PQclear (result);
     return GNUNET_NO;
   }
-  for (i=0;i<nrows;i++)
+  for (int i=0;i<nrows;i++)
   {
     struct GNUNET_HashCode h_blind_ev;
     struct TALER_DenominationPublicKey denom_pub;
@@ -5506,16 +5538,18 @@ postgres_select_reserves_out_above_serial_id (void *cls,
       PQclear (result);
       return GNUNET_SYSERR;
     }
-    cb (cb_cls,
-        rowid,
-        &h_blind_ev,
-        &denom_pub,
-        &denom_sig,
-        &reserve_pub,
-        &reserve_sig,
-        execution_date,
-        &amount_with_fee);
+    ret = cb (cb_cls,
+              rowid,
+              &h_blind_ev,
+              &denom_pub,
+              &denom_sig,
+              &reserve_pub,
+              &reserve_sig,
+              execution_date,
+              &amount_with_fee);
     GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
   }
 
   PQclear (result);
@@ -5548,6 +5582,9 @@ postgres_select_wire_out_above_serial_id (void *cls,
     GNUNET_PQ_query_param_end
   };
   PGresult *result;
+  int nrows;
+  int ret;
+
   result = GNUNET_PQ_exec_prepared (session->conn,
                                     "audit_get_wire_incr",
                                     params);
@@ -5558,7 +5595,6 @@ postgres_select_wire_out_above_serial_id (void *cls,
     PQclear (result);
     return GNUNET_SYSERR;
   }
-  int nrows;
 
   nrows = PQntuples (result);
   if (0 == nrows)
@@ -5600,13 +5636,126 @@ postgres_select_wire_out_above_serial_id (void *cls,
       return GNUNET_SYSERR;
     }
 
-    cb (cb_cls,
-        rowid,
-        date,
-        &wtid,
-        wire,
-        &amount);
+    ret = cb (cb_cls,
+              rowid,
+              date,
+              &wtid,
+              wire,
+              &amount);
+    GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
+  }
+
+  PQclear (result);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Function called to select payback requests the exchange
+ * received, ordered by serial ID (monotonically increasing).
+ *
+ * @param cls closure
+ * @param session database connection
+ * @param serial_id lowest serial ID to include (select larger or equal)
+ * @param cb function to call for ONE unfinished item
+ * @param cb_cls closure for @a cb
+ * @return #GNUNET_OK on success,
+ *         #GNUNET_NO if there are no entries,
+ *         #GNUNET_SYSERR on DB errors
+ */
+static int
+postgres_select_payback_above_serial_id (void *cls,
+                                         struct TALER_EXCHANGEDB_Session 
*session,
+                                         uint64_t serial_id,
+                                         TALER_EXCHANGEDB_PaybackCallback cb,
+                                         void *cb_cls)
+{
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_end
+  };
+  PGresult *result;
+  result = GNUNET_PQ_exec_prepared (session->conn,
+                                    "payback_get_incr",
+                                    params);
+  if (PGRES_TUPLES_OK !=
+      PQresultStatus (result))
+  {
+    BREAK_DB_ERR (result, session->conn);
+    PQclear (result);
+    return GNUNET_SYSERR;
+  }
+  int nrows;
+  int ret;
+
+  nrows = PQntuples (result);
+  if (0 == nrows)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "select_prepare_above_serial_id() returned 0 matching rows\n");
+    PQclear (result);
+    return GNUNET_NO;
+  }
+  for (int i=0;i<nrows;i++)
+  {
+    uint64_t rowid;
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_CoinSpendSignatureP coin_sig;
+    struct TALER_DenominationBlindingKeyP coin_blind;
+    struct TALER_Amount amount;
+    struct GNUNET_HashCode h_blind_ev;
+    struct GNUNET_TIME_Absolute timestamp;
+    struct TALER_DenominationPublicKey denom_pub;
+    struct GNUNET_HashCode h_denom_pub;
+
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_uint64 ("payback_uuid",
+                                    &rowid),
+      GNUNET_PQ_result_spec_absolute_time ("timestamp",
+                                           &timestamp),
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                            &reserve_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+                                            &coin_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+                                            &coin_sig),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+                                            &coin_blind),
+      GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
+                                            &h_blind_ev),
+      GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+                                            &denom_pub.rsa_public_key),
+      TALER_PQ_result_spec_amount ("amount",
+                                   &amount),
+      GNUNET_PQ_result_spec_end
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      PQclear (result);
+      return GNUNET_SYSERR;
+    }
+    GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key,
+                                       &h_denom_pub);
+    ret = cb (cb_cls,
+              rowid,
+              timestamp,
+              &amount,
+              &reserve_pub,
+              &coin_pub,
+              &coin_sig,
+              &h_denom_pub,
+              &coin_blind);
     GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
   }
 
   PQclear (result);
@@ -5868,6 +6017,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
   plugin->select_reserves_in_above_serial_id = 
&postgres_select_reserves_in_above_serial_id;
   plugin->select_reserves_out_above_serial_id = 
&postgres_select_reserves_out_above_serial_id;
   plugin->select_wire_out_above_serial_id = 
&postgres_select_wire_out_above_serial_id;
+  plugin->select_payback_above_serial_id = 
&postgres_select_payback_above_serial_id;
   plugin->insert_payback_request = &postgres_insert_payback_request;
   plugin->get_reserve_by_h_blind = &postgres_get_reserve_by_h_blind;
   return plugin;
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index e8fd211..49cc643 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -1205,8 +1205,9 @@ static  struct TALER_Amount wire_out_amount;
  * @param wtid wire transfer subject
  * @param wire wire transfer details of the receiver
  * @param amount amount that was wired
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration
  */
-static void
+static int
 audit_wire_cb (void *cls,
                uint64_t rowid,
                struct GNUNET_TIME_Absolute date,
@@ -1223,6 +1224,7 @@ audit_wire_cb (void *cls,
                          &wire_out_wtid,
                          sizeof (*wtid)));
   GNUNET_assert (date.abs_value_us == wire_out_date.abs_value_us);
+  return GNUNET_OK;
 }
 
 
diff --git a/src/include/taler_auditordb_plugin.h 
b/src/include/taler_auditordb_plugin.h
index 031df58..170a68f 100644
--- a/src/include/taler_auditordb_plugin.h
+++ b/src/include/taler_auditordb_plugin.h
@@ -122,6 +122,18 @@ struct TALER_AUDITORDB_ProgressPoint
   uint64_t last_reserve_out_serial_id;
 
   /**
+   * last_payback_serial_id serial ID of the last payback entry the auditor 
processed when
+   * considering reserves.
+   */
+  uint64_t last_reserve_payback_serial_id;
+
+  /**
+   * last_reserve_close_serial_id serial ID of the last reserve_close
+   * entry the auditor processed.
+   */
+  uint64_t last_reserve_close_serial_id;
+
+  /**
    * last_reserve_out_serial_id serial ID of the last withdraw the auditor 
processed
    */
   uint64_t last_withdraw_serial_id;
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 322a305..f6d78ab 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -875,8 +875,9 @@ typedef void
  * @param wtid wire transfer subject
  * @param wire wire transfer details of the receiver
  * @param amount amount that was wired
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration
  */
-typedef void
+typedef int
 (*TALER_EXCHANGEDB_WireTransferOutCallback)(void *cls,
                                             uint64_t rowid,
                                             struct GNUNET_TIME_Absolute date,
@@ -894,8 +895,9 @@ typedef void
  * @param buf transaction data that was persisted, NULL on error
  * @param buf_size number of bytes in @a buf, 0 on error
  * @param finished did we complete the transfer yet?
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration
  */
-typedef void
+typedef int
 (*TALER_EXCHANGEDB_WirePreparationCallback)(void *cls,
                                             uint64_t rowid,
                                             const char *wire_method,
@@ -909,18 +911,25 @@ typedef void
  *
  * @param cls closure
  * @param rowid row identifier used to uniquely identify the payback operation
- * @param deadline by when did we promise the payment
- * @param receiver_account_details to whom do we need to send the funds
- * @param amount how much should be transferred
- * @param wire_subject what should be the wire subject
+ * @param timestamp when did we receive the payback request
+ * @param amount how much should be added back to the reserve
+ * @param reserve_pub public key of the reserve
+ * @param coin_pub public key of the coin
+ * @param coin_sig signature with @e coin_pub of type 
#TALER_SIGNATURE_WALLET_COIN_PAYBACK
+ * @param h_denom_pub hash of the denomination key of the coin
+ * @param coin_blind blinding factor used to blind the coin
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
  */
-typedef void
+typedef int
 (*TALER_EXCHANGEDB_PaybackCallback)(void *cls,
                                     uint64_t rowid,
-                                    struct GNUNET_TIME_Absolute deadline,
-                                    const json_t *receiver_account_details,
+                                    struct GNUNET_TIME_Absolute timestamp,
                                     const struct TALER_Amount *amount,
-                                    const struct 
TALER_WireTransferIdentifierRawP *wtid);
+                                    const struct TALER_ReservePublicKeyP 
*reserve_pub,
+                                    const struct TALER_CoinSpendPublicKeyP 
*coin_pub,
+                                    const struct TALER_CoinSpendSignatureP 
*coin_sig,
+                                    const struct GNUNET_HashCode *h_denom_pub,
+                                    const struct 
TALER_DenominationBlindingKeyP *coin_blind);
 
 
 /**
@@ -1940,6 +1949,27 @@ struct TALER_EXCHANGEDB_Plugin
 
 
   /**
+   * Function called to select payback requests the exchange
+   * received, ordered by serial ID (monotonically increasing).
+   *
+   * @param cls closure
+   * @param session database connection
+   * @param serial_id lowest serial ID to include (select larger or equal)
+   * @param cb function to call for ONE unfinished item
+   * @param cb_cls closure for @a cb
+   * @return #GNUNET_OK on success,
+   *         #GNUNET_NO if there are no entries,
+   *         #GNUNET_SYSERR on DB errors
+   */
+  int
+  (*select_payback_above_serial_id)(void *cls,
+                                    struct TALER_EXCHANGEDB_Session *session,
+                                    uint64_t serial_id,
+                                    TALER_EXCHANGEDB_PaybackCallback cb,
+                                    void *cb_cls);
+
+
+  /**
    * Function called to add a request for an emergency payback for a
    * coin.  The funds are to be added back to the reserve.  The
    * function should return the @a deadline by which the exchange will

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



reply via email to

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