summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNic Eigel <nic@eigel.ch>2024-01-16 22:37:07 +0100
committerNic Eigel <nic@eigel.ch>2024-01-16 22:37:07 +0100
commit45b110edb2b4fd39c56f433c5c0a7f93cd29d4da (patch)
tree3ce6145e8ea7f67daaa1af55b3651002021167fd
parent510d4fc5234e8e17d73e8d95a0dc66ad37c03fef (diff)
downloadexchange-45b110edb2b4fd39c56f433c5c0a7f93cd29d4da.tar.gz
exchange-45b110edb2b4fd39c56f433c5c0a7f93cd29d4da.tar.bz2
exchange-45b110edb2b4fd39c56f433c5c0a7f93cd29d4da.zip
progress on auditor helpers
m---------contrib/wallet-core0
-rw-r--r--debian/taler-auditor.taler-helper-auditor-deposits.service15
-rw-r--r--src/auditor/Makefile.am1
-rw-r--r--src/auditor/generate-auditor-basedb.conf28
-rw-r--r--src/auditor/taler-auditor-httpd.c3
-rw-r--r--src/auditor/taler-auditor-httpd_deposit-confirmation-get.c206
-rw-r--r--src/auditor/taler-auditor-httpd_deposit-confirmation-get.h70
-rw-r--r--src/auditor/taler-auditor-httpd_deposit-confirmation.c98
-rw-r--r--src/auditor/taler-auditor-httpd_deposit-confirmation.h29
-rw-r--r--src/auditor/taler-helper-auditor-deposits.c132
-rw-r--r--src/auditordb/0002-auditor_deposit_confirmations.sql2
-rw-r--r--src/auditordb/Makefile.am13
-rw-r--r--src/auditordb/auditor-0002.sql.in2
-rw-r--r--src/auditordb/drop.sql1
-rw-r--r--src/auditordb/pg_get_auditor_progress_deposit_confirmation.c4
-rw-r--r--src/auditordb/pg_get_deposit_confirmations.c11
-rw-r--r--src/auditordb/pg_get_deposit_confirmations.h1
-rw-r--r--src/auditordb/pg_insert_auditor_progress_deposit_confirmation.c4
-rw-r--r--src/auditordb/pg_list_exchanges.c1
-rw-r--r--src/auditordb/pg_select_pending_deposits.c4
-rw-r--r--src/auditordb/plugin_auditordb_postgres.c66
-rw-r--r--src/include/taler_auditordb_plugin.h43
-rwxr-xr-xsrc/testing/taler-unified-setup.sh3
23 files changed, 537 insertions, 200 deletions
diff --git a/contrib/wallet-core b/contrib/wallet-core
-Subproject 330edf879ab8f6fa4dbaf96de8ac84365c584e1
+Subproject a17a7a51dd50e2f508b078b9aada038fe124ff9
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 <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @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 <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_json_lib.h>
+#include <jansson.h>
+#include <microhttpd.h>
+#include <pthread.h>
+#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 <http://www.gnu.org/licenses/>
+*/
+/**
+ * @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 <gnunet/gnunet_util_lib.h>
+#include <microhttpd.h>
+#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;
@@ -54,11 +55,6 @@
*/
/**
- * Next task to run, if any.
- */
-static struct GNUNET_SCHEDULER_Task *task;
-
-/**
* Return value from main().
*/
static int global_ret;
@@ -91,6 +87,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.
*/
struct DepositConfirmationContext
@@ -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; i<dc->num_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
@@ -166,6 +166,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.
*
* @param[in,out] pg the plugin-specific state
@@ -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