donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

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

[donau][donaudb] work on issue receipts

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

diff --git 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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);