From 45b110edb2b4fd39c56f433c5c0a7f93cd29d4da Mon Sep 17 00:00:00 2001 From: Nic Eigel Date: Tue, 16 Jan 2024 22:37:07 +0100 Subject: progress on auditor helpers --- contrib/wallet-core | 2 +- ...r-auditor.taler-helper-auditor-deposits.service | 15 ++ src/auditor/Makefile.am | 1 + src/auditor/generate-auditor-basedb.conf | 28 +++ src/auditor/taler-auditor-httpd.c | 3 +- .../taler-auditor-httpd_deposit-confirmation-get.c | 206 +++++++++++++++++++++ .../taler-auditor-httpd_deposit-confirmation-get.h | 70 +++++++ .../taler-auditor-httpd_deposit-confirmation.c | 98 ---------- .../taler-auditor-httpd_deposit-confirmation.h | 29 --- src/auditor/taler-helper-auditor-deposits.c | 132 ++++++++----- .../0002-auditor_deposit_confirmations.sql | 2 +- src/auditordb/Makefile.am | 13 +- src/auditordb/auditor-0002.sql.in | 2 +- src/auditordb/drop.sql | 1 + .../pg_get_auditor_progress_deposit_confirmation.c | 4 +- src/auditordb/pg_get_deposit_confirmations.c | 11 +- src/auditordb/pg_get_deposit_confirmations.h | 1 - ..._insert_auditor_progress_deposit_confirmation.c | 4 +- src/auditordb/pg_list_exchanges.c | 1 - src/auditordb/pg_select_pending_deposits.c | 4 +- src/auditordb/plugin_auditordb_postgres.c | 66 +++++++ src/include/taler_auditordb_plugin.h | 43 ++++- src/testing/taler-unified-setup.sh | 3 + 23 files changed, 538 insertions(+), 201 deletions(-) create mode 100644 debian/taler-auditor.taler-helper-auditor-deposits.service create mode 100644 src/auditor/taler-auditor-httpd_deposit-confirmation-get.c create mode 100644 src/auditor/taler-auditor-httpd_deposit-confirmation-get.h diff --git a/contrib/wallet-core b/contrib/wallet-core index 330edf879..a17a7a51d 160000 --- a/contrib/wallet-core +++ b/contrib/wallet-core @@ -1 +1 @@ -Subproject commit 330edf879ab8f6fa4dbaf96de8ac84365c584e15 +Subproject commit a17a7a51dd50e2f508b078b9aada038fe124ff9c diff --git a/debian/taler-auditor.taler-helper-auditor-deposits.service b/debian/taler-auditor.taler-helper-auditor-deposits.service new file mode 100644 index 000000000..a536d5d25 --- /dev/null +++ b/debian/taler-auditor.taler-helper-auditor-deposits.service @@ -0,0 +1,15 @@ +[Unit] +Description=GNU Taler auditor helper reporting confirmation deposits +After=postgres.service + +[Service] +User=taler-auditor-httpd +Type=simple +Restart=always +RestartSec=1s +RestartPreventExitStatus=9 +ExecStart=/usr/bin/taler-helper-auditor-deposits -c /etc/taler/taler.conf +PrivateTmp=yes +PrivateDevices=yes +ProtectSystem=full +RuntimeMaxSec=3600s diff --git a/src/auditor/Makefile.am b/src/auditor/Makefile.am index c3deedba1..36b540c03 100644 --- a/src/auditor/Makefile.am +++ b/src/auditor/Makefile.am @@ -163,6 +163,7 @@ taler_helper_auditor_wire_LDADD = \ taler_auditor_httpd_SOURCES = \ taler-auditor-httpd.c taler-auditor-httpd.h \ taler-auditor-httpd_deposit-confirmation.c taler-auditor-httpd_deposit-confirmation.h \ + taler-auditor-httpd_deposit-confirmation-get.c taler-auditor-httpd_deposit-confirmation-get.h \ taler-auditor-httpd_mhd.c taler-auditor-httpd_mhd.h taler_auditor_httpd_LDADD = \ $(LIBGCRYPT_LIBS) \ diff --git a/src/auditor/generate-auditor-basedb.conf b/src/auditor/generate-auditor-basedb.conf index 8aae9a924..8efb81a3e 100644 --- a/src/auditor/generate-auditor-basedb.conf +++ b/src/auditor/generate-auditor-basedb.conf @@ -13,9 +13,22 @@ SIGNKEY_DURATION = 4 weeks LOOKAHEAD_SIGN = 32 weeks 1 day SIGNKEY_LEGAL_DURATION = 4 weeks AML_THRESHOLD = TESTKUDOS:1000000 +db = postgres +BASE_URL = http://localhost:8081/ +IDLE_RESERVE_EXPIRATION_TIME = 4 weeks +LEGAL_RESERVE_EXPIRATION_TIME = 4 weeks + +[exchangedb] +IDLE_RESERVE_EXPIRATION_TIME = 4 weeks +LEGAL_RESERVE_EXPIRATION_TIME = 4 weeks +AGGREGATOR_SHIFT = 1 s +DEFAULT_PURSE_LIMIT = 1 [exchangedb-postgres] CONFIG = postgres:///auditor-basedb +SQL_DIR = $DATADIR/sql/exchange/ +IDLE_RESERVE_EXPIRATION_TIME = 4 weeks +LEGAL_RESERVE_EXPIRATION_TIME = 4 weeks [exchange-account-1] PAYTO_URI = payto://iban/SANDBOXX/DE989651?receiver-name=Exchange+Company @@ -49,9 +62,12 @@ WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" [merchant] FORCE_AUDIT = YES +SERVE = TCP +PORT = 8888 [merchantdb-postgres] CONFIG = postgres:///auditor-basedb +SQL_DIR = $DATADIR/sql/merchant/ [merchant-exchange-default] MASTER_KEY = M4FGP18EQFXFGGFQ1AWXHACN2JX0SMVK9CNF6459Z1WG18JSN0BG @@ -67,13 +83,25 @@ DB_CONNECTION="postgresql:///auditor-basedb" [libeufin-sandbox] DB_CONNECTION="postgresql:///auditor-basedb" +[libeufin-bank] +CURRENCY = EUR +DEFAULT_CUSTOMER_DEBT_LIMIT = EUR:200 # dead +DEFAULT_ADMIN_DEBT_LIMIT = EUR:2000 +REGISTRATION_BONUS_ENABLED = yes +REGISTRATION_BONUS = EUR:100 +SUGGESTED_WITHDRAWAL_EXCHANGE = http://localhost:8081/ +SERVE = tcp +PORT = 8082 + [auditor] BASE_URL = http://localhost:8083/ TINY_AMOUNT = TESTKUDOS:0.01 PUBLIC_KEY = 0EHPW5WEKHXPPN4MPJNGA7Z6D29JP21GKVNV8ARFB1YW7WWJX20G +db = postgres [auditordb-postgres] CONFIG = postgres:///auditor-basedb +SQL_DIR = $DATADIR/sql/auditor/ [coin_kudos_ct_1] value = TESTKUDOS:0.01 diff --git a/src/auditor/taler-auditor-httpd.c b/src/auditor/taler-auditor-httpd.c index 0bb9c77d9..94adb5471 100644 --- a/src/auditor/taler-auditor-httpd.c +++ b/src/auditor/taler-auditor-httpd.c @@ -31,6 +31,7 @@ #include "taler_auditordb_lib.h" #include "taler_exchangedb_lib.h" #include "taler-auditor-httpd_deposit-confirmation.h" +#include "taler-auditor-httpd_deposit-confirmation-get.h" #include "taler-auditor-httpd_mhd.h" #include "taler-auditor-httpd.h" @@ -207,7 +208,7 @@ handle_mhd_request (void *cls, &TAH_DEPOSIT_CONFIRMATION_handler, MHD_HTTP_OK }, { "/deposit-confirmation", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, - &TAH_DEPOSIT_CONFIRMATION_get, MHD_HTTP_OK }, + &TAH_DEPOSIT_CONFIRMATION_handler_get, MHD_HTTP_OK }, // { "/deposit-confirmation", MHD_HTTP_METHOD_DELETE, "application/json", // NULL, 0, // &TAH_DEPOSIT_CONFIRMATION_delete, MHD_HTTP_OK }, diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation-get.c b/src/auditor/taler-auditor-httpd_deposit-confirmation-get.c new file mode 100644 index 000000000..5caff7aba --- /dev/null +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation-get.c @@ -0,0 +1,206 @@ +/* + 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 Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ + +/** + * @file taler-auditor-httpd_deposit-confirmation-get.c + * @brief Handle /deposit-confirmation requests; return list of deposit confirmations from merchant + * that were not received from the exchange, by auditor. + * @author Nic Eigel + */ + +#include "platform.h" +#include +#include +#include +#include +#include +#include "taler_json_lib.h" +#include "taler_mhd_lib.h" +#include "taler-auditor-httpd.h" +#include "taler-auditor-httpd_deposit-confirmation-get.h" + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * @brief Information about a signing key of the exchange. Signing keys are used + * to sign exchange messages other than coins, i.e. to confirm that a + * deposit was successful or that a refresh was accepted. + */ +struct ExchangeSigningKeyDataP +{ + + /** + * When does this signing key begin to be valid? + */ + struct GNUNET_TIME_TimestampNBO start; + + /** + * When does this signing key expire? Note: This is currently when + * the Exchange will definitively stop using it. Signatures made with + * the key remain valid until @e end. When checking validity periods, + * clients should allow for some overlap between keys and tolerate + * the use of either key during the overlap time (due to the + * possibility of clock skew). + */ + struct GNUNET_TIME_TimestampNBO expire; + + /** + * When do signatures with this signing key become invalid? After + * this point, these signatures cannot be used in (legal) disputes + * anymore, as the Exchange is then allowed to destroy its side of the + * evidence. @e end is expected to be significantly larger than @e + * expire (by a year or more). + */ + struct GNUNET_TIME_TimestampNBO end; + + /** + * The public online signing key that the exchange will use + * between @e start and @e expire. + */ + struct TALER_ExchangePublicKeyP signkey_pub; +}; + +GNUNET_NETWORK_STRUCT_END + +/** + * Cache of already verified exchange signing keys. Maps the hash of the + * `struct TALER_ExchangeSigningKeyValidityPS` to the (static) string + * "verified" or "revoked". Access to this map is guarded by the #lock. + */ +static struct GNUNET_CONTAINER_MultiHashMap *cache; + +/** + * Lock for operations on #cache. + */ +static pthread_mutex_t lock; + + +/** + * Add deposit confirmation to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param serial_id location of the @a dc in the database + * @param dc struct of deposit confirmation + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +static enum GNUNET_GenericReturnValue +add_deposit_confirmation (void *cls, + uint64_t serial_id, + const struct TALER_AUDITORDB_DepositConfirmation *dc) +{ + json_t *list = cls; + json_t *obj; + + obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("dc", + dc)); + GNUNET_break (0 == + json_array_append_new (list, + obj)); + return GNUNET_OK; +} + + +/** + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +MHD_RESULT +TAH_DEPOSIT_CONFIRMATION_handler_get (struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + json_t *ja; + enum GNUNET_DB_QueryStatus qs; + + (void) rh; + (void) connection_cls; + (void) upload_data; + (void) upload_data_size; + if (GNUNET_SYSERR == + TAH_plugin->preflight (TAH_plugin->cls)) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_SETUP_FAILED, + NULL); + } + ja = json_array (); + GNUNET_break (NULL != ja); + // TODO correct below + struct TALER_AUDITORDB_ProgressPointDepositConfirmation ppdc = { 0 }; // FIXME: initialize... + + qs = TAH_plugin->get_deposit_confirmations ( + TAH_plugin->cls, + ppdc.last_deposit_confirmation_serial_id, + &add_deposit_confirmation, + ja); + + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + json_decref (ja); + TALER_LOG_WARNING ( + "Failed to handle GET /deposit-confirmation in database\n"); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "deposit-confirmation"); + } + return TALER_MHD_REPLY_JSON_PACK ( + connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_array_steal ("deposit-confirmation", + ja)); +} + + +void +TEAH_DEPOSIT_CONFIRMATION_GET_init (void) +{ + cache = GNUNET_CONTAINER_multihashmap_create (32, + GNUNET_NO); + GNUNET_assert (0 == pthread_mutex_init (&lock, NULL)); +} + + +void +TEAH_DEPOSIT_CONFIRMATION_GET_done (void) +{ + if (NULL != cache) + { + GNUNET_CONTAINER_multihashmap_destroy (cache); + cache = NULL; + GNUNET_assert (0 == pthread_mutex_destroy (&lock)); + } +} + + +/*MHD_RESULT +TAH_DEPOSIT_CONFIRMATION_delete(struct TEH_RequestContext *rc, + const char *const args[1]) { +}*/ + + +/* end of taler-auditor-httpd_deposit-confirmation.c */ diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation-get.h b/src/auditor/taler-auditor-httpd_deposit-confirmation-get.h new file mode 100644 index 000000000..f1f522787 --- /dev/null +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation-get.h @@ -0,0 +1,70 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file taler-auditor-httpd_deposit-confirmation-get.h + * @brief Handle GET /deposit-confirmation requests + * @author Nic Eigel + */ +#ifndef TALER_AUDITOR_HTTPD_DEPOSIT_CONFIRMATION_GET_H +#define TALER_AUDITOR_HTTPD_DEPOSIT_CONFIRMATION_GET_H + +#include +#include +#include "taler-auditor-httpd.h" + +/** + * Initialize subsystem. + */ +void +TEAH_DEPOSIT_CONFIRMATION_GET_init (void); + +/** + * Shut down subsystem. + */ +void +TEAH_DEPOSIT_CONFIRMATION_GET_done (void); + +/** + * Handle a "/deposit-confirmation" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +MHD_RESULT +TAH_DEPOSIT_CONFIRMATION_handler_get (struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + +/** + * Handle a DELETE "/deposit-confirmation/$dc" request. + * + * @param rc request details about the request to handle + * @param args argument with the dc primary key + * @return MHD result code + */ +/*MHD_RESULT +TAH_DEPOSIT_CONFIRMATION_delete ( + struct TEH_RequestContext *rc, + const char *const args[1]);*/ + + +#endif diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c index 2631c6f58..10243eafc 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c @@ -453,101 +453,3 @@ TEAH_DEPOSIT_CONFIRMATION_done (void) GNUNET_assert (0 == pthread_mutex_destroy (&lock)); } } - - -/** - * Add deposit confirmation to the list. - * - * @param[in,out] cls a `json_t *` array to extend - * @param serial_id location of the @a dc in the database - * @param dc struct of deposit confirmation - * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating - */ -static enum GNUNET_GenericReturnValue -add_deposit_confirmation (void *cls, - uint64_t serial_id, - const struct TALER_AUDITORDB_DepositConfirmation *dc) -{ - json_t *list = cls; - json_t *obj; - - obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("dc", - dc)); - GNUNET_break (0 == - json_array_append_new (list, - obj)); - return GNUNET_OK; -} - - -/** - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @return MHD result code - */ -MHD_RESULT -TAH_DEPOSIT_CONFIRMATION_get (struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) -{ - json_t *ja; - enum GNUNET_DB_QueryStatus qs; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - ja = json_array (); - GNUNET_break (NULL != ja); - // TODO correct below - struct TALER_AUDITORDB_ProgressPointDepositConfirmation ppdc = { 0 }; // FIXME: initialize... - - qs = TAH_plugin->get_deposit_confirmations ( - TAH_plugin->cls, - NULL, /* FIXME: master-public key to be removed! */ - ppdc.last_deposit_confirmation_serial_id, - &add_deposit_confirmation, - ja); - - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - json_decref (ja); - TALER_LOG_WARNING ( - "Failed to handle GET /deposit-confirmation in database\n"); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "deposit-confirmation"); - } - return TALER_MHD_REPLY_JSON_PACK ( - connection, - MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("deposit-confirmation", - ja)); -} - - -/*MHD_RESULT -TAH_DEPOSIT_CONFIRMATION_delete(struct TEH_RequestContext *rc, - const char *const args[1]) { -}*/ - - -/* end of taler-auditor-httpd_deposit-confirmation.c */ diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.h b/src/auditor/taler-auditor-httpd_deposit-confirmation.h index ff42e4aa3..1226dda69 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.h +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.h @@ -56,34 +56,5 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh, const char *upload_data, size_t *upload_data_size); -/** - * Handle a "/deposit-confirmation" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @return MHD result code - */ -MHD_RESULT -TAH_DEPOSIT_CONFIRMATION_get (struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size); - -/** - * Handle a DELETE "/deposit-confirmation/$dc" request. - * - * @param rc request details about the request to handle - * @param args argument with the dc primary key - * @return MHD result code - */ -/*MHD_RESULT -TAH_DEPOSIT_CONFIRMATION_delete ( - struct TEH_RequestContext *rc, - const char *const args[1]);*/ - #endif diff --git a/src/auditor/taler-helper-auditor-deposits.c b/src/auditor/taler-helper-auditor-deposits.c index 520fc2f47..fea23131b 100644 --- a/src/auditor/taler-helper-auditor-deposits.c +++ b/src/auditor/taler-helper-auditor-deposits.c @@ -17,6 +17,7 @@ * @file auditor/taler-helper-auditor-deposits.c * @brief audits an exchange database for deposit confirmation consistency * @author Christian Grothoff + * @author Nic Eigel * * We simply check that all of the deposit confirmations reported to us * by merchants were also reported to us by the exchange. @@ -35,14 +36,14 @@ /* -- -- SELECT serial_id,h_contract_terms,h_wire,merchant_pub ... --- FROM auditor.depoist_confirmations +-- FROM auditor.auditor_deposit_confirmations -- WHERE NOT ancient -- ORDER BY exchange_timestamp ASC; -- SELECT 1 - FROM exchange.deposits dep WHERE ($RESULT.contract_terms = dep.h_contract_terms) AND ($RESULT.h_wire = dep.h_wire) AND ...); -- IF FOUND --- DELETE FROM auditor.depoist_confirmations +-- DELETE FROM auditor.auditor_deposit_confirmations -- WHERE serial_id = $RESULT.serial_id; -- SELECT exchange_timestamp AS latest -- FROM exchange.deposits ORDER BY exchange_timestamp DESC; @@ -53,11 +54,6 @@ -- AND NOT ancient; */ -/** - * Next task to run, if any. - */ -static struct GNUNET_SCHEDULER_Task *task; - /** * Return value from main(). */ @@ -90,6 +86,11 @@ static struct GNUNET_DB_EventHandler *eh; */ static struct TALER_AUDITORDB_Plugin *db_plugin; +/** + * The auditors's configuration. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + /** * Closure for #test_dc. */ @@ -126,7 +127,6 @@ struct DepositConfirmationContext }; - /** * Given a deposit confirmation from #TALER_ARL_adb, check that it is also * in #TALER_ARL_edb. Update the deposit confirmation context accordingly. @@ -145,7 +145,7 @@ test_dc (void *cls, bool missing = false; dcc->last_seen_coin_serial = serial_id; - for (unsigned int i = 0; inum_coins; i++) + for (unsigned int i = 0; i < dc->num_coins; i++) { enum GNUNET_DB_QueryStatus qs; struct GNUNET_TIME_Timestamp exchange_timestamp; @@ -215,15 +215,14 @@ analyze_deposit_confirmations (void *cls) enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qsx; enum GNUNET_DB_QueryStatus qsp; - (void) cls; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Analyzing deposit confirmations\n"); + ppdc.last_deposit_confirmation_serial_id = 0; qsp = TALER_ARL_adb->get_auditor_progress_deposit_confirmation ( TALER_ARL_adb->cls, &TALER_ARL_master_pub, &ppdc); + if (0 > qsp) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); @@ -248,9 +247,10 @@ analyze_deposit_confirmations (void *cls) dcc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; dcc.missed_count = 0LLU; dcc.first_missed_coin_serial = UINT64_MAX; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "lastdepconfserialid %lu\n", + ppdc.last_deposit_confirmation_serial_id); qsx = TALER_ARL_adb->get_deposit_confirmations ( TALER_ARL_adb->cls, - &TALER_ARL_master_pub, ppdc.last_deposit_confirmation_serial_id, &test_dc, &dcc); @@ -268,11 +268,16 @@ analyze_deposit_confirmations (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == dcc.qs); return dcc.qs; } - if (UINT64_MAX == dcc.first_missed_coin_serial) - ppdc.last_deposit_confirmation_serial_id = dcc.last_seen_coin_serial; - else - ppdc.last_deposit_confirmation_serial_id = dcc.first_missed_coin_serial - 1; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "getting in here when i shouldnt\n"); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "lastseencoinserialid %lu\n", + dcc.last_seen_coin_serial); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "dcc.qs %u\n", dcc.qs); + /* if (UINT64_MAX == dcc.first_missed_coin_serial) + ppdc.last_deposit_confirmation_serial_id = dcc.last_seen_coin_serial; + else + ppdc.last_deposit_confirmation_serial_id = dcc.first_missed_coin_serial - 1; + */ /* sync 'cc' back to disk */ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp) qs = TALER_ARL_adb->update_auditor_progress_deposit_confirmation ( @@ -291,6 +296,7 @@ analyze_deposit_confirmations (void *cls) GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); return qs; } + number_missed_deposit_confirmations = (json_int_t) dcc.missed_count; total_missed_deposit_confirmations = dcc.missed_amount; @@ -313,14 +319,52 @@ db_notify (void *cls, const void *extra, size_t extra_size) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Received notification for new deposit_confirmation\n"); + (void) cls; (void) extra; (void) extra_size; - GNUNET_assert (NULL != task); - GNUNET_SCHEDULER_cancel (task); - task = GNUNET_SCHEDULER_add_now (&analyze_deposit_confirmations, - NULL); + if (GNUNET_OK != + TALER_ARL_init (cfg)) + { + global_ret = EXIT_FAILURE; + return; + } + + if (NULL == + (db_plugin = TALER_AUDITORDB_plugin_load (cfg))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to initialize DB subsystem\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_assert (NULL != + (report_deposit_confirmation_inconsistencies = json_array ())); + + if (GNUNET_OK != + TALER_ARL_setup_sessions_and_run (&analyze_deposit_confirmations, + NULL)) + { + global_ret = EXIT_FAILURE; + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deposit audit complete\n"); + TALER_ARL_done ( + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_array_steal ("deposit_confirmation_inconsistencies", + report_deposit_confirmation_inconsistencies), + GNUNET_JSON_pack_uint64 ("missing_deposit_confirmation_count", + number_missed_deposit_confirmations), + TALER_JSON_pack_amount ("missing_deposit_confirmation_total", + &total_missed_deposit_confirmations), + TALER_JSON_pack_time_abs_human ("auditor_start_time", + start_time), + TALER_JSON_pack_time_abs_human ("auditor_end_time", + GNUNET_TIME_absolute_get ()))); } @@ -341,6 +385,7 @@ run (void *cls, (void) cls; (void) args; (void) cfgfile; + cfg = c; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching deposit auditor\n"); if (GNUNET_OK != @@ -350,37 +395,32 @@ run (void *cls, return; } - /*if (NULL == + if (NULL == (db_plugin = TALER_AUDITORDB_plugin_load (cfg))) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to initialize DB subsystem\n"); - GNUNET_SCHEDULER_shutdown (); - return; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to initialize DB subsystem\n"); + GNUNET_SCHEDULER_shutdown (); + return; } if (GNUNET_OK != - db_plugin->connect (db_plugin->cls)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to connect to database\n"); - GNUNET_SCHEDULER_shutdown (); - return; - } + db_plugin->preflight (db_plugin->cls)) { - struct GNUNET_DB_EventHeaderP es = { - .size = htons (sizeof (es)), - .type = htons (TALER_DBEVENT_AUDITOR_NEW_DEPOSIT_CONFIRMATIONS) - }; - - eh = db_plugin->event_listen (db_plugin->cls, - &es, - GNUNET_TIME_UNIT_FOREVER_REL, - &db_notify, - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to connect to database\n"); + GNUNET_SCHEDULER_shutdown (); + return; } - GNUNET_assert (NULL == task); - task = GNUNET_SCHEDULER_add_now (&select_work, - NULL);*/ + + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (TALER_DBEVENT_EXCHANGE_AUDITOR_NEW_DEPOSIT_CONFIRMATION) + }; + eh = db_plugin->event_listen (db_plugin->cls, + &es, + GNUNET_TIME_UNIT_FOREVER_REL, + &db_notify, + NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting deposit audit\n"); diff --git a/src/auditordb/0002-auditor_deposit_confirmations.sql b/src/auditordb/0002-auditor_deposit_confirmations.sql index dd85c0a62..e26009efc 100644 --- a/src/auditordb/0002-auditor_deposit_confirmations.sql +++ b/src/auditordb/0002-auditor_deposit_confirmations.sql @@ -56,5 +56,5 @@ COMMENT ON FUNCTION auditor_new_transactions_trigger() CREATE TRIGGER auditor_notify_helper_deposits AFTER INSERT - ON auditor.deposit_confirmations + ON auditor.auditor_deposit_confirmations EXECUTE PROCEDURE auditor_new_transactions_trigger(); \ No newline at end of file diff --git a/src/auditordb/Makefile.am b/src/auditordb/Makefile.am index 573b1b980..af5c5a1e0 100644 --- a/src/auditordb/Makefile.am +++ b/src/auditordb/Makefile.am @@ -13,18 +13,19 @@ pkgcfg_DATA = \ sqldir = $(prefix)/share/taler/sql/auditor/ -sql_DATA = \ - versioning.sql \ - auditor-0001.sql \ - drop.sql \ - restart.sql - sqlinputs = \ 0002-*.sql \ auditor-0002.sql.in # auditor_do_*.sql # procedures.sql.in +sql_DATA = \ + versioning.sql \ + auditor-0001.sql \ + auditor-0002.sql \ + drop.sql \ + restart.sql + auditor-0002.sql: auditor-0002.sql.in 0002-*.sql chmod +w $@ || true gcc -E -P -undef - < auditor-0002.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@ diff --git a/src/auditordb/auditor-0002.sql.in b/src/auditordb/auditor-0002.sql.in index 5b8f9e074..ac0dd33d4 100644 --- a/src/auditordb/auditor-0002.sql.in +++ b/src/auditordb/auditor-0002.sql.in @@ -36,7 +36,7 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; - +#include "0002-auditor_amount_arithmetic_inconsistency.sql" #include "0002-auditor_balances.sql" #include "0002-auditor_denomination_pending.sql" #include "0002-auditor_exchange_signkeys.sql" diff --git a/src/auditordb/drop.sql b/src/auditordb/drop.sql index 37a50ee68..b7421b1c3 100644 --- a/src/auditordb/drop.sql +++ b/src/auditordb/drop.sql @@ -20,6 +20,7 @@ BEGIN; -- Drop versioning (auditor-0001.sql) SELECT _v.unregister_patch('auditor-0001'); +SELECT _v.unregister_patch('auditor-0002'); DROP SCHEMA auditor CASCADE; -- And we're out of here... diff --git a/src/auditordb/pg_get_auditor_progress_deposit_confirmation.c b/src/auditordb/pg_get_auditor_progress_deposit_confirmation.c index f69f4a692..7a14b4600 100644 --- a/src/auditordb/pg_get_auditor_progress_deposit_confirmation.c +++ b/src/auditordb/pg_get_auditor_progress_deposit_confirmation.c @@ -34,7 +34,6 @@ TAH_PG_get_auditor_progress_deposit_confirmation ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (master_pub), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { @@ -47,8 +46,7 @@ TAH_PG_get_auditor_progress_deposit_confirmation ( "auditor_progress_select_deposit_confirmation", "SELECT" " last_deposit_confirmation_serial_id" - " FROM auditor_progress_deposit_confirmation" - " WHERE master_pub=$1;"); + " FROM auditor_progress_deposit_confirmation;"); return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "auditor_progress_select_deposit_confirmation", params, diff --git a/src/auditordb/pg_get_deposit_confirmations.c b/src/auditordb/pg_get_deposit_confirmations.c index 01d78dba4..cb52c36c2 100644 --- a/src/auditordb/pg_get_deposit_confirmations.c +++ b/src/auditordb/pg_get_deposit_confirmations.c @@ -156,29 +156,27 @@ deposit_confirmation_cb (void *cls, enum GNUNET_DB_QueryStatus TAH_PG_get_deposit_confirmations ( void *cls, - const struct TALER_MasterPublicKeyP *master_public_key, uint64_t start_id, TALER_AUDITORDB_DepositConfirmationCallback cb, void *cb_cls) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (master_public_key), GNUNET_PQ_query_param_uint64 (&start_id), GNUNET_PQ_query_param_end }; struct DepositConfirmationContext dcc = { - .master_pub = master_public_key, .cb = cb, .cb_cls = cb_cls, .pg = pg }; enum GNUNET_DB_QueryStatus qs; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "id above %ld\n", start_id); PREPARE (pg, "auditor_deposit_confirmation_select", "SELECT" - " serial_id" + " deposit_confirmation_serial_id" ",h_contract_terms" ",h_policy" ",h_wire" @@ -192,9 +190,8 @@ TAH_PG_get_deposit_confirmations ( ",exchange_sig" ",exchange_pub" ",master_sig" /* master_sig could be normalized... */ - " FROM deposit_confirmations" - " WHERE master_pub=$1" - " AND serial_id>$2"); + " FROM auditor_deposit_confirmations" + " WHERE deposit_confirmation_serial_id>$1"); qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, "auditor_deposit_confirmation_select", params, diff --git a/src/auditordb/pg_get_deposit_confirmations.h b/src/auditordb/pg_get_deposit_confirmations.h index 48ee70634..2c3c28538 100644 --- a/src/auditordb/pg_get_deposit_confirmations.h +++ b/src/auditordb/pg_get_deposit_confirmations.h @@ -40,7 +40,6 @@ enum GNUNET_DB_QueryStatus TAH_PG_get_deposit_confirmations ( void *cls, - const struct TALER_MasterPublicKeyP *master_public_key, uint64_t start_id, TALER_AUDITORDB_DepositConfirmationCallback cb, void *cb_cls); diff --git a/src/auditordb/pg_insert_auditor_progress_deposit_confirmation.c b/src/auditordb/pg_insert_auditor_progress_deposit_confirmation.c index 4f4c7390e..94231b1c6 100644 --- a/src/auditordb/pg_insert_auditor_progress_deposit_confirmation.c +++ b/src/auditordb/pg_insert_auditor_progress_deposit_confirmation.c @@ -38,7 +38,9 @@ TAH_PG_insert_auditor_progress_deposit_confirmation ( GNUNET_PQ_query_param_uint64 (&ppdc->last_deposit_confirmation_serial_id), GNUNET_PQ_query_param_end }; - + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "isnert ppdc last deposit conf serial id above %ld\n", + ppdc->last_deposit_confirmation_serial_id); PREPARE (pg, "auditor_progress_insert_deposit_confirmation", "INSERT INTO auditor_progress_deposit_confirmation " diff --git a/src/auditordb/pg_list_exchanges.c b/src/auditordb/pg_list_exchanges.c index f0637b13f..a455ee32a 100644 --- a/src/auditordb/pg_list_exchanges.c +++ b/src/auditordb/pg_list_exchanges.c @@ -107,7 +107,6 @@ TAH_PG_list_exchanges (void *cls, .cb_cls = cb_cls }; enum GNUNET_DB_QueryStatus qs; - PREPARE (pg, "auditor_list_exchanges", "SELECT" diff --git a/src/auditordb/pg_select_pending_deposits.c b/src/auditordb/pg_select_pending_deposits.c index a5d1c6ae8..3a46770a2 100644 --- a/src/auditordb/pg_select_pending_deposits.c +++ b/src/auditordb/pg_select_pending_deposits.c @@ -118,7 +118,6 @@ TAH_PG_select_pending_deposits ( { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (master_pub), GNUNET_PQ_query_param_absolute_time (&deadline), GNUNET_PQ_query_param_end }; @@ -137,8 +136,7 @@ TAH_PG_select_pending_deposits ( ",wire_target_h_payto" ",deadline" " FROM auditor_pending_deposits" - " WHERE master_pub=$1" - " AND deadline<$2;"); + " WHERE deadline<$1;"); qs = GNUNET_PQ_eval_prepared_multi_select ( pg->conn, "auditor_select_pending_deposits", diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index dc66990ba..2366eb69f 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -165,6 +165,69 @@ postgres_create_tables (void *cls) } +/** + * 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. * @@ -399,6 +462,9 @@ libtaler_plugin_auditordb_postgres_init (void *cls) 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; diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index b83d6316c..6e0e97ca0 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -689,6 +689,47 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_GenericReturnValue (*preflight)(void *cls); + /** + * 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 + */ + struct GNUNET_DB_EventHandler * + (*event_listen)(void *cls, + const struct GNUNET_DB_EventHeaderP *es, + struct GNUNET_TIME_Relative timeout, + GNUNET_DB_EventCallback cb, + void *cb_cls); + + /** + * Stop notifications. + * + * @param eh handle to unregister. + */ + void + (*event_listen_cancel)(struct GNUNET_DB_EventHandler *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 + */ + void + (*event_notify)(void *cls, + const struct GNUNET_DB_EventHeaderP *es, + const void *extra, + size_t extra_size); + /** * Drop all auditor tables OR deletes recoverable auditor state. @@ -828,7 +869,6 @@ struct TALER_AUDITORDB_Plugin * Get information about deposit confirmations from the database. * * @param cls the @e cls of this struct with the plugin-specific state - * @param master_public_key for which exchange do we want to get deposit confirmations * @param start_id row/serial ID where to start the iteration (0 from * the start, exclusive, i.e. serial_ids must start from 1) * @param cb function to call with results @@ -838,7 +878,6 @@ struct TALER_AUDITORDB_Plugin enum GNUNET_DB_QueryStatus (*get_deposit_confirmations)( void *cls, - const struct TALER_MasterPublicKeyP *master_public_key, uint64_t start_id, TALER_AUDITORDB_DepositConfirmationCallback cb, void *cb_cls); diff --git a/src/testing/taler-unified-setup.sh b/src/testing/taler-unified-setup.sh index cb0273e30..02d502237 100755 --- a/src/testing/taler-unified-setup.sh +++ b/src/testing/taler-unified-setup.sh @@ -671,6 +671,9 @@ then $USE_VALGRIND taler-auditor-httpd \ -L "$LOGLEVEL" \ -c "$CONF" 2> taler-auditor-httpd.log & + $USE_VALGRIND taler-helper-auditor-deposits \ + -L "$LOGLEVEL" \ + -c "$CONF" 2> taler-helper-auditor.log & echo " DONE" fi -- cgit v1.2.3