gnunet-svn
[Top][All Lists]
Advanced

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

[taler-donau] 01/03: [donau][donaudb] work on issue receipts


From: gnunet
Subject: [taler-donau] 01/03: [donau][donaudb] work on issue receipts
Date: Wed, 27 Mar 2024 10:44:29 +0100

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

lukas-matyja pushed a commit to branch master
in repository donau.

commit 62a0e09bcaefc51e543ae44ea59049e5ec60e353
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
AuthorDate: Wed Mar 27 10:40:44 2024 +0100

    [donau][donaudb] work on issue receipts
---
 src/donau/Makefile.am                      |   2 +-
 src/donau/donau-httpd.c                    |  16 +-
 src/donau/donau-httpd_keys.h               |  20 ++
 src/donau/donau-httpd_post-batch-issue.c   | 161 ++++++---
 src/donaudb/0002-donau_receipts_issued.sql |  27 +-
 src/donaudb/pg_insert_issued_receipt.c     |  61 ++--
 src/donaudb/pg_insert_issued_receipt.h     |  13 +-
 src/donaudb/pg_lookup_issued_receipts.c    |  14 +-
 src/donaudb/pg_lookup_issued_receipts.h    |   2 +-
 src/donaudb/plugin_auditordb_postgres.c    | 558 +++++++++++++++++++++++++++++
 src/include/donau_crypto_lib.h             |  25 +-
 src/include/donau_json_lib.h               |  30 ++
 src/include/donau_pq_lib.h                 |  39 +-
 src/include/donaudb_plugin.h               |  94 ++---
 14 files changed, 918 insertions(+), 144 deletions(-)

diff --git a/src/donau/Makefile.am b/src/donau/Makefile.am
index ad3eed3..6e8b3a0 100644
--- a/src/donau/Makefile.am
+++ b/src/donau/Makefile.am
@@ -48,8 +48,8 @@ donau_httpd_SOURCES = \
   donau-httpd_get-charity.c donau-httpd_post-charity.c \
   donau-httpd_get-history.c \
   donau-httpd_post-submit-receipts.c donau_httpd_submit-receipts.h \
-  donau-httpd_post-batch-issue.c donau_httpd_batch-issue.h \
   donau-httpd_terms.c donau-httpd_terms.h
+  #donau-httpd_post-batch-issue.c donau_httpd_batch-issue.h 
 
 # Testcases
 
diff --git a/src/donau/donau-httpd.c b/src/donau/donau-httpd.c
index 21bed5c..74796c4 100644
--- a/src/donau/donau-httpd.c
+++ b/src/donau/donau-httpd.c
@@ -54,7 +54,7 @@
  * Above what request latency do we start to log?
  */
  #define WARN_LATENCY GNUNET_TIME_relative_multiply ( \
-           GNUNET_TIME_UNIT_MILLISECONDS, 500)
+    GNUNET_TIME_UNIT_MILLISECONDS, 500)
 
 /**
  * Are clients allowed to request /keys for times other than the
@@ -498,13 +498,13 @@ handle_mhd_request (void *cls,
       .nargs_is_upper_bound = true
     },
     /* POST batch issue receipts */
-    {
-      .url = "batch-issue",
-      .method = MHD_HTTP_METHOD_POST,
-      .handler.post = &DH_handler_issue_receipts_post,
-      .nargs = 1,
-      .nargs_is_upper_bound = true
-    },
+    // {
+    //   .url = "batch-issue",
+    //   .method = MHD_HTTP_METHOD_POST,
+    //   .handler.post = &DH_handler_issue_receipts_post,
+    //   .nargs = 1,
+    //   .nargs_is_upper_bound = true
+    // },
     /**
     etc
 
diff --git a/src/donau/donau-httpd_keys.h b/src/donau/donau-httpd_keys.h
index c978765..09de95e 100644
--- a/src/donau/donau-httpd_keys.h
+++ b/src/donau/donau-httpd_keys.h
@@ -173,6 +173,26 @@ MHD_RESULT
 DH_handler_keys (struct DH_RequestContext *rc,
                  const char *const args[]);
 
+
+// TODO: Implement
+/**
+ * Look up the issue for a donation unit public key.  Note that the result
+ * must only be used in this thread and only until another key or
+ * key state is resolved.
+ *
+ * @param h_du_pub hash of donation unit public key
+ * @param[in,out] conn used to return status message if NULL is returned
+ * @param[out] mret set to the MHD status if NULL is returned
+ * @return the donation unit key issue,
+ *         or NULL if @a h_du_pub could not be found
+ */
+struct DH_DonationUnitKey *
+DH_keys_donation_unit_by_hash (
+  const struct DONAU_DonationUnitHashP *h_du_pub,
+  struct MHD_Connection *conn,
+  MHD_RESULT *mret);
+
+
 /**
  * Initialize keys subsystem.
  *
diff --git a/src/donau/donau-httpd_post-batch-issue.c 
b/src/donau/donau-httpd_post-batch-issue.c
index 217d247..2be89eb 100644
--- a/src/donau/donau-httpd_post-batch-issue.c
+++ b/src/donau/donau-httpd_post-batch-issue.c
@@ -31,6 +31,8 @@
 #include "donau-httpd_batch-issue.h"
 #include "donau-httpd_db.h"
 #include "donau-httpd_metrics.h"
+#include "donau_json_lib.h"
+#include "donau-httpd_keys.h"
 
 
 /**
@@ -59,7 +61,7 @@ parse_json_bkp (struct 
DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp,
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("h_du_pub",
                                  &bkp->h_donation_unit_pub),
-    GNUNET_JSON_spec_fixed_auto ("blinded_udi",
+    DONAU_JSON_spec_blinded_udi ("blinded_udi",
                                  &bkp->blinded_udi),
     GNUNET_JSON_spec_end ()
   };
@@ -72,9 +74,11 @@ parse_json_bkp (struct 
DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
+  /* TODO: Check for duplicate blinded UDIs.*/
   return GNUNET_OK;
 }
 
+
 /**
  * Parse signatures to JSON.
  *
@@ -85,23 +89,25 @@ parse_json_bkp (struct 
DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp,
  * is malformed.
  */
 void
-signatures_to_JSON(const unsigned int num_sig,
-                          struct DONAU_BlindedDonationUnitSignature* 
signatures[num_sig],
-                                  json_t *j_signatures)
+signatures_to_JSON (const unsigned int num_sig,
+                    struct DONAU_BlindedDonationUnitSignature*signatures,
+                    json_t *j_signatures)
 {
-       int i = 0;
-       while (i < num_sig)
-       {
-         GNUNET_assert (
-           0 == json_array_append (
-                       j_signatures,
-             GNUNET_JSON_PACK (
-               GNUNET_JSON_pack_data_auto ("du_sig",
-                                             signatures[i]))));
-         i++;
-       }
+  int i = 0;
+  while (i < num_sig)
+  {
+    struct DONAU_BlindedDonationUnitSignature*signature = &signatures[i];
+    GNUNET_assert (
+      0 == json_array_append (
+        j_signatures,
+        GNUNET_JSON_PACK (
+          DONAU_JSON_pack_blinded_donation_unit_sig ("blinded_signatures",
+                                                     signature))));
+    i++;
+  }
 }
 
+
 MHD_RESULT
 DH_handler_issue_receipts_post (struct DH_RequestContext *rc,
                                 const json_t *root,
@@ -160,7 +166,7 @@ DH_handler_issue_receipts_post (struct DH_RequestContext 
*rc,
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "parse some values!");
   /* parse the budikeypairs array */
-  const uint64_t num_bkp
+  const size_t num_bkp
     = json_array_size (budikeypairs);
   if (0 != num_bkp)
   {
@@ -243,15 +249,19 @@ DH_handler_issue_receipts_post (struct DH_RequestContext 
*rc,
   /* request already made? -> idempotent */
   enum GNUNET_DB_QueryStatus qs_check_receipts;
   struct DONAUDB_IssuedReceiptsMetaData check_receipts_meta;
-  struct DONAU_BudiKeyPairsHashP bkp_hash;
+  struct DONAU_DonationReceiptHashP h_receipts = {0};
   json_t *blind_signatures = json_array ();
 
-  GNUNET_CRYPTO_hash (irc.bkp,
-                      sizeof (irc.bkp[0]) * num_bkp,
-                      &bkp_hash.hash);
-
+  for (int i = 0; i < num_bkp; i++)
+  {
+    struct GNUNET_HashCode temp_hash;
+    GNUNET_CRYPTO_hash (irc.bkp,
+                        sizeof (irc.bkp[0].blinded_udi) * num_bkp,
+                        &temp_hash);
+    GNUNET_CRYPTO_hash_xor (&h_receipts.hash, &temp_hash, &h_receipts.hash);
+  }
   qs_check_receipts = DH_plugin->lookup_issued_receipts (DH_plugin->cls,
-                                                         bkp_hash,
+                                                         h_receipts,
                                                          &check_receipts_meta);
   switch (qs_check_receipts)
   {
@@ -269,39 +279,96 @@ DH_handler_issue_receipts_post (struct DH_RequestContext 
*rc,
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "request have been made already!");
-    signatures_to_JSON(num_bkp, check_receipts_meta.blinded_sig, 
blind_signatures);
-//    return TALER_MHD_REPLY_JSON_PACK (
-//      rc->connection,
-//      MHD_HTTP_OK,
-//      GNUNET_JSON_pack_array_steal ("blind_signatures",
-//                                    blind_signatures));
-    break;
+    signatures_to_JSON (num_bkp, check_receipts_meta.blinded_sig,
+                        blind_signatures);
+    return TALER_MHD_REPLY_JSON_PACK (
+      rc->connection,
+      MHD_HTTP_OK,
+      GNUNET_JSON_pack_array_steal ("blind_signatures",
+                                    blind_signatures));
   }
-  /* check annual limit and change it -> Rollback if we could not save the 
request*/
-  /* save Request (charity signature, charity id, amount, hash over bkps) and 
make it idempotent*/
-  /* sign budis and send the signatures back */
-  int i = 0;
-  struct DONAU_BlindedDonationUnitSignature **du_sig;
-  while(i < num_bkp)
+  /* calculate new receipts to date and check annual limit */
+  struct TALER_Amount receipts_sum;
+  for (int i = 0; i < num_bkp; i++)
   {
-    // TODO: get donation unit private key
-    const struct DONAU_DonationUnitPrivateKey du_priv;
-    const struct DONAU_BlindedUniqueDonationIdentifier budi = irc.bkp[i].
-                                                            blinded_udi;
-    if (GNUNET_SYSERR == TALER_donation_unit_sign_blinded (du_sig[i], 
&du_priv, &
-                                                         budi)) {
-      GNUNET_break (0);
+    MHD_RESULT mret;
+    struct DH_DonationUnitKey *dk;
+    dk = DH_keys_donation_unit_by_hash (&irc.bkp[i].h_donation_unit_pub,
+                                        rc->connection,
+                                        &mret);
+    if (NULL == dk || 0 >= TALER_amount_add (&receipts_sum, &receipts_sum,
+                                             &dk->value))
       return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_BAD_REQUEST,
+                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                                         "budikeypairs");
+  }
+  struct TALER_Amount new_receipts_to_date;
+  TALER_amount_add (&new_receipts_to_date, &receipts_sum,
+                    &charity_meta.receipts_to_date);
+  // new_receipts_to_date has to be smaller or equal as max_per_year
+  if (0 > TALER_amount_cmp (&new_receipts_to_date, &charity_meta.max_per_year))
+    return TALER_MHD_reply_with_error (rc->connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,// 
TODO: other EC
+                                       "budikeypairs");
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "calculated the new receipts to date amount");
+
+  /* sign budis and send the signatures back */
+  struct DONAU_BlindedDonationUnitSignature *du_sigs = {0};
+  {
+    int i = 0;
+    while (i < num_bkp)
+    {
+      // TODO: get donation unit private key
+      const struct DONAU_DonationUnitPrivateKey du_priv;
+      const struct DONAU_BlindedUniqueDonationIdentifier budi = irc.bkp[i].
+                                                                blinded_udi;
+      struct DONAU_BlindedDonationUnitSignature *du_sig = &du_sigs[i];
+      if (GNUNET_SYSERR == TALER_donation_unit_sign_blinded (du_sig, &du_priv, 
&
+                                                             budi))
+      {
+        GNUNET_break (0);
+        return TALER_MHD_reply_with_error (rc->connection,
+                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                           TALER_EC_GENERIC_DB_FETCH_FAILED, 
// TODO:other EC
+                                           NULL);
+
+      }
+      i++;
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "made blind signatures!");
+  }
+  /* save new receipts to date and save receipts Request (blinded signatures,
+   * charity id, amount, hash over bkps) to make it idempotent*/
+  enum GNUNET_DB_QueryStatus qs_insert_ir;
+  qs_insert_ir = DH_plugin->insert_issued_receipt (
+    DH_plugin->cls,
+    num_bkp,
+    du_sigs,
+    (uint64_t) charity_id,
+    &h_receipts,
+    &receipts_sum,
+    &new_receipts_to_date);
+  switch (qs_insert_ir)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return TALER_MHD_reply_with_error (rc->connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
                                        NULL);
-
-    }
-    i++;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+  case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+    break;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "made blind signatures!");
-  signatures_to_JSON(num_bkp, du_sig, blind_signatures);
+              "issue receipts request is saved! (idempotent)");
+
+  signatures_to_JSON (num_bkp, du_sigs, blind_signatures);
   return TALER_MHD_REPLY_JSON_PACK (
     rc->connection,
     MHD_HTTP_OK,
diff --git a/src/donaudb/0002-donau_receipts_issued.sql 
b/src/donaudb/0002-donau_receipts_issued.sql
index 4f76fdb..f8f8ecd 100644
--- a/src/donaudb/0002-donau_receipts_issued.sql
+++ b/src/donaudb/0002-donau_receipts_issued.sql
@@ -23,7 +23,32 @@ CREATE TABLE receipts_issued
   );
 COMMENT ON TABLE receipts_issued
   IS 'Table containing the issued blinded donation receipts to the charity.';
-COMMENT ON COLUMN receipts_issued.charity_sig
+COMMENT ON COLUMN receipts_issued.blinded_sig
   IS 'Signature from the charity.';
 COMMENT ON COLUMN receipts_issued.receipt_hash
   IS 'Hash value over all the blinded donation receipt received plus the hash 
of the donation units public key.';
+
+
+CREATE FUNCTION 
transaction_update_current_amount_receipts_save_issue_receipts_request(
+   IN blinded_sig BYTEA[] NOT NULL -- blinded signatures
+  ,IN charity_id BIGINT NOT NULL -- charity id which made the issue receitps 
request
+  ,IN receipt_hash BYTEA NOT NULL-- hash over all budi key pairs (primary key)
+  ,IN amount taler_amount NOT NULL -- total amount of the requested receipts
+  ,IN new_total_amount NOT NULL -- new total amount of a charity
+)
+RETURNS VOID
+--LANGUAGE plpgsql
+AS $$
+BEGIN;
+
+-- Update table charity
+UPDATE charity SET receipts_to_date = new_total_amount;
+-- Insert into the table receipts_issued
+INSERT INTO receipts_issued (blinded_sig, charity_id, receipt_hash, amount) 
VALUES ('blinded_sig', 'charity_id', 'receipts_hash', 'amount');
+
+-- Commit the transaction if everything is successful
+COMMIT;
+END $$;
+
+COMMENT ON FUNCTION transaction_save_issue_receipts_request
+  IS 'This is a transaction for updating the current amount of receipts of a 
year of a charity and saves the receipts request what makes it idempotent';
diff --git a/src/donaudb/pg_insert_issued_receipt.c 
b/src/donaudb/pg_insert_issued_receipt.c
index fbcb45a..c1f3b29 100644
--- a/src/donaudb/pg_insert_issued_receipt.c
+++ b/src/donaudb/pg_insert_issued_receipt.c
@@ -17,7 +17,9 @@
  * @file donaudb/pg_insert_issed_receipt.c
  * @brief Implementation of the insert_issued_receipt function for Postgres
  * @author Johannes Casaburi
+ * @author Lukas Matyja
  */
+#include <gnunet/gnunet_pq_lib.h>
 #include <taler/platform.h>
 #include <taler/taler_error_codes.h>
 #include <taler/taler_dbevents.h>
@@ -25,34 +27,53 @@
 #include "pg_insert_issued_receipt.h"
 #include "pg_helper.h"
 #include "donau_service.h"
+#include "donau_pq_lib.h"
 
 enum GNUNET_DB_QueryStatus
 DH_PG_insert_issued_receipt (void *cls,
-                             const struct DONAU_CharitySignatureP *charity_sig,
+                             const size_t num_blinded_sig,
+                             const struct
+                             DONAU_BlindedDonationUnitSignature *signatures,
                              const uint64_t charity_id,
                              const struct DONAU_DonationReceiptHashP 
*h_receipt,
-                             const struct TALER_Amount *amount)
+                             const struct TALER_Amount 
*amount_receipts_request,
+                             const struct TALER_Amount *charity_new_amount)
 {
-  struct PostgresClosure *pg = cls;
+  struct PostgresClosure *pc = cls;
+  enum GNUNET_GenericReturnValue ret = GNUNET_OK;
+  // struct GNUNET_PQ_Context *conn;
   struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_auto_from_type (charity_sig),
+    DONAU_PQ_query_param_array_blinded_donation_unit_sig (num_blinded_sig,
+                                                          signatures, 
pc->conn),
     GNUNET_PQ_query_param_uint64 (&charity_id),
-    GNUNET_PQ_query_param_auto_from_type (h_receipt),
-    TALER_PQ_query_param_amount (pg->conn,
-                                 amount),
+    GNUNET_PQ_query_param_fixed_size (&h_receipt->hash, sizeof(struct
+                                                               
DONAU_DonationReceiptHashP)),
+    TALER_PQ_query_param_amount_with_currency (pc->conn,
+                                               amount_receipts_request),
+    TALER_PQ_query_param_amount_with_currency (pc->conn, charity_new_amount),
     GNUNET_PQ_query_param_end
   };
-
-  PREPARE (pg,
-           "insert_issued_receipts",
-           "INSERT INTO receipts_issued "
-           "(charity_sig"
-           ",charity_id"
-           ",h_receipt"
-           ",amount"
-           ") VALUES "
-           "($1, $2, $3, $4);");
-  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "insert_issued_receipt",
-                                             params);
+  PREPARE (pc,
+           "donation_unit_insert",
+           "SELECT"
+           " 
receipts_issued.transaction_update_current_amount_receipts_save_issue_receipts_request"
+           " ($1, $2, $3, $4, $5);");
+  if (0 >
+      GNUNET_PQ_eval_prepared_non_select (pc->conn,
+                                          
"transaction_update_current_amount_receipts_save_issue_receipts_request",
+                                          params))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Failed to run 
'transaction_update_current_amount_receipts_save_issue_receipts_request' 
prepared statement\n");
+    ret = GNUNET_SYSERR;
+  }
+  if (GNUNET_OK == ret)
+  {
+    ret = GNUNET_PQ_exec_sql (pc->conn,
+                              "procedures");
+    if (GNUNET_OK != ret)
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Failed to load stored procedures\n");
+  }
+  return ret;
 }
diff --git a/src/donaudb/pg_insert_issued_receipt.h 
b/src/donaudb/pg_insert_issued_receipt.h
index 781f283..4089e1d 100644
--- a/src/donaudb/pg_insert_issued_receipt.h
+++ b/src/donaudb/pg_insert_issued_receipt.h
@@ -29,17 +29,22 @@
  * Insert issued blinded donation receipt to the charity.
  *
  * @param cls closure
- * @param charity_sig signature from the charity
+ * @param num_blinded_sig
+ * @param signatures blinded signatures
  * @param charity_id identifier of the charity
  * @param h_receipt hash of the donation receipt
- * @param amount donation amount
+ * @param amount_receipts_request donation amount
+ * @param charity_new_amount new current receipts amount of the charity
  * @return transaction status code
  */
 enum GNUNET_DB_QueryStatus
 DH_PG_insert_issued_receipt (void *cls,
-                             const struct DONAU_CharitySignatureP *charity_sig,
+                             const size_t num_blinded_sig,
+                             const struct
+                             DONAU_BlindedDonationUnitSignature *signatures,
                              const uint64_t charity_id,
                              const struct DONAU_DonationReceiptHashP 
*h_receipt,
-                             const struct TALER_Amount *amount);
+                             const struct TALER_Amount 
*amount_receipts_request,
+                             const struct TALER_Amount *charity_new_amount);
 
 #endif
diff --git a/src/donaudb/pg_lookup_issued_receipts.c 
b/src/donaudb/pg_lookup_issued_receipts.c
index 3e341ff..8d77448 100644
--- a/src/donaudb/pg_lookup_issued_receipts.c
+++ b/src/donaudb/pg_lookup_issued_receipts.c
@@ -24,21 +24,25 @@
 #include <taler/taler_pq_lib.h>
 #include "pg_lookup_issued_receipts.h"
 #include "pg_helper.h"
+#include "donau_pq_lib.h"
 
 enum GNUNET_DB_QueryStatus
 DH_PG_lookup_issued_receipts (
   void *cls,
-  struct DONAU_BudiKeyPairsHashP bkp_hash,
+  struct DONAU_DonationReceiptHashP h_receipts,
   struct DONAUDB_IssuedReceiptsMetaData *meta)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_auto_from_type (&bkp_hash),
+    GNUNET_PQ_query_param_auto_from_type (&h_receipts),
     GNUNET_PQ_query_param_end
   };
   struct GNUNET_PQ_ResultSpec rs[] = {
-//    GNUNET_PQ_result_spec_auto_from_type ("blinded_sig",
-//                                          &meta->blinded_sig),
+    DONAU_PQ_result_spec_array_blinded_donation_unit_sig (
+      pg->conn,
+      "blinded_sig",
+      &meta->num_sig,
+      &meta->blinded_sig),
     TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
                                  &meta->amount),
     GNUNET_PQ_result_spec_uint64 ("charity_id",
@@ -49,7 +53,7 @@ DH_PG_lookup_issued_receipts (
   PREPARE (pg,
            "lookup_issued_receipts",
            "SELECT "
-           /*" charity_sig"*/
+           " blinded_sig"
            " ,amount"
            " ,charity_id"
            " FROM receipts_issued"
diff --git a/src/donaudb/pg_lookup_issued_receipts.h 
b/src/donaudb/pg_lookup_issued_receipts.h
index a527ea5..a23c071 100644
--- a/src/donaudb/pg_lookup_issued_receipts.h
+++ b/src/donaudb/pg_lookup_issued_receipts.h
@@ -34,6 +34,6 @@
 enum GNUNET_DB_QueryStatus
 DH_PG_lookup_issued_receipts (
   void *cls,
-  struct DONAU_BudiKeyPairsHashP bkp_hash,
+  struct DONAU_DonationReceiptHashP h_receipts,
   struct DONAUDB_IssuedReceiptsMetaData *meta);
 #endif
diff --git a/src/donaudb/plugin_auditordb_postgres.c 
b/src/donaudb/plugin_auditordb_postgres.c
new file mode 100644
index 0000000..f5c405d
--- /dev/null
+++ b/src/donaudb/plugin_auditordb_postgres.c
@@ -0,0 +1,558 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2024 Taler Systems SA
+
+  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
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file plugin_auditordb_postgres.c
+ * @brief Low-level (statement-level) Postgres database access for the auditor
+ * @author Christian Grothoff
+ * @author Gabor X Toth
+ */
+#include "platform.h"
+#include "taler_pq_lib.h"
+#include <pthread.h>
+#include <libpq-fe.h>
+#include "pg_delete_deposit_confirmations.h"
+#include "pg_delete_pending_deposit.h"
+#include "pg_delete_purse_info.h"
+#include "pg_del_denomination_balance.h"
+#include "pg_del_reserve_info.h"
+#include "pg_get_auditor_progress.h"
+#include "pg_get_balance.h"
+#include "pg_get_denomination_balance.h"
+#include "pg_get_deposit_confirmations.h"
+#include "pg_get_purse_info.h"
+#include "pg_get_reserve_info.h"
+#include "pg_get_wire_fee_summary.h"
+#include "pg_helper.h"
+#include "pg_insert_auditor_progress.h"
+#include "pg_insert_balance.h"
+#include "pg_insert_denomination_balance.h"
+#include "pg_insert_deposit_confirmation.h"
+#include "pg_insert_exchange_signkey.h"
+#include "pg_insert_historic_denom_revenue.h"
+#include "pg_insert_historic_reserve_revenue.h"
+#include "pg_insert_pending_deposit.h"
+#include "pg_insert_purse_info.h"
+#include "pg_insert_reserve_info.h"
+#include "pg_select_historic_denom_revenue.h"
+#include "pg_select_historic_reserve_revenue.h"
+#include "pg_select_pending_deposits.h"
+#include "pg_select_purse_expired.h"
+#include "pg_update_auditor_progress.h"
+#include "pg_update_balance.h"
+#include "pg_update_denomination_balance.h"
+#include "pg_update_purse_info.h"
+#include "pg_update_reserve_info.h"
+#include "pg_update_wire_fee_summary.h"
+
+
+#define LOG(kind,...) GNUNET_log_from (kind, "taler-auditordb-postgres", \
+                                       __VA_ARGS__)
+
+
+/**
+ * Drop all auditor tables OR deletes recoverable auditor state.
+ * This should only be used by testcases or when restarting the
+ * auditor from scratch.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param drop_exchangelist drop all tables, including schema versioning
+ *        and the exchange and deposit_confirmations table; NOT to be
+ *        used when restarting the auditor
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
+ */
+static enum GNUNET_GenericReturnValue
+postgres_drop_tables (void *cls,
+                      bool drop_exchangelist)
+{
+  struct PostgresClosure *pc = cls;
+  struct GNUNET_PQ_Context *conn;
+  enum GNUNET_GenericReturnValue ret;
+
+  conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+                                     "auditordb-postgres",
+                                     NULL,
+                                     NULL,
+                                     NULL);
+  if (NULL == conn)
+    return GNUNET_SYSERR;
+  ret = GNUNET_PQ_exec_sql (conn,
+                            (drop_exchangelist) ? "drop" : "restart");
+  GNUNET_PQ_disconnect (conn);
+  return ret;
+}
+
+
+/**
+ * Create the necessary tables if they are not present
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param support_partitions true to support partitioning
+ * @param num_partitions number of partitions to use
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
+ */
+static enum GNUNET_GenericReturnValue
+postgres_create_tables (void *cls,
+                        bool support_partitions,
+                        uint32_t num_partitions)
+{
+  struct PostgresClosure *pc = cls;
+  enum GNUNET_GenericReturnValue ret = GNUNET_OK;
+  struct GNUNET_PQ_Context *conn;
+  struct GNUNET_PQ_QueryParam params[] = {
+    support_partitions
+    ? GNUNET_PQ_query_param_uint32 (&num_partitions)
+    : GNUNET_PQ_query_param_null (),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_PreparedStatement ps[] = {
+    GNUNET_PQ_make_prepare ("create_tables",
+                            "SELECT"
+                            " auditor.do_create_tables"
+                            " ($1);"),
+    GNUNET_PQ_PREPARED_STATEMENT_END
+  };
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+                                     "auditordb-postgres",
+                                     "auditor-",
+                                     es,
+                                     ps);
+  if (NULL == conn)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Failed to connect to database\n");
+    return GNUNET_SYSERR;
+  }
+  if (0 >
+      GNUNET_PQ_eval_prepared_non_select (conn,
+                                          "create_tables",
+                                          params))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Failed to run 'create_tables' prepared statement\n");
+    ret = GNUNET_SYSERR;
+  }
+  if (GNUNET_OK == ret)
+  {
+    ret = GNUNET_PQ_exec_sql (conn,
+                              "procedures");
+    if (GNUNET_OK != ret)
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Failed to load stored procedures\n");
+  }
+  GNUNET_PQ_disconnect (conn);
+  return ret;
+}
+
+
+/**
+ * Register callback to be invoked on events of type @a es.
+ *
+ * @param cls database context to use
+ * @param es specification of the event to listen for
+ * @param timeout how long to wait for the event
+ * @param cb function to call when the event happens, possibly
+ *         mulrewardle times (until cancel is invoked)
+ * @param cb_cls closure for @a cb
+ * @return handle useful to cancel the listener
+ */
+static struct GNUNET_DB_EventHandler *
+postgres_event_listen (void *cls,
+                       const struct GNUNET_DB_EventHeaderP *es,
+                       struct GNUNET_TIME_Relative timeout,
+                       GNUNET_DB_EventCallback cb,
+                       void *cb_cls)
+{
+  struct PostgresClosure *pg = cls;
+
+  return GNUNET_PQ_event_listen (pg->conn,
+                                 es,
+                                 timeout,
+                                 cb,
+                                 cb_cls);
+}
+
+
+/**
+ * Stop notifications.
+ *
+ * @param eh handle to unregister.
+ */
+static void
+postgres_event_listen_cancel (struct GNUNET_DB_EventHandler *eh)
+{
+  GNUNET_PQ_event_listen_cancel (eh);
+}
+
+
+/**
+ * Notify all that listen on @a es of an event.
+ *
+ * @param cls database context to use
+ * @param es specification of the event to generate
+ * @param extra additional event data provided
+ * @param extra_size number of bytes in @a extra
+ */
+static void
+postgres_event_notify (void *cls,
+                       const struct GNUNET_DB_EventHeaderP *es,
+                       const void *extra,
+                       size_t extra_size)
+{
+  struct PostgresClosure *pg = cls;
+
+  return GNUNET_PQ_event_notify (pg->conn,
+                                 es,
+                                 extra,
+                                 extra_size);
+}
+
+
+/**
+ * Connect to the db if the connection does not exist yet.
+ *
+ * @param[in,out] pg the plugin-specific state
+ * @return #GNUNET_OK on success
+ */
+static enum GNUNET_GenericReturnValue
+setup_connection (struct PostgresClosure *pg)
+{
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+  struct GNUNET_PQ_Context *db_conn;
+
+  if (NULL != pg->conn)
+  {
+    GNUNET_PQ_reconnect_if_down (pg->conn);
+    return GNUNET_OK;
+  }
+  db_conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
+                                        "auditordb-postgres",
+                                        NULL,
+                                        es,
+                                        NULL);
+  if (NULL == db_conn)
+    return GNUNET_SYSERR;
+  pg->conn = db_conn;
+  pg->prep_gen++;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Do a pre-flight check that we are not in an uncommitted transaction.
+ * If we are, rollback the previous transaction and output a warning.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @return #GNUNET_OK on success,
+ *         #GNUNET_NO if we rolled back an earlier transaction
+ *         #GNUNET_SYSERR if we have no DB connection
+ */
+static enum GNUNET_GenericReturnValue
+postgres_preflight (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("ROLLBACK"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  if (NULL == pg->conn)
+  {
+    if (GNUNET_OK !=
+        setup_connection (pg))
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+  }
+  if (NULL == pg->transaction_name)
+    return GNUNET_OK; /* all good */
+  if (GNUNET_OK ==
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check rolled back transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check failed to rollback transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  pg->transaction_name = NULL;
+  return GNUNET_NO;
+}
+
+
+/**
+ * Start a transaction.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @return #GNUNET_OK on success
+ */
+static enum GNUNET_GenericReturnValue
+postgres_start (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  postgres_preflight (cls);
+  if (GNUNET_OK !=
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    TALER_LOG_ERROR ("Failed to start transaction\n");
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Roll back the current transaction of a database connection.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ */
+static void
+postgres_rollback (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("ROLLBACK"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  GNUNET_break (GNUNET_OK ==
+                GNUNET_PQ_exec_statements (pg->conn,
+                                           es));
+}
+
+
+/**
+ * Commit the current transaction of a database connection.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+postgres_commit (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_end
+  };
+
+  PREPARE (pg,
+           "do_commit",
+           "COMMIT");
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "do_commit",
+                                             params);
+}
+
+
+/**
+ * Function called to perform "garbage collection" on the
+ * database, expiring records we no longer require.
+ *
+ * @param cls closure
+ * @return #GNUNET_OK on success,
+ *         #GNUNET_SYSERR on DB errors
+ */
+static enum GNUNET_GenericReturnValue
+postgres_gc (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_TIME_Absolute now = {0};
+  struct GNUNET_PQ_QueryParam params_time[] = {
+    GNUNET_PQ_query_param_absolute_time (&now),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_Context *conn;
+  enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_PQ_PreparedStatement ps[] = {
+    GNUNET_PQ_PREPARED_STATEMENT_END
+  };
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  now = GNUNET_TIME_absolute_get ();
+  conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
+                                     "auditordb-postgres",
+                                     NULL,
+                                     es,
+                                     ps);
+  if (NULL == conn)
+    return GNUNET_SYSERR;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "TODO: Auditor GC not implemented (#4960)\n");
+  qs = GNUNET_PQ_eval_prepared_non_select (conn,
+                                           "gc_auditor",
+                                           params_time);
+  GNUNET_PQ_disconnect (conn);
+  if (0 > qs)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Initialize Postgres database subsystem.
+ *
+ * @param cls a configuration instance
+ * @return NULL on error, otherwise a `struct TALER_AUDITORDB_Plugin`
+ */
+void *
+libtaler_plugin_auditordb_postgres_init (void *cls)
+{
+  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+  struct PostgresClosure *pg;
+  struct TALER_AUDITORDB_Plugin *plugin;
+
+  pg = GNUNET_new (struct PostgresClosure);
+  pg->cfg = cfg;
+  if (GNUNET_OK !=
+      TALER_config_get_currency (cfg,
+                                 &pg->currency))
+  {
+    GNUNET_free (pg);
+    return NULL;
+  }
+  plugin = GNUNET_new (struct TALER_AUDITORDB_Plugin);
+  plugin->cls = pg;
+  plugin->preflight = &postgres_preflight;
+  plugin->drop_tables = &postgres_drop_tables;
+  plugin->create_tables = &postgres_create_tables;
+  plugin->event_listen = &postgres_event_listen;
+  plugin->event_listen_cancel = &postgres_event_listen_cancel;
+  plugin->event_notify = &postgres_event_notify;
+  plugin->start = &postgres_start;
+  plugin->commit = &postgres_commit;
+  plugin->rollback = &postgres_rollback;
+  plugin->gc = &postgres_gc;
+
+  plugin->get_auditor_progress
+    = &TAH_PG_get_auditor_progress;
+  plugin->get_balance
+    = &TAH_PG_get_balance;
+  plugin->insert_auditor_progress
+    = &TAH_PG_insert_auditor_progress;
+  plugin->insert_balance
+    = &TAH_PG_insert_balance;
+  plugin->update_auditor_progress
+    = &TAH_PG_update_auditor_progress;
+  plugin->update_balance
+    = &TAH_PG_update_balance;
+
+  plugin->insert_exchange_signkey
+    = &TAH_PG_insert_exchange_signkey;
+  plugin->insert_deposit_confirmation
+    = &TAH_PG_insert_deposit_confirmation;
+  plugin->get_deposit_confirmations
+    = &TAH_PG_get_deposit_confirmations;
+  plugin->delete_deposit_confirmation
+    = &TAH_PG_delete_deposit_confirmation;
+
+  plugin->insert_reserve_info
+    = &TAH_PG_insert_reserve_info;
+  plugin->update_reserve_info
+    = &TAH_PG_update_reserve_info;
+  plugin->get_reserve_info
+    = &TAH_PG_get_reserve_info;
+  plugin->del_reserve_info
+    = &TAH_PG_del_reserve_info;
+
+  plugin->insert_pending_deposit
+    = &TAH_PG_insert_pending_deposit;
+  plugin->select_pending_deposits
+    = &TAH_PG_select_pending_deposits;
+  plugin->delete_pending_deposit
+    = &TAH_PG_delete_pending_deposit;
+
+  plugin->insert_purse_info
+    = &TAH_PG_insert_purse_info;
+  plugin->update_purse_info
+    = &TAH_PG_update_purse_info;
+  plugin->get_purse_info
+    = &TAH_PG_get_purse_info;
+  plugin->delete_purse_info
+    = &TAH_PG_delete_purse_info;
+  plugin->select_purse_expired
+    = &TAH_PG_select_purse_expired;
+
+  plugin->insert_denomination_balance
+    = &TAH_PG_insert_denomination_balance;
+  plugin->update_denomination_balance
+    = &TAH_PG_update_denomination_balance;
+  plugin->del_denomination_balance
+    = &TAH_PG_del_denomination_balance;
+  plugin->get_denomination_balance
+    = &TAH_PG_get_denomination_balance;
+
+  plugin->insert_historic_denom_revenue
+    = &TAH_PG_insert_historic_denom_revenue;
+  plugin->select_historic_denom_revenue
+    = &TAH_PG_select_historic_denom_revenue;
+
+  plugin->insert_historic_reserve_revenue
+    = &TAH_PG_insert_historic_reserve_revenue;
+  plugin->select_historic_reserve_revenue
+    = &TAH_PG_select_historic_reserve_revenue;
+
+  return plugin;
+}
+
+
+/**
+ * Shutdown Postgres database subsystem.
+ *
+ * @param cls a `struct TALER_AUDITORDB_Plugin`
+ * @return NULL (always)
+ */
+void *
+libtaler_plugin_auditordb_postgres_done (void *cls)
+{
+  struct TALER_AUDITORDB_Plugin *plugin = cls;
+  struct PostgresClosure *pg = plugin->cls;
+
+  if (NULL != pg->conn)
+    GNUNET_PQ_disconnect (pg->conn);
+  GNUNET_free (pg->currency);
+  GNUNET_free (pg);
+  GNUNET_free (plugin);
+  return NULL;
+}
+
+
+/* end of plugin_auditordb_postgres.c */
diff --git a/src/include/donau_crypto_lib.h b/src/include/donau_crypto_lib.h
index 36373be..59d424d 100644
--- a/src/include/donau_crypto_lib.h
+++ b/src/include/donau_crypto_lib.h
@@ -279,10 +279,10 @@ struct DONAU_BlindedUniqueDonationIdentifierKeyPair
 /**
  * Hash of a budikeypair array
  */
-struct DONAU_BudiKeyPairsHashP
-{
-  struct GNUNET_HashCode hash;
-};
+// struct DONAU_BudiKeyPairsHashP
+// {
+//   struct GNUNET_HashCode hash;
+// };
 
 /**
  * Hash of a budikeypair array
@@ -393,9 +393,12 @@ DONAU_blinded_donation_unit_sig_free (
  * @return #GNUNET_OK on success
  */
 enum GNUNET_GenericReturnValue
-TALER_donation_unit_sign_blinded (struct DONAU_BlindedDonationUnitSignature 
*du_sig,
-                          const struct DONAU_DonationUnitPrivateKey *du_priv,
-                          const struct DONAU_BlindedUniqueDonationIdentifier 
*budi);
+TALER_donation_unit_sign_blinded (struct
+                                  DONAU_BlindedDonationUnitSignature *du_sig,
+                                  const struct
+                                  DONAU_DonationUnitPrivateKey *du_priv,
+                                  const struct
+                                  DONAU_BlindedUniqueDonationIdentifier *budi);
 
 
 /**
@@ -408,9 +411,11 @@ TALER_donation_unit_sign_blinded (struct 
DONAU_BlindedDonationUnitSignature *du_
  * @return #GNUNET_OK if the signature is valid
  */
 enum GNUNET_GenericReturnValue
-TALER_donation_unit_pub_verify (const struct DONAU_DonationUnitPublicKey 
*du_pub,
-                        const struct DONAU_DonationUnitSignature *du_sig,
-                        const struct DONAU_BudiHashP *budi_hash);
+TALER_donation_unit_pub_verify (const struct
+                                DONAU_DonationUnitPublicKey *du_pub,
+                                const struct
+                                DONAU_DonationUnitSignature *du_sig,
+                                const struct DONAU_BudiHashP *budi_hash);
 
 
 // FIXME: Copied from taler_crypto_lib.h, is anything of this necessary?
diff --git a/src/include/donau_json_lib.h b/src/include/donau_json_lib.h
index 7d8f7d1..43503b9 100644
--- a/src/include/donau_json_lib.h
+++ b/src/include/donau_json_lib.h
@@ -59,6 +59,21 @@ DONAU_JSON_spec_donation_unit_group (const char *field,
                                      const char *currency,
                                      struct DONAU_DonationUnitGroup *group);
 
+// TODO: Implement (like exchange TALER_JSON_spec_blinded_planchet method)
+/**
+ * Generate line in parser specification for a
+ * blinded unique identifier.
+ *
+ * @param field name of the field
+ * @param[out] blinded_udi the blinded unique identifier to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+DONAU_JSON_spec_blinded_udi (const char *field,
+                             struct DONAU_BlindedUniqueDonationIdentifier *
+                             blinded_udi);
+
+
 /**
  * Generate packer instruction for a JSON field of type
  * unsigned integer.
@@ -84,4 +99,19 @@ DONAU_JSON_pack_donation_unit_pub (
   const char *name,
   const struct DONAU_DonationUnitPublicKey *pk);
 
+// TODO: implement
+/**
+ * Generate packer instruction for a JSON field of type
+ * blinded donation unit signature (that needs to be
+ * unblinded before it becomes valid).
+ *
+ * @param name name of the field to add to the object
+ * @param sig signature
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+DONAU_JSON_pack_blinded_donation_unit_sig (
+  const char *name,
+  const struct DONAU_BlindedDonationUnitSignature *sig);
+
 #endif
diff --git a/src/include/donau_pq_lib.h b/src/include/donau_pq_lib.h
index 6a6399e..a11412e 100644
--- a/src/include/donau_pq_lib.h
+++ b/src/include/donau_pq_lib.h
@@ -16,7 +16,8 @@
 /**
  * @file include/donau_pq_lib.h
  * @brief helper functions for DB interactions
- * @author Johannes Casaburi>
+ * @author Johannes Casaburi
+ * @author Lukas Matyja
  */
 #ifndef DONAU_PQ_LIB_H_
 #define DONAU_PQ_LIB_H_
@@ -37,6 +38,23 @@ struct GNUNET_PQ_QueryParam
 DONAU_PQ_query_param_donation_unit_pub (
   const struct DONAU_DonationUnitPublicKey *donation_unit_pub);
 
+
+// TODO: implement
+/**
+ * Generate query parameter for an array of blinded donation unit signatures
+ *
+ * @param num number of elements in @e du_sigs
+ * @param du_sigs array of blinded denomination signatures
+ * @param db context for the db-connection
+ */
+struct GNUNET_PQ_QueryParam
+DONAU_PQ_query_param_array_blinded_donation_unit_sig (
+  size_t num,
+  const struct DONAU_BlindedDonationUnitSignature *du_sigs,
+  struct GNUNET_PQ_Context *db
+  );
+
+
 /**
  * Denomination public key expected.
  *
@@ -46,8 +64,25 @@ DONAU_PQ_query_param_donation_unit_pub (
  */
 struct GNUNET_PQ_ResultSpec
 DONAU_PQ_result_spec_donation_unit_pub (const char *name,
-                                        struct DONAU_DonationUnitPublicKey 
*donation_unit_pub);
+                                        struct DONAU_DonationUnitPublicKey *
+                                        donation_unit_pub);
 
+// TODO: implement
+/**
+ * Array of blinded donation unit signature expected
+ *
+ * @param db context of the database connection
+ * @param name name of the field in the table
+ * @param[out] num number of elements in @e denomdu_sigs_sigs
+ * @param[out] du_sigs where to store the result
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+DONAU_PQ_result_spec_array_blinded_donation_unit_sig (
+  struct GNUNET_PQ_Context *db,
+  const char *name,
+  size_t *num,
+  struct DONAU_BlindedDonationUnitSignature **du_sigs);
 #endif  /* DONAU_PQ_LIB_H_ */
 
 /* end of include/donau_pq_lib.h */
\ No newline at end of file
diff --git a/src/include/donaudb_plugin.h b/src/include/donaudb_plugin.h
index c9028e2..208d18d 100644
--- a/src/include/donaudb_plugin.h
+++ b/src/include/donaudb_plugin.h
@@ -107,12 +107,12 @@ struct DONAUDB_IssuedReceiptsMetaData
   /**
    * number of signatures
    */
-  unsigned int num_sig;
+  size_t num_sig;
 
-    /**
-   * Charity signature
+  /**
+   * Array of blinded signatures
    */
-  struct DONAU_BlindedDonationUnitSignature **blinded_sig;
+  struct DONAU_BlindedDonationUnitSignature *blinded_sig;
 
 };
 
@@ -216,7 +216,7 @@ struct DONAUDB_Plugin
    * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
    */
   enum GNUNET_GenericReturnValue
-    (*drop_tables)(void *cls);
+  (*drop_tables)(void *cls);
 
   /**
    * Create the necessary tables if they are not present
@@ -229,9 +229,9 @@ struct DONAUDB_Plugin
    * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
    */
   enum GNUNET_GenericReturnValue
-    (*create_tables)(void *cls,
-                     bool support_partitions,
-                     uint32_t num_partitions);
+  (*create_tables)(void *cls,
+                   bool support_partitions,
+                   uint32_t num_partitions);
 
 
   /**
@@ -243,8 +243,8 @@ struct DONAUDB_Plugin
    * @return #GNUNET_OK on success
    */
   enum GNUNET_GenericReturnValue
-    (*start)(void *cls,
-             const char *name);
+  (*start)(void *cls,
+           const char *name);
 
 
   /**
@@ -256,8 +256,8 @@ struct DONAUDB_Plugin
    * @return #GNUNET_OK on success
    */
   enum GNUNET_GenericReturnValue
-    (*start_read_committed)(void *cls,
-                            const char *name);
+  (*start_read_committed)(void *cls,
+                          const char *name);
 
   /**
    * Start a READ ONLY serializable transaction.
@@ -268,8 +268,8 @@ struct DONAUDB_Plugin
    * @return #GNUNET_OK on success
    */
   enum GNUNET_GenericReturnValue
-    (*start_read_only)(void *cls,
-                       const char *name);
+  (*start_read_only)(void *cls,
+                     const char *name);
 
 
   /**
@@ -279,7 +279,7 @@ struct DONAUDB_Plugin
    * @return transaction status
    */
   enum GNUNET_DB_QueryStatus
-    (*commit)(void *cls);
+  (*commit)(void *cls);
 
 
   /**
@@ -293,7 +293,7 @@ struct DONAUDB_Plugin
    *         #GNUNET_SYSERR on hard errors
    */
   enum GNUNET_GenericReturnValue
-    (*preflight)(void *cls);
+  (*preflight)(void *cls);
 
 
   /**
@@ -314,7 +314,7 @@ struct DONAUDB_Plugin
    *         #GNUNET_SYSERR on DB errors
    */
   enum GNUNET_GenericReturnValue
-    (*gc)(void *cls);
+  (*gc)(void *cls);
 
 
   /**
@@ -369,7 +369,7 @@ struct DONAUDB_Plugin
    * @return database transaction status
    */
   enum GNUNET_DB_QueryStatus
-    (*lookup_charity)(
+  (*lookup_charity)(
     void *cls,
     uint64_t charity_id,
     struct DONAUDB_CharityMetaData *meta);
@@ -384,7 +384,7 @@ struct DONAUDB_Plugin
    * @return database transaction status
    */
   enum GNUNET_DB_QueryStatus
-    (*do_charity_delete)(
+  (*do_charity_delete)(
     void *cls,
     uint64_t charity_id);
 
@@ -397,7 +397,7 @@ struct DONAUDB_Plugin
    * @return database transaction status
    */
   enum GNUNET_DB_QueryStatus
-    (*get_charities)(
+  (*get_charities)(
     void *cls,
     DONAUDB_GetCharitiesCallback cb,
     void *cb_cls);
@@ -411,7 +411,7 @@ struct DONAUDB_Plugin
    * @return database transaction status
    */
   enum GNUNET_DB_QueryStatus
-    (*insert_charity)(
+  (*insert_charity)(
     void *cls,
     const struct DONAU_CharityPublicKeyP *charity_pub,
     const char *charity_name,
@@ -430,7 +430,7 @@ struct DONAUDB_Plugin
     * @return database transaction status
     */
   enum GNUNET_DB_QueryStatus
-    (*iterate_donation_units)(
+  (*iterate_donation_units)(
     void *cls,
     DONAUDB_IterateDonationUnitsCallback cb,
     void *cb_cls);
@@ -444,7 +444,7 @@ struct DONAUDB_Plugin
     * @return database transaction status
     */
   enum GNUNET_DB_QueryStatus
-    (*get_history)(
+  (*get_history)(
     void *cls,
     DONAUDB_GetHistoryCallback cb,
     void *cb_cls);
@@ -458,7 +458,7 @@ struct DONAUDB_Plugin
     * @return database transaction status
     */
   enum GNUNET_DB_QueryStatus
-    (*lookup_history_entry)(
+  (*lookup_history_entry)(
     void *cls,
     const unsigned long long charity_id,
     const struct TALER_Amount *final_amount,
@@ -472,7 +472,7 @@ struct DONAUDB_Plugin
     * @return database transaction status
     */
   enum GNUNET_DB_QueryStatus
-    (*insert_donation_unit)(
+  (*insert_donation_unit)(
     void *cls,
     const struct DONAU_DonationUnitHashP *h_donation_unit_pub,
     const struct DONAU_DonationUnitPublicKey *donation_unit_pub,
@@ -489,7 +489,7 @@ struct DONAUDB_Plugin
     * @return transaction status code
     */
   enum GNUNET_DB_QueryStatus
-    (*insert_history_entry) (
+  (*insert_history_entry)(
     void *cls,
     const uint64_t charity_id,
     const struct TALER_Amount *final_amount,
@@ -499,19 +499,23 @@ struct DONAUDB_Plugin
     * Insert issued blinded donation receipt to the charity.
     *
     * @param cls closure
-    * @param charity_sig signature from the charity
+    * @param num_blinded_sig
+    * @param signatures blinded signatures
     * @param charity_id identifier of the charity
     * @param h_receipt hash of the donation receipt
-    * @param amount donation amount
+    * @param amount_receipts_request donation amount
+    * @param charity_new_amount new current receipts amount of the charity
     * @return transaction status code
     */
   enum GNUNET_DB_QueryStatus
-    (*insert_issued_receipt) (
+  (*insert_issued_receipt)(
     void *cls,
-    const struct DONAU_CharitySignatureP *charity_sig,
+    const size_t num_blinded_sig,
+    const struct DONAU_BlindedDonationUnitSignature *signatures,
     const uint64_t charity_id,
     const struct DONAU_DonationReceiptHashP *h_receipt,
-    const struct TALER_Amount *amount);
+    const struct TALER_Amount *amount_receipts_request,
+    const struct TALER_Amount *charity_new_amount);
 
   /**
     * Insert submitted donation receipt from the donor.
@@ -525,7 +529,7 @@ struct DONAUDB_Plugin
     * @return transaction status code
     */
   enum GNUNET_DB_QueryStatus
-    (*insert_submitted_receipt) (
+  (*insert_submitted_receipt)(
     void *cls,
     const struct DONAU_HashDonorTaxId *h_tax_number,
     const union GNUNET_CRYPTO_BlindSessionNonce *nonce,
@@ -533,18 +537,18 @@ struct DONAUDB_Plugin
     const struct DONAU_DonauSignatureP *donau_sig,
     const uint64_t donation_year);
 
-    /**
-    * Lookup issued receipts from the charity.
-    *
-    * @param cls closure
-    * @param bkp_hash the hash over the budi-key-pairs
-    * @param meta meta data about an issued request
-    * @return transaction status code
-    */
+  /**
+  * Lookup issued receipts from the charity.
+  *
+  * @param cls closure
+  * @param budis_hash the hash over the budi-key-pairs
+  * @param meta meta data about an issued request
+  * @return transaction status code
+  */
   enum GNUNET_DB_QueryStatus
-    (*lookup_issued_receipts) (
+  (*lookup_issued_receipts)(
     void *cls,
-    struct DONAU_BudiKeyPairsHashP bkp_hash,
+    struct DONAU_DonationReceiptHashP h_receitps,
     struct DONAUDB_IssuedReceiptsMetaData *meta);
 
   /**
@@ -556,7 +560,7 @@ struct DONAUDB_Plugin
     * @return transaction status code
     */
   enum GNUNET_DB_QueryStatus
-    (*insert_signing_key) (
+  (*insert_signing_key)(
     void *cls,
     const struct DONAU_DonauPublicKeyP *donau_pub,
     struct DONAUDB_SignkeyMetaData *meta);
@@ -570,7 +574,7 @@ struct DONAUDB_Plugin
     * @return transaction status code
     */
   enum GNUNET_DB_QueryStatus
-    (*lookup_signing_key) (
+  (*lookup_signing_key)(
     void *cls,
     const struct DONAU_DonauPublicKeyP *donau_pub,
     struct DONAUDB_SignkeyMetaData *meta);
@@ -584,7 +588,7 @@ struct DONAUDB_Plugin
     * @return database transaction status
     */
   enum GNUNET_DB_QueryStatus
-    (*iterate_active_signing_keys)(
+  (*iterate_active_signing_keys)(
     void *cls,
     DONAUDB_IterateActiveSigningKeysCallback cb,
     void *cb_cls);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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