diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-03-02 21:07:27 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-03-02 21:07:27 +0100 |
commit | 17ff4f5e97b981f0b3eebd6e3923fe60dc75edd5 (patch) | |
tree | 585b6cbe92aec91b2e186206c1bfe746a0cd85e6 /src/mintdb | |
parent | 531272a92a5aa08559436138ff5106a6bff1b361 (diff) | |
parent | 201b2b3d1af2a4d44fe32c8b0312d935845cf129 (diff) | |
download | exchange-17ff4f5e97b981f0b3eebd6e3923fe60dc75edd5.tar.xz |
fixing #4230 in bank-lib
Diffstat (limited to 'src/mintdb')
-rw-r--r-- | src/mintdb/Makefile.am | 110 | ||||
-rw-r--r-- | src/mintdb/mintdb_keyio.c | 558 | ||||
-rw-r--r-- | src/mintdb/mintdb_plugin.c | 87 | ||||
-rw-r--r-- | src/mintdb/perf_taler_mintdb.c | 358 | ||||
-rw-r--r-- | src/mintdb/perf_taler_mintdb_init.c | 622 | ||||
-rw-r--r-- | src/mintdb/perf_taler_mintdb_init.h | 257 | ||||
-rw-r--r-- | src/mintdb/perf_taler_mintdb_interpreter.c | 1998 | ||||
-rw-r--r-- | src/mintdb/perf_taler_mintdb_interpreter.h | 1319 | ||||
-rw-r--r-- | src/mintdb/perf_taler_mintdb_values.h | 25 | ||||
-rw-r--r-- | src/mintdb/plugin_mintdb_common.c | 162 | ||||
-rw-r--r-- | src/mintdb/plugin_mintdb_postgres.c | 4295 | ||||
-rw-r--r-- | src/mintdb/test-mint-db-postgres.conf | 8 | ||||
-rw-r--r-- | src/mintdb/test_mintdb.c | 907 | ||||
-rw-r--r-- | src/mintdb/test_mintdb_deposits.c | 152 | ||||
-rw-r--r-- | src/mintdb/test_mintdb_keyio.c | 85 | ||||
-rw-r--r-- | src/mintdb/test_perf_taler_mintdb.c | 182 |
16 files changed, 0 insertions, 11125 deletions
diff --git a/src/mintdb/Makefile.am b/src/mintdb/Makefile.am deleted file mode 100644 index e3d37b2e5..000000000 --- a/src/mintdb/Makefile.am +++ /dev/null @@ -1,110 +0,0 @@ -# This Makefile.am is in the public domain -AM_CPPFLAGS = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/pq/ $(POSTGRESQL_CPPFLAGS) - -if USE_COVERAGE - AM_CFLAGS = --coverage -O0 - XLIB = -lgcov -endif - -plugindir = $(libdir)/taler - -if HAVE_POSTGRESQL -plugin_LTLIBRARIES = \ - libtaler_plugin_mintdb_postgres.la -endif - -EXTRA_DIST = \ - plugin_mintdb_common.c \ - test-mint-db-postgres.conf - -libtaler_plugin_mintdb_postgres_la_SOURCES = \ - plugin_mintdb_postgres.c -libtaler_plugin_mintdb_postgres_la_LIBADD = \ - $(LTLIBINTL) -libtaler_plugin_mintdb_postgres_la_LDFLAGS = \ - $(TALER_PLUGIN_LDFLAGS) \ - $(top_builddir)/src/pq/libtalerpq.la \ - $(top_builddir)/src/util/libtalerutil.la \ - -lpq \ - -lgnunetpq \ - -lgnunetutil $(XLIB) - -lib_LTLIBRARIES = \ - libtalermintdb.la - -libtalermintdb_la_SOURCES = \ - mintdb_keyio.c \ - mintdb_plugin.c - -libtalermintdb_la_LIBADD = \ - $(top_builddir)/src/util/libtalerutil.la \ - -lgnunetutil $(XLIB) - -libtalermintdb_la_LDFLAGS = \ - $(POSTGRESQL_LDFLAGS) \ - -version-info 0:0:0 \ - -no-undefined - - -check_PROGRAMS = \ - test-mintdb-deposits \ - test-mintdb-keyio \ - test-mintdb-postgres \ - test-perf-taler-mintdb \ - perf-mintdb - -TESTS = \ - test-mintdb-postgres \ - test-perf-taler-mintdb - -test_mintdb_deposits_SOURCES = \ - test_mintdb_deposits.c -test_mintdb_deposits_LDADD = \ - libtalermintdb.la \ - $(top_srcdir)/src/util/libtalerutil.la \ - $(top_srcdir)/src/pq/libtalerpq.la \ - -lgnunetutil \ - -ljansson \ - -lpq - -test_mintdb_keyio_SOURCES = \ - test_mintdb_keyio.c -test_mintdb_keyio_LDADD = \ - libtalermintdb.la \ - $(top_srcdir)/src/util/libtalerutil.la \ - $(top_srcdir)/src/pq/libtalerpq.la \ - -lgnunetutil - -test_mintdb_postgres_SOURCES = \ - test_mintdb.c -test_mintdb_postgres_LDADD = \ - libtalermintdb.la \ - $(top_srcdir)/src/util/libtalerutil.la \ - $(top_srcdir)/src/pq/libtalerpq.la \ - -lgnunetutil -ljansson - -test_perf_taler_mintdb_SOURCES = \ - test_perf_taler_mintdb.c \ - perf_taler_mintdb_init.c \ - perf_taler_mintdb_interpreter.c -test_perf_taler_mintdb_LDADD = \ - libtalermintdb.la \ - $(top_srcdir)/src/util/libtalerutil.la \ - $(top_srcdir)/src/pq/libtalerpq.la \ - -ljansson \ - -lgnunetutil - -perf_mintdb_SOURCES = \ - perf_taler_mintdb.c \ - perf_taler_mintdb_init.c \ - perf_taler_mintdb_interpreter.c -perf_mintdb_LDADD = \ - libtalermintdb.la \ - $(top_srcdir)/src/util/libtalerutil.la \ - $(top_srcdir)/src/pq/libtalerpq.la \ - -ljansson \ - -lgnunetutil - - -EXTRA_test_mintdb_postgres_DEPENDENCIES = \ - libtaler_plugin_mintdb_postgres.la diff --git a/src/mintdb/mintdb_keyio.c b/src/mintdb/mintdb_keyio.c deleted file mode 100644 index 89ac9055a..000000000 --- a/src/mintdb/mintdb_keyio.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file mintdb/mintdb_keyio.c - * @brief I/O operations for the Mint's private keys - * @author Florian Dold - * @author Benedikt Mueller - * @author Sree Harsha Totakura - * @author Christian Grothoff - */ -#include "platform.h" -#include "taler_mintdb_lib.h" - - -/** - * Closure for the #signkeys_iterate_dir_iter(). - */ -struct SignkeysIterateContext -{ - - /** - * Function to call on each signing key. - */ - TALER_MINTDB_SigningKeyIterator it; - - /** - * Closure for @e it. - */ - void *it_cls; -}; - - -/** - * Function called on each file in the directory with our signing - * keys. Parses the file and calls the iterator from @a cls. - * - * @param cls the `struct SignkeysIterateContext *` - * @param filename name of the file to parse - * @return #GNUNET_OK to continue, - * #GNUNET_NO to stop iteration without error, - * #GNUNET_SYSERR to stop iteration with error - */ -static int -signkeys_iterate_dir_iter (void *cls, - const char *filename) -{ - struct SignkeysIterateContext *skc = cls; - ssize_t nread; - struct TALER_MINTDB_PrivateSigningKeyInformationP issue; - - nread = GNUNET_DISK_fn_read (filename, - &issue, - sizeof (struct TALER_MINTDB_PrivateSigningKeyInformationP)); - if (nread != sizeof (struct TALER_MINTDB_PrivateSigningKeyInformationP)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid signkey file `%s': wrong size (%d, expected %u)\n", - filename, - (int) nread, - sizeof (struct TALER_MINTDB_PrivateSigningKeyInformationP)); - return GNUNET_OK; - } - return skc->it (skc->it_cls, - filename, - &issue); -} - - -/** - * Call @a it for each signing key found in the @a mint_base_dir. - * - * @param mint_base_dir base directory for the mint, - * the signing keys must be in the #TALER_MINTDB_DIR_SIGNING_KEYS - * subdirectory - * @param it function to call on each signing key - * @param it_cls closure for @a it - * @return number of files found (may not match - * number of keys given to @a it as malformed - * files are simply skipped), -1 on error - */ -int -TALER_MINTDB_signing_keys_iterate (const char *mint_base_dir, - TALER_MINTDB_SigningKeyIterator it, - void *it_cls) -{ - char *signkey_dir; - struct SignkeysIterateContext skc; - int ret; - - GNUNET_asprintf (&signkey_dir, - "%s" DIR_SEPARATOR_STR TALER_MINTDB_DIR_SIGNING_KEYS, - mint_base_dir); - skc.it = it; - skc.it_cls = it_cls; - ret = GNUNET_DISK_directory_scan (signkey_dir, - &signkeys_iterate_dir_iter, - &skc); - GNUNET_free (signkey_dir); - return ret; -} - - -/** - * Import a denomination key from the given file. - * - * @param filename the file to import the key from - * @param[out] dki set to the imported denomination key - * @return #GNUNET_OK upon success; - * #GNUNET_SYSERR upon failure - */ -int -TALER_MINTDB_denomination_key_read (const char *filename, - struct TALER_MINTDB_DenominationKeyIssueInformation *dki) -{ - uint64_t size; - size_t offset; - void *data; - struct GNUNET_CRYPTO_rsa_PrivateKey *priv; - - if (GNUNET_OK != GNUNET_DISK_file_size (filename, - &size, - GNUNET_YES, - GNUNET_YES)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Skipping inaccessable denomination key file `%s'\n", - filename); - return GNUNET_SYSERR; - } - offset = sizeof (struct TALER_MINTDB_DenominationKeyInformationP); - if (size <= offset) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - data = GNUNET_malloc (size); - if (size != - GNUNET_DISK_fn_read (filename, - data, - size)) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, - "read", - filename); - GNUNET_free (data); - return GNUNET_SYSERR; - } - if (NULL == - (priv = GNUNET_CRYPTO_rsa_private_key_decode (data + offset, - size - offset))) - { - GNUNET_free (data); - return GNUNET_SYSERR; - } - GNUNET_assert (NULL == dki->denom_priv.rsa_private_key); - dki->denom_priv.rsa_private_key = priv; - dki->denom_pub.rsa_public_key - = GNUNET_CRYPTO_rsa_private_key_get_public (priv); - memcpy (&dki->issue, - data, - offset); - GNUNET_free (data); - return GNUNET_OK; -} - - -/** - * Exports a denomination key to the given file. - * - * @param filename the file where to write the denomination key - * @param dki the denomination key - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure. - */ -int -TALER_MINTDB_denomination_key_write (const char *filename, - const struct TALER_MINTDB_DenominationKeyIssueInformation *dki) -{ - char *priv_enc; - size_t priv_enc_size; - struct GNUNET_DISK_FileHandle *fh; - ssize_t wrote; - size_t wsize; - int ret; - - fh = NULL; - priv_enc_size - = GNUNET_CRYPTO_rsa_private_key_encode (dki->denom_priv.rsa_private_key, - &priv_enc); - ret = GNUNET_SYSERR; - if (NULL == (fh = GNUNET_DISK_file_open - (filename, - GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE, - GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))) - goto cleanup; - wsize = sizeof (struct TALER_MINTDB_DenominationKeyInformationP); - if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh, - &dki->issue, - wsize))) - goto cleanup; - if (wrote != wsize) - goto cleanup; - if (GNUNET_SYSERR == - (wrote = GNUNET_DISK_file_write (fh, - priv_enc, - priv_enc_size))) - goto cleanup; - if (wrote != priv_enc_size) - goto cleanup; - ret = GNUNET_OK; - cleanup: - GNUNET_free_non_null (priv_enc); - if (NULL != fh) - (void) GNUNET_DISK_file_close (fh); - return ret; -} - - -/** - * Closure for #denomkeys_iterate_keydir_iter() and - * #denomkeys_iterate_topdir_iter(). - */ -struct DenomkeysIterateContext -{ - - /** - * Set to the name of the directory below the top-level directory - * during the call to #denomkeys_iterate_keydir_iter(). - */ - const char *alias; - - /** - * Function to call on each denomination key. - */ - TALER_MINTDB_DenominationKeyIterator it; - - /** - * Closure for @e it. - */ - void *it_cls; -}; - - -/** - * Decode the denomination key in the given file @a filename and call - * the callback in @a cls with the information. - * - * @param cls the `struct DenomkeysIterateContext *` - * @param filename name of a file that should contain - * a denomination key - * @return #GNUNET_OK to continue to iterate - * #GNUNET_NO to abort iteration with success - * #GNUNET_SYSERR to abort iteration with failure - */ -static int -denomkeys_iterate_keydir_iter (void *cls, - const char *filename) -{ - struct DenomkeysIterateContext *dic = cls; - struct TALER_MINTDB_DenominationKeyIssueInformation issue; - int ret; - - memset (&issue, 0, sizeof (issue)); - if (GNUNET_OK != - TALER_MINTDB_denomination_key_read (filename, - &issue)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid denomkey file: '%s'\n", - filename); - return GNUNET_OK; - } - ret = dic->it (dic->it_cls, - dic->alias, - &issue); - GNUNET_CRYPTO_rsa_private_key_free (issue.denom_priv.rsa_private_key); - GNUNET_CRYPTO_rsa_public_key_free (issue.denom_pub.rsa_public_key); - return ret; -} - - -/** - * Function called on each subdirectory in the #TALER_MINTDB_DIR_DENOMINATION_KEYS. Will - * call the #denomkeys_iterate_keydir_iter() on each file in the - * subdirectory. - * - * @param cls the `struct DenomkeysIterateContext *` - * @param filename name of the subdirectory to scan - * @return #GNUNET_OK on success, - * #GNUNET_SYSERR if we need to abort - */ -static int -denomkeys_iterate_topdir_iter (void *cls, - const char *filename) -{ - struct DenomkeysIterateContext *dic = cls; - - dic->alias = GNUNET_STRINGS_get_short_name (filename); - if (0 > GNUNET_DISK_directory_scan (filename, - &denomkeys_iterate_keydir_iter, - dic)) - return GNUNET_SYSERR; - return GNUNET_OK; -} - - -/** - * Call @a it for each denomination key found in the @a mint_base_dir. - * - * @param mint_base_dir base directory for the mint, - * the signing keys must be in the #TALER_MINTDB_DIR_DENOMINATION_KEYS - * subdirectory - * @param it function to call on each denomination key found - * @param it_cls closure for @a it - * @return -1 on error, 0 if no files were found, otherwise - * a positive number (however, even with a positive - * number it is possible that @a it was never called - * as maybe none of the files were well-formed) - */ -int -TALER_MINTDB_denomination_keys_iterate (const char *mint_base_dir, - TALER_MINTDB_DenominationKeyIterator it, - void *it_cls) -{ - char *dir; - struct DenomkeysIterateContext dic; - int ret; - - GNUNET_asprintf (&dir, - "%s" DIR_SEPARATOR_STR TALER_MINTDB_DIR_DENOMINATION_KEYS, - mint_base_dir); - dic.it = it; - dic.it_cls = it_cls; - ret = GNUNET_DISK_directory_scan (dir, - &denomkeys_iterate_topdir_iter, - &dic); - GNUNET_free (dir); - return ret; -} - - -/** - * Closure for #auditor_iter() and - */ -struct AuditorIterateContext -{ - - /** - * Function to call with the information for each auditor. - */ - TALER_MINTDB_AuditorIterator it; - - /** - * Closure for @e it. - */ - void *it_cls; -}; - - -GNUNET_NETWORK_STRUCT_BEGIN - -/** - * Header of a file with auditing information. - */ -struct AuditorFileHeaderP -{ - - /** - * Public key of the auditor. - */ - struct TALER_AuditorPublicKeyP apub; - - /** - * Master public key of the mint the auditor is signing - * information for. - */ - struct TALER_MasterPublicKeyP mpub; - -}; -GNUNET_NETWORK_STRUCT_END - - -/** - * Load the auditor signature and the information signed by the - * auditor and call the callback in @a cls with the information. - * - * @param cls the `struct AuditorIterateContext *` - * @param filename name of a file that should contain - * a denomination key - * @return #GNUNET_OK to continue to iterate - * #GNUNET_NO to abort iteration with success - * #GNUNET_SYSERR to abort iteration with failure - */ -static int -auditor_iter (void *cls, - const char *filename) -{ - struct AuditorIterateContext *aic = cls; - uint64_t size; - struct AuditorFileHeaderP *af; - const struct TALER_AuditorSignatureP *sigs; - const struct TALER_DenominationKeyValidityPS *dki; - unsigned int len; - int ret; - - if (GNUNET_OK != GNUNET_DISK_file_size (filename, - &size, - GNUNET_YES, - GNUNET_YES)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Skipping inaccessable auditor information file `%s'\n", - filename); - return GNUNET_SYSERR; - } - if ( (size < sizeof (struct AuditorFileHeaderP)) || - (0 != (len = ((size - sizeof (struct AuditorFileHeaderP)) % - (sizeof (struct TALER_DenominationKeyValidityPS) + - sizeof (struct TALER_AuditorSignatureP))))) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - af = GNUNET_malloc (size); - if (size != - GNUNET_DISK_fn_read (filename, - af, - size)) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, - "read", - filename); - GNUNET_free (af); - return GNUNET_SYSERR; - } - sigs = (const struct TALER_AuditorSignatureP *) &af[1]; - dki = (const struct TALER_DenominationKeyValidityPS *) &sigs[len]; - ret = aic->it (aic->it_cls, - &af->apub, - &af->mpub, - len, - sigs, - dki); - GNUNET_free (af); - return ret; -} - - -/** - * Call @a it with information for each auditor found in the @a mint_base_dir. - * - * @param mint_base_dir base directory for the mint, - * the signing keys must be in the #TALER_MINTDB_DIR_DENOMINATION_KEYS - * subdirectory - * @param it function to call with auditor information - * @param it_cls closure for @a it - * @return -1 on error, 0 if no files were found, otherwise - * a positive number (however, even with a positive - * number it is possible that @a it was never called - * as maybe none of the files were well-formed) - */ -int -TALER_MINTDB_auditor_iterate (const char *mint_base_dir, - TALER_MINTDB_AuditorIterator it, - void *it_cls) -{ - char *dir; - struct AuditorIterateContext aic; - int ret; - - GNUNET_asprintf (&dir, - "%s" DIR_SEPARATOR_STR TALER_MINTDB_DIR_AUDITORS, - mint_base_dir); - aic.it = it; - aic.it_cls = it_cls; - ret = GNUNET_DISK_directory_scan (dir, - &auditor_iter, - &aic); - GNUNET_free (dir); - return ret; -} - - -/** - * Write auditor information to the given file. - * - * @param filename the file where to write the auditor information to - * @param apub the auditor's public key - * @param asigs the auditor's signatures, array of length @a dki_len - * @param mpub the mint's public key (as expected by the auditor) - * @param dki_len length of @a dki - * @param dki array of denomination coin data signed by the auditor - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure. - */ -int -TALER_MINTDB_auditor_write (const char *filename, - const struct TALER_AuditorPublicKeyP *apub, - const struct TALER_AuditorSignatureP *asigs, - const struct TALER_MasterPublicKeyP *mpub, - unsigned int dki_len, - const struct TALER_DenominationKeyValidityPS *dki) -{ - struct AuditorFileHeaderP af; - struct GNUNET_DISK_FileHandle *fh; - ssize_t wrote; - size_t wsize; - int ret; - int eno; - - af.apub = *apub; - af.mpub = *mpub; - ret = GNUNET_SYSERR; - if (NULL == (fh = GNUNET_DISK_file_open - (filename, - GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE, - GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))) - goto cleanup; - wsize = sizeof (struct AuditorFileHeaderP); - if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh, - &af, - wsize))) - goto cleanup; - if (wrote != wsize) - goto cleanup; - wsize = dki_len * sizeof (struct TALER_AuditorSignatureP); - if (wsize == - GNUNET_DISK_file_write (fh, - asigs, - wsize)) - ret = GNUNET_OK; - wsize = dki_len * sizeof (struct TALER_DenominationKeyValidityPS); - if (wsize == - GNUNET_DISK_file_write (fh, - dki, - wsize)) - ret = GNUNET_OK; - cleanup: - eno = errno; - if (NULL != fh) - (void) GNUNET_DISK_file_close (fh); - errno = eno; - return ret; -} - - -/* end of mintdb_keyio.c */ diff --git a/src/mintdb/mintdb_plugin.c b/src/mintdb/mintdb_plugin.c deleted file mode 100644 index 4a0f1dc04..000000000 --- a/src/mintdb/mintdb_plugin.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file mintdb/mintdb_plugin.c - * @brief Logic to load database plugin - * @author Christian Grothoff - * @author Sree Harsha Totakura <sreeharsha@totakura.in> - */ -#include "platform.h" -#include "taler_mintdb_plugin.h" -#include <ltdl.h> - - -/** - * Initialize the plugin. - * - * @param cfg configuration to use - * @return #GNUNET_OK on success - */ -struct TALER_MINTDB_Plugin * -TALER_MINTDB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - char *plugin_name; - char *lib_name; - struct GNUNET_CONFIGURATION_Handle *cfg_dup; - struct TALER_MINTDB_Plugin *plugin; - - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_string (cfg, - "mint", - "db", - &plugin_name)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "mint", - "db"); - return NULL; - } - (void) GNUNET_asprintf (&lib_name, - "libtaler_plugin_mintdb_%s", - plugin_name); - GNUNET_free (plugin_name); - cfg_dup = GNUNET_CONFIGURATION_dup (cfg); - plugin = GNUNET_PLUGIN_load (lib_name, cfg_dup); - if (NULL != plugin) - plugin->library_name = lib_name; - else - GNUNET_free (lib_name); - GNUNET_CONFIGURATION_destroy (cfg_dup); - return plugin; -} - - -/** - * Shutdown the plugin. - * - * @param plugin the plugin to unload - */ -void -TALER_MINTDB_plugin_unload (struct TALER_MINTDB_Plugin *plugin) -{ - char *lib_name; - - if (NULL == plugin) - return; - lib_name = plugin->library_name; - GNUNET_assert (NULL == GNUNET_PLUGIN_unload (lib_name, - plugin)); - GNUNET_free (lib_name); -} - - - -/* end of mintdb_plugin.c */ diff --git a/src/mintdb/perf_taler_mintdb.c b/src/mintdb/perf_taler_mintdb.c deleted file mode 100644 index fbaa2ce34..000000000 --- a/src/mintdb/perf_taler_mintdb.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> - */ -/** - * @file mintdb/perf_taler_mintdb.c - * @brief Mint database performance analysis - * @author Nicolas Fournier - */ -#include "platform.h" -#include "perf_taler_mintdb_interpreter.h" - - -#define NB_DENOMINATION_INIT 15 -#define NB_DENOMINATION_SAVE 15 - -#define SMALL 1000 -#define BIG 10000 -#define BIGGER 100000 - -#define NB_RESERVE_INIT BIGGER -#define NB_RESERVE_SAVE BIG - -#define NB_DEPOSIT_INIT BIGGER -#define NB_DEPOSIT_SAVE BIG - -#define NB_WITHDRAW_INIT BIGGER -#define NB_WITHDRAW_SAVE BIG - -#define NB_REFRESH_INIT BIGGER -#define NB_REFRESH_SAVE BIG - -#define NB_MELT_INIT BIG -#define NB_MELT_SAVE SMALL - -/** - * Runs the performances tests for the mint database - * and logs the results using Gauger - */ -int -main (int argc, char ** argv) -{ - int ret; - struct PERF_TALER_MINTDB_Cmd benchmark[] = - { - /* Denomination used to create coins */ - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("Initializing database"), - - PERF_TALER_MINTDB_INIT_CMD_LOOP ("01 - denomination loop", - NB_DENOMINATION_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_CREATE_DENOMINATION ("01 - denomination"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_DENOMINATION ("01 - insert", - "01 - denomination"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("01 - save denomination", - "01 - denomination loop", - "01 - denomination", - NB_DENOMINATION_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("01 - end", - "01 - denomination loop"), - /* End of initialization */ - /* Reserve initialization */ - PERF_TALER_MINTDB_INIT_CMD_LOOP ("02 - init reserve loop", - NB_RESERVE_INIT), - PERF_TALER_MINTDB_INIT_CMD_CREATE_RESERVE ("02 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_RESERVE ("02 - insert", - "02 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("02 - save reserve", - "02 - init reserve loop", - "02 - reserve", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("02 - end", - "02 - init reserve loop"), - /* End reserve init */ - /* Withdrawal initialization */ - PERF_TALER_MINTDB_INIT_CMD_LOOP ("03 - init withdraw loop", - NB_WITHDRAW_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("03 - denomination load", - "03 - init withdraw loop", - "01 - save denomination"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("03 - reserve load", - "03 - init withdraw loop", - "02 - save reserve"), - PERF_TALER_MINTDB_INIT_CMD_CREATE_WITHDRAW ("03 - withdraw", - "03 - denomination load", - "03 - reserve load"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_WITHDRAW ("03 - insert", - "03 - withdraw"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("03 - save coin", - "03 - init withdraw loop", - "03 - withdraw", - NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("03 - end", - "03 - init withdraw loop"), - /*End of withdrawal initialization */ - /*Deposit initialization */ - PERF_TALER_MINTDB_INIT_CMD_LOOP ("04 - deposit init loop", - NB_DEPOSIT_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("04 - coin load", - "04 - deposit init loop", - "03 - save coin"), - PERF_TALER_MINTDB_INIT_CMD_CREATE_DEPOSIT ("04 - deposit", - "04 - coin load"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_DEPOSIT ("04 - insert", - "04 - deposit"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("04 - deposit array", - "04 - deposit init loop", - "04 - deposit", - NB_DEPOSIT_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "04 - deposit init loop"), - /* End of deposit initialization */ - /* Session initialization */ - PERF_TALER_MINTDB_INIT_CMD_LOOP ("05 - refresh session init loop", - NB_REFRESH_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_CREATE_REFRESH_SESSION ("05 - refresh session"), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("05 - session array", - "05 - refresh session init loop", - "05 - refresh session", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("05 - end", - "05 - refresh session init loop"), - /* End of refresh session initialization */ - /* Refresh melt initialization */ - PERF_TALER_MINTDB_INIT_CMD_LOOP ("06 - refresh melt init loop", - NB_MELT_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION (""), - /* TODO: initialize using coins & sessions created localy - * in order to make sure the same coin are not melted twice*/ - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("06 - session hash", - "06 - refresh melt init loop", - "05 - session array"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("06 - coin", - "06 - refresh melt init loop", - "03 - save coin"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_REFRESH_MELT ("06 - refresh melt", - "06 - session hash", - "06 - coin"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("06 - end", - "06 - refresh melt init loop"), - /* End of refresh melt initialization */ - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("End of initialization"), - - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("Start of performances measuring"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("21 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("21 - reserve insert measure", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_CREATE_RESERVE ("21 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_RESERVE ("21 - insert", - "21 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "21 - reserve insert measure"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("21 - stop"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("21 - gauger", - "21 - start", - "21 - stop", - "POSTGRES", - "Number of reserve inserted per second", - "item/sec", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("End of reserve insertion"), - - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("22 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("22 - reserve load measure", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("22 - reserve", - "22 - reserve load measure", - "02 - save reserve"), - PERF_TALER_MINTDB_INIT_CMD_GET_RESERVE ("22 - get", - "22 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "22 - reserve load measure"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("22 - stop"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("", - "22 - start", - "22 - stop", - "POSTGRES", - "Number of reserve loaded per second", - "item/sec", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("End of reserve retreival"), - - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("23 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("23 - reserve history measure", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("23 - reserve", - "23 - reserve history measure", - "02 - save reserve"), - PERF_TALER_MINTDB_INIT_CMD_GET_RESERVE_HISTORY ("", - "23 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "23 - reserve history measure"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("23 - stop"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("", - "23 - start", - "23 - stop", - "POSTGRES", - "Number of reserve history loaded per second", - "item/sec", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("End of reserve history access"), - - - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("24 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("24 - withdraw insert measure", - NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("24 - reserve", - "24 - withdraw insert measure", - "02 - save reserve"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("24 - denomination", - "24 - withdraw insert measure", - "01 - save denomination"), - PERF_TALER_MINTDB_INIT_CMD_CREATE_WITHDRAW ("24 - withdraw", - "24 - denomination", - "24 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_WITHDRAW ("24 - insert", - "24 - withdraw"), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "24 - withdraw insert measure"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("24 - stop"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("", - "24 - start", - "24 - stop", - "POSTGRES", - "Number of withdraw insert per second", - "item/sec", - NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("End of withdraw insertion"), - - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("25 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("25 - withdraw insert measure", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("25 - coin", - "25 - withdraw insert measure", - "03 - save coin"), - PERF_TALER_MINTDB_INIT_CMD_GET_WITHDRAW ("", - "25 - coin"), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "25 - withdraw insert measure"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("25 - stop"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("", - "25 - start", - "25 - stop", - "POSTGRES", - "Number of withdraw loaded per second", - "item/sec", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("End of withdraw loading"), - - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("26 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("26 - get coin transaction", - NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("26 - coin", - "26 - get coin transaction", - "03 - save coin"), - PERF_TALER_MINTDB_INIT_CMD_GET_COIN_TRANSACTION("", - "26 - coin"), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "26 - get coin transaction"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("26 - end"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("", - "26 - start", - "26 - end", - "POSTGRES", - "Number of coin transaction history loaded per second", - "item/sec", - NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("End of transaction loading"), - - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("27 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("27 - /reserve/withdraw", - NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("27 - reserve", - "27 - /reserve/withdraw", - "02 - save reserve"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("27 - dki", - "27 - /reserve/withdraw", - "01 - save denomination"), - PERF_TALER_MINTDB_INIT_CMD_WITHDRAW_SIGN ("", - "27 - dki", - "27 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "27 - /reserve/withdraw"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("27 - end"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("", - "27 - start", - "27 - end", - "POSTGRES", - "Number of /reserve/withdraw per second", - "item/sec", - NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("End of /reserve/withdraw"), - - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("28 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("28 - /deposit", - NB_DEPOSIT_SAVE), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("28 - coin", - "28 - /deposit", - "03 - save coin"), - PERF_TALER_MINTDB_INIT_CMD_DEPOSIT ("28 - deposit", - "28 - coin"), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "28 - /deposit"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("28 - stop"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("", - "28 - start", - "28 - stop", - "POSTGRES", - "Number of /deposit per second", - "item/sec", - NB_DEPOSIT_SAVE), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("29 - start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("29 - insert refresh session", - NB_REFRESH_SAVE), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_CREATE_REFRESH_SESSION (""), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "29 - insert refresh session"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("29 - stop"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("", - "29 - start", - "29 - stop", - "POSTGRES", - "Number of refresh session inserted per second", - "item/sec", - NB_REFRESH_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END (""), - }; - - ret = PERF_TALER_MINTDB_run_benchmark ( - "perf-taler-mintdb", - "./test-mint-db-postgres.conf", - (struct PERF_TALER_MINTDB_Cmd []) {PERF_TALER_MINTDB_INIT_CMD_END("")}, - benchmark); - if (GNUNET_SYSERR == ret) - return 1; - return 0; -} diff --git a/src/mintdb/perf_taler_mintdb_init.c b/src/mintdb/perf_taler_mintdb_init.c deleted file mode 100644 index ccfc6a05a..000000000 --- a/src/mintdb/perf_taler_mintdb_init.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> - */ -/** - * @file mintdb/perf_taler_mintdb_init.c - * @brief Interpreter library for mint database performance analysis - * @author Nicolas Fournier - */ -#include "platform.h" -#include "perf_taler_mintdb_init.h" -#include <gnunet/gnunet_signatures.h> -#include "taler_signatures.h" -#include "taler_amount_lib.h" - - -#define CURRENCY "EUR" -#define PERF_TALER_MINTDB_RSA_SIZE 512 - - -/** - * Generate a dummy DenominationKeyInformation for testing purposes - * @return a dummy denomination key - */ -struct TALER_MINTDB_DenominationKeyIssueInformation * -PERF_TALER_MINTDB_denomination_init () -{ - struct GNUNET_CRYPTO_EddsaPrivateKey *master_prvt; - struct TALER_MINTDB_DenominationKeyIssueInformation *dki; - struct TALER_DenominationPrivateKey denom_priv; - struct TALER_DenominationPublicKey denom_pub; - struct TALER_MINTDB_DenominationKeyInformationP issue; - - master_prvt = GNUNET_CRYPTO_eddsa_key_create(); - - dki = GNUNET_new (struct TALER_MINTDB_DenominationKeyIssueInformation); - GNUNET_assert (NULL != dki); - denom_priv.rsa_private_key - = GNUNET_CRYPTO_rsa_private_key_create (PERF_TALER_MINTDB_RSA_SIZE); - GNUNET_assert (NULL != denom_priv.rsa_private_key); - denom_pub.rsa_public_key = - GNUNET_CRYPTO_rsa_private_key_get_public (denom_priv.rsa_private_key); - GNUNET_assert (NULL != denom_pub.rsa_public_key); - {/* issue */ - struct TALER_MasterSignatureP signature; - struct TALER_DenominationKeyValidityPS properties; - - {/* properties */ - struct TALER_Amount amount; - - properties.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY); - properties.purpose.size = htonl (sizeof (struct TALER_DenominationKeyValidityPS)); - GNUNET_CRYPTO_eddsa_key_get_public (master_prvt, - &properties.master.eddsa_pub); - properties.start = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get()); - properties.expire_withdraw = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); - properties.expire_spend = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); - properties.expire_legal = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":1.1", &amount)); - TALER_amount_hton (&properties.value, &amount); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":0.1", &amount)); - TALER_amount_hton (&properties.fee_withdraw, &amount); - TALER_amount_hton (&properties.fee_deposit, &amount); - TALER_amount_hton (&properties.fee_refresh, &amount); - GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key, - &properties.denom_hash); - issue.properties = properties; - } - {/* signature */ - GNUNET_CRYPTO_eddsa_sign (master_prvt, - &properties.purpose, - &signature.eddsa_signature); - issue.signature = signature; - } - } - dki->denom_priv = denom_priv; - dki->denom_pub = denom_pub; - dki->issue = issue; - GNUNET_free (master_prvt); - return dki; -} - - -/** - * Copies the given denomination - * @param reserve the deposit copy - * @return a copy of @a deposit; NULL if error - */ -struct TALER_MINTDB_DenominationKeyIssueInformation * -PERF_TALER_MINTDB_denomination_copy (const struct TALER_MINTDB_DenominationKeyIssueInformation *dki) -{ - struct TALER_MINTDB_DenominationKeyIssueInformation *copy; - - GNUNET_assert (NULL != - (copy = GNUNET_new (struct TALER_MINTDB_DenominationKeyIssueInformation))); - {/* denom_priv */ - copy->denom_priv.rsa_private_key = - GNUNET_CRYPTO_rsa_private_key_dup ( dki->denom_priv.rsa_private_key); - } - {/* denom_pub */ - copy->denom_pub.rsa_public_key = - GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key); - } - {/* issue */ - copy->issue.properties = dki->issue.properties; - copy->issue.signature = dki->issue.signature; - } - return copy; -} - - -/** - * Free memory of a DenominationKeyIssueInformation - * @param dki pointer to the struct to free - */ -int -PERF_TALER_MINTDB_denomination_free (struct TALER_MINTDB_DenominationKeyIssueInformation *dki) -{ - if (NULL == dki) - return GNUNET_OK; - GNUNET_CRYPTO_rsa_private_key_free (dki->denom_priv.rsa_private_key); - GNUNET_CRYPTO_rsa_public_key_free (dki->denom_pub.rsa_public_key); - - GNUNET_free (dki); - return GNUNET_OK; -} - - -/** - * Generate a dummy reserve for testing - * @return a reserve with 1000 EUR in it - */ -struct PERF_TALER_MINTDB_Reserve * -PERF_TALER_MINTDB_reserve_init () -{ - struct PERF_TALER_MINTDB_Reserve *reserve; - - GNUNET_assert (NULL != - (reserve = GNUNET_new (struct PERF_TALER_MINTDB_Reserve))); - {/* private */ - struct GNUNET_CRYPTO_EddsaPrivateKey *private; - private = GNUNET_CRYPTO_eddsa_key_create (); - GNUNET_assert (NULL != private); - reserve->private = *private; - GNUNET_free (private); - } - - GNUNET_CRYPTO_eddsa_key_get_public (&reserve->private, - &reserve->reserve.pub.eddsa_pub); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":1000", &reserve->reserve.balance)); - reserve->reserve.expiry = GNUNET_TIME_absolute_get_forever_ (); - return reserve; -} - - -/** - * Copies the given reserve - * @param reserve the reserve to copy - * @return a copy of @a reserve; NULL if error - */ -struct PERF_TALER_MINTDB_Reserve * -PERF_TALER_MINTDB_reserve_copy (const struct PERF_TALER_MINTDB_Reserve *reserve) -{ - struct PERF_TALER_MINTDB_Reserve *copy; - GNUNET_assert (NULL != - (copy = GNUNET_new (struct PERF_TALER_MINTDB_Reserve))); - *copy = *reserve; - return copy; -} - - -/** - * Free memory of a reserve - * @param reserve pointer to the structure to be freed - */ -int -PERF_TALER_MINTDB_reserve_free (struct PERF_TALER_MINTDB_Reserve *reserve) -{ - if (NULL == reserve) - return GNUNET_OK; - GNUNET_free (reserve); - return GNUNET_OK; -} - - -/** - * Generate a dummy deposit for testing purposes - * @param dki the denomination key used to sign the key - */ -struct TALER_MINTDB_Deposit * -PERF_TALER_MINTDB_deposit_init (const struct PERF_TALER_MINTDB_Coin *coin) -{ - struct TALER_MINTDB_Deposit *deposit; - struct TALER_CoinSpendSignatureP csig; - struct TALER_MerchantPublicKeyP merchant_pub; - struct GNUNET_HashCode h_contract; - struct GNUNET_HashCode h_wire; - const char wire[] = "{" - "\"type\":\"SEPA\"," - "\"IBAN\":\"DE67830654080004822650\"," - "\"NAME\":\"GNUNET E.\"," - "\"BIC\":\"GENODEF1SRL\"" - "}"; - static uint64_t transaction_id = 0; - struct GNUNET_TIME_Absolute timestamp; - struct GNUNET_TIME_Absolute refund_deadline; - struct TALER_Amount amount_with_fee; - struct TALER_Amount deposit_fee; - - GNUNET_assert (NULL != - (deposit = GNUNET_malloc (sizeof (struct TALER_MINTDB_Deposit) + sizeof (wire)))); - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, - &h_contract); - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, - &h_wire); - { //csig - struct u32_presign - { - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - struct GNUNET_HashCode h_wire; - struct GNUNET_HashCode h_contract; - } unsigned_data; - - unsigned_data.h_contract = h_contract; - unsigned_data.h_wire = h_wire; - unsigned_data.purpose.size = htonl (sizeof (struct u32_presign)); - unsigned_data.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST); - GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_eddsa_sign (&coin->priv, - &unsigned_data.purpose, - &csig.eddsa_signature)); - } - { //merchant_pub - struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_prv; - - eddsa_prv = GNUNET_CRYPTO_eddsa_key_create (); - GNUNET_assert(NULL != eddsa_prv); - GNUNET_CRYPTO_eddsa_key_get_public ( - eddsa_prv, - &merchant_pub.eddsa_pub); - GNUNET_free (eddsa_prv); - } - timestamp = GNUNET_TIME_absolute_get (); - refund_deadline = GNUNET_TIME_absolute_get (); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":1.1", - &amount_with_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":0.1", - &deposit_fee)); - { - deposit->coin.coin_pub = coin->public_info.coin_pub; - deposit->coin.denom_pub.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup ( - coin->public_info.denom_pub.rsa_public_key); - GNUNET_assert (NULL != coin->public_info.denom_pub.rsa_public_key); - deposit->coin.denom_sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup ( - coin->public_info.denom_sig.rsa_signature); - GNUNET_assert (NULL != coin->public_info.denom_sig.rsa_signature); - } - deposit->csig = csig; - deposit->h_contract = h_contract; - deposit->h_wire = h_wire; - deposit->wire = json_loads (wire, 0, NULL); - deposit->transaction_id = transaction_id++; - deposit->timestamp = timestamp; - deposit->refund_deadline = refund_deadline; - deposit->amount_with_fee = amount_with_fee; - deposit->deposit_fee = deposit_fee; - return deposit; -} - - -/** - * Copies the given deposit - * @param reserve the deposit copy - * @return a copy of @a deposit; NULL if error - */ -struct TALER_MINTDB_Deposit * -PERF_TALER_MINTDB_deposit_copy (const struct TALER_MINTDB_Deposit *deposit) -{ - struct TALER_MINTDB_Deposit *copy; - - copy = GNUNET_new (struct TALER_MINTDB_Deposit); - *copy = *deposit; - json_incref (copy->wire); - copy->coin.denom_pub.rsa_public_key = - GNUNET_CRYPTO_rsa_public_key_dup (deposit->coin.denom_pub.rsa_public_key); - copy->coin.denom_sig.rsa_signature = - GNUNET_CRYPTO_rsa_signature_dup (deposit->coin.denom_sig.rsa_signature); - return copy; -} - - -/** - * Free memory of a deposit - * @param deposit pointer to the structure to free - */ -int -PERF_TALER_MINTDB_deposit_free (struct TALER_MINTDB_Deposit *deposit) -{ - if (NULL == deposit) - return GNUNET_OK; - GNUNET_CRYPTO_rsa_public_key_free (deposit->coin.denom_pub.rsa_public_key); - GNUNET_CRYPTO_rsa_signature_free (deposit->coin.denom_sig.rsa_signature); - json_decref (deposit->wire); - GNUNET_free (deposit); - return GNUNET_OK; -} - - -/** - * Generate a CollectableBlindcoin for testing purpuses - * @param dki denomination key used to sign the coin - * @param reserve reserve providing the money for the coin - * @return a randomly generated CollectableBlindcoin - */ -struct PERF_TALER_MINTDB_Coin * -PERF_TALER_MINTDB_coin_init ( - const struct TALER_MINTDB_DenominationKeyIssueInformation *dki, - const struct PERF_TALER_MINTDB_Reserve *reserve) -{ - struct PERF_TALER_MINTDB_Coin *coin; - struct GNUNET_CRYPTO_EddsaPrivateKey *priv; - - coin = GNUNET_new (struct PERF_TALER_MINTDB_Coin); - GNUNET_assert (NULL != coin); - /* priv */ - - priv = GNUNET_CRYPTO_eddsa_key_create(); - GNUNET_assert (NULL != priv); - coin->priv = *priv; - GNUNET_free (priv); - - /* public_info */ - GNUNET_CRYPTO_eddsa_key_get_public (&coin->priv, - &coin->public_info.coin_pub.eddsa_pub); - coin->public_info.denom_pub.rsa_public_key = - GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key); - coin->public_info.denom_sig.rsa_signature = - GNUNET_CRYPTO_rsa_sign (dki->denom_priv.rsa_private_key, - &coin->public_info.coin_pub, - sizeof (struct TALER_CoinSpendPublicKeyP)); - GNUNET_assert (NULL != coin->public_info.denom_pub.rsa_public_key); - GNUNET_assert (NULL != coin->public_info.denom_sig.rsa_signature); - - /* blind */ - coin->blind.sig.rsa_signature = - GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature); - coin->blind.denom_pub.rsa_public_key = - GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key); - GNUNET_assert (NULL != coin->blind.sig.rsa_signature); - GNUNET_assert (NULL != coin->blind.denom_pub.rsa_public_key); - TALER_amount_ntoh (&coin->blind.amount_with_fee, - &dki->issue.properties.value); - TALER_amount_ntoh (&coin->blind.withdraw_fee, - &dki->issue.properties.fee_withdraw); - coin->blind.reserve_pub = reserve->reserve.pub; - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, - &coin->blind.h_coin_envelope); - - return coin; -} - - -/** - * Copies the given coin - * - * @param coin the coin to copy - * @return a copy of coin; NULL if error - */ -struct PERF_TALER_MINTDB_Coin * -PERF_TALER_MINTDB_coin_copy (const struct PERF_TALER_MINTDB_Coin *coin) -{ - struct PERF_TALER_MINTDB_Coin *copy; - - copy = GNUNET_new (struct PERF_TALER_MINTDB_Coin); - /* priv */ - copy->priv = coin->priv; - /* public_info */ - copy->public_info.coin_pub = coin->public_info.coin_pub; - copy->public_info.denom_pub.rsa_public_key = - GNUNET_CRYPTO_rsa_public_key_dup (coin->public_info.denom_pub.rsa_public_key); - copy->public_info.denom_sig.rsa_signature = - GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature); - - /* blind */ - copy->blind.sig.rsa_signature = - GNUNET_CRYPTO_rsa_signature_dup (coin->blind.sig.rsa_signature); - copy->blind.denom_pub.rsa_public_key = - GNUNET_CRYPTO_rsa_public_key_dup (coin->blind.denom_pub.rsa_public_key); - copy->blind.amount_with_fee = coin->blind.amount_with_fee; - copy->blind.withdraw_fee = coin->blind.withdraw_fee; - copy->blind.reserve_pub = coin->blind.reserve_pub; - copy->blind.h_coin_envelope = coin->blind.h_coin_envelope; - copy->blind.reserve_sig = coin->blind.reserve_sig; - - return copy; -} - - -/** - * Free memory of @a coin - * - * @param coin pointer to the structure to free - */ -int -PERF_TALER_MINTDB_coin_free (struct PERF_TALER_MINTDB_Coin *coin) -{ - if (NULL == coin) - return GNUNET_OK; - GNUNET_CRYPTO_rsa_public_key_free (coin->public_info.denom_pub.rsa_public_key); - GNUNET_CRYPTO_rsa_signature_free (coin->public_info.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_signature_free (coin->blind.sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (coin->blind.denom_pub.rsa_public_key); - GNUNET_free (coin); - return GNUNET_OK; -} - - -/** - * @return a randomly generated refresh session - */ -struct TALER_MINTDB_RefreshSession * -PERF_TALER_MINTDB_refresh_session_init () -{ - struct TALER_MINTDB_RefreshSession *refresh_session; - - GNUNET_assert (NULL != - (refresh_session = GNUNET_new (struct TALER_MINTDB_RefreshSession))); - refresh_session->noreveal_index = 1; - refresh_session->num_oldcoins = 1; - refresh_session->num_newcoins = 1; - - return refresh_session; -} - - -/** - * @return #GNUNET_OK if the copy was successful, #GNUNET_SYSERR if it wasn't - */ -int -PERF_TALER_MINTDB_refresh_session_copy (struct TALER_MINTDB_RefreshSession *session, - struct TALER_MINTDB_RefreshSession *copy) -{ - *copy = *session; - return GNUNET_OK; -} - - -/** - * Free a refresh session - */ -int -PERF_TALER_MINTDB_refresh_session_free (struct TALER_MINTDB_RefreshSession *refresh_session) -{ - if (NULL == refresh_session) - return GNUNET_OK; - GNUNET_free (refresh_session); - return GNUNET_OK; -} - - -/** - * Create a melt operation - * - * @param session the refresh session - * @param dki the denomination the melted coin uses - * @return a pointer to a #TALER_MINTDB_RefreshMelt - */ -struct TALER_MINTDB_RefreshMelt * -PERF_TALER_MINTDB_refresh_melt_init (struct GNUNET_HashCode *session, - struct PERF_TALER_MINTDB_Coin *coin) -{ - struct TALER_MINTDB_RefreshMelt *melt; - struct TALER_CoinSpendSignatureP coin_sig; - struct TALER_Amount amount; - struct TALER_Amount amount_with_fee; - - { - struct - { - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - struct GNUNET_HashCode session; - } to_sign; - - to_sign.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_TEST; - to_sign.purpose.size = htonl (sizeof (to_sign)); - to_sign.session = *session; - GNUNET_CRYPTO_eddsa_sign (&coin->priv, - &to_sign.purpose, - &coin_sig.eddsa_signature); - } - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":1.1", - &amount)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":0.1", - &amount_with_fee)); - melt = GNUNET_new (struct TALER_MINTDB_RefreshMelt); - melt->coin.coin_pub = coin->public_info.coin_pub; - melt->coin.denom_sig.rsa_signature = - GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature); - melt->coin.denom_pub.rsa_public_key = - GNUNET_CRYPTO_rsa_public_key_dup (coin->public_info.denom_pub.rsa_public_key); - GNUNET_assert (NULL != melt->coin.denom_pub.rsa_public_key); - GNUNET_assert (NULL != melt->coin.denom_sig.rsa_signature); - melt->coin_sig = coin_sig; - melt->session_hash = *session; - melt->amount_with_fee = amount; - melt->melt_fee = amount_with_fee; - return melt; -} - - -/** - * Copies the internals of a #TALER_MINTDB_RefreshMelt - * - * @param melt the refresh melt to copy - * @return an copy of @ melt - */ -struct TALER_MINTDB_RefreshMelt * -PERF_TALER_MINTDB_refresh_melt_copy (const struct TALER_MINTDB_RefreshMelt *melt) -{ - struct TALER_MINTDB_RefreshMelt *copy; - - copy = GNUNET_new (struct TALER_MINTDB_RefreshMelt); - *copy = *melt; - copy->coin.denom_sig.rsa_signature = - GNUNET_CRYPTO_rsa_signature_dup (melt->coin.denom_sig.rsa_signature); - GNUNET_assert (NULL != copy->coin.denom_sig.rsa_signature); - - return copy; -} - - -/** - * Free the internal memory of a #TALER_MINTDB_RefreshMelt - * - * @param melt the #TALER_MINTDB_RefreshMelt to free - * @return #GNUNET_OK if the operation was successful, #GNUNET_SYSERROR - */ -int -PERF_TALER_MINTDB_refresh_melt_free (struct TALER_MINTDB_RefreshMelt *melt) -{ - GNUNET_CRYPTO_rsa_signature_free (melt->coin.denom_sig.rsa_signature); - GNUNET_free (melt); - return GNUNET_OK; -} - - -/** - * Create a #TALER_MINTDB_RefreshCommitCoin - */ -struct TALER_MINTDB_RefreshCommitCoin * -PERF_TALER_MINTDB_refresh_commit_coin_init () -{ - struct TALER_MINTDB_RefreshCommitCoin *commit_coin; - struct TALER_RefreshLinkEncrypted refresh_link; - - commit_coin = GNUNET_new (struct TALER_MINTDB_RefreshCommitCoin); - GNUNET_assert (NULL != commit_coin); - {/* refresh_link */ - refresh_link = (struct TALER_RefreshLinkEncrypted) - { - .blinding_key_enc = "blinding_key", - .blinding_key_enc_size = 13 - }; - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - &refresh_link.coin_priv_enc, - sizeof(struct TALER_CoinSpendPrivateKeyP)); - } - commit_coin->coin_ev = "coin_ev"; - commit_coin->coin_ev_size = 8; - commit_coin->refresh_link = GNUNET_new (struct TALER_RefreshLinkEncrypted); - *commit_coin->refresh_link = refresh_link; - return commit_coin; -} - - -/** - * Copies a #TALER_MINTDB_RefreshCommitCoin - * - * @param commit_coin the commit to copy - * @return a copy of @a commit_coin - */ -struct TALER_MINTDB_RefreshCommitCoin * -PERF_TALER_MINTDB_refresh_commit_coin_copy (struct TALER_MINTDB_RefreshCommitCoin *commit_coin) -{ - struct TALER_MINTDB_RefreshCommitCoin *copy; - - copy = GNUNET_new (struct TALER_MINTDB_RefreshCommitCoin); - copy->refresh_link = GNUNET_new (struct TALER_RefreshLinkEncrypted); - *copy->refresh_link = *commit_coin->refresh_link; - return copy; -} - - -/** - * Free a #TALER_MINTDB_RefreshCommitCoin - * - * @param commit_coin the coin to free - */ -void -PERF_TALER_MINTDB_refresh_commit_coin_free (struct TALER_MINTDB_RefreshCommitCoin *commit_coin) -{ - GNUNET_free (commit_coin->refresh_link); - GNUNET_free (commit_coin); -} diff --git a/src/mintdb/perf_taler_mintdb_init.h b/src/mintdb/perf_taler_mintdb_init.h deleted file mode 100644 index f94beef10..000000000 --- a/src/mintdb/perf_taler_mintdb_init.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> - */ -/** - * @file mintdb/perf_taler_mintdb_init.h - * @brief Heler function for creating dummy inputs for the mint database - * @author Nicolas Fournier - */ -#ifndef __PERF_TALER_MINTDB_INIT_H___ -#define __PERF_TALER_MINTDB_INIT_H___ - -#include "taler_mintdb_plugin.h" - - -#define CURRENCY "EUR" - -/** - * All information about a reserve - */ -struct PERF_TALER_MINTDB_Reserve -{ - /** - * Information about a rserve available to the Mint - */ - struct TALER_MINTDB_Reserve reserve; - - /** - * Private key of a reserve - */ - struct GNUNET_CRYPTO_EddsaPrivateKey private; -}; - - -/** - * All informations about a coin - */ -struct PERF_TALER_MINTDB_Coin -{ - /** - * Blinded coin, known by the mint - */ - struct TALER_MINTDB_CollectableBlindcoin blind; - - /** - * Public key of the coin and othes informations - */ - struct TALER_CoinPublicInfo public_info; - - /** - * Private key of the coin - */ - struct GNUNET_CRYPTO_EddsaPrivateKey priv; -}; - - -/** - * Generate a dummy DenominationKeyInformation for testing purposes - * @return a dummy denomination key - */ -struct TALER_MINTDB_DenominationKeyIssueInformation * -PERF_TALER_MINTDB_denomination_init (void); - - -/** - * Copies the given denomination - * @param reserve the deposit copy - * @return a copy of @a deposit; NULL if error - */ -struct TALER_MINTDB_DenominationKeyIssueInformation * -PERF_TALER_MINTDB_denomination_copy ( - const struct TALER_MINTDB_DenominationKeyIssueInformation *dki); - - -/** - * Free memory of a DenominationKeyIssueInformation - * @param dki pointer to the struct to free - */ -int -PERF_TALER_MINTDB_denomination_free ( - struct TALER_MINTDB_DenominationKeyIssueInformation *dki); - - -/** - * Generate a dummy reserve for testing - * @return a reserve with 1000 EUR in it - */ -struct PERF_TALER_MINTDB_Reserve * -PERF_TALER_MINTDB_reserve_init (void); - - -/** - * Copies the given reserve - * @param reserve the reserve to copy - * @return a copy of @a reserve; NULL if error - */ -struct PERF_TALER_MINTDB_Reserve * -PERF_TALER_MINTDB_reserve_copy (const struct PERF_TALER_MINTDB_Reserve *reserve); - - -/** - * Free memory of a reserve - * @param reserve pointer to the structure to be freed - */ -int -PERF_TALER_MINTDB_reserve_free (struct PERF_TALER_MINTDB_Reserve *reserve); - - -/** - * Generate a dummy deposit for testing purposes - * @param dki the denomination key used to sign the key - */ -struct TALER_MINTDB_Deposit * -PERF_TALER_MINTDB_deposit_init ( - const struct PERF_TALER_MINTDB_Coin *coin); - - -/** - * Copies the given deposit - * @param reserve the deposit copy - * @return a copy of @a deposit; NULL if error - */ -struct TALER_MINTDB_Deposit * -PERF_TALER_MINTDB_deposit_copy (const struct TALER_MINTDB_Deposit *deposit); - - -/** - * Free memory of a deposit - * @param deposit pointer to the structure to free - */ -int -PERF_TALER_MINTDB_deposit_free (struct TALER_MINTDB_Deposit *deposit); - - -/** - * Generate a coin for testing purpuses - * @param dki denomination key used to sign the coin - * @param reserve reserve providing the money for the coin - * @return a randomly generated CollectableBlindcoin - */ -struct PERF_TALER_MINTDB_Coin * -PERF_TALER_MINTDB_coin_init ( - const struct TALER_MINTDB_DenominationKeyIssueInformation *dki, - const struct PERF_TALER_MINTDB_Reserve *reserve); - - -/** - * Copies the given coin - * @param coin the coin to copy - * @return a copy of coin; NULL if error - */ -struct PERF_TALER_MINTDB_Coin * -PERF_TALER_MINTDB_coin_copy ( - const struct PERF_TALER_MINTDB_Coin *coin); - - -/** - * Liberate memory of @a coin - * @param coin pointer to the structure to free - */ -int -PERF_TALER_MINTDB_coin_free ( - struct PERF_TALER_MINTDB_Coin *coin); - - -/** - * @return a randomly generated refresh session - */ -struct TALER_MINTDB_RefreshSession * -PERF_TALER_MINTDB_refresh_session_init (void); - - -/** - * @return #GNUNET_OK if the copy was successful, #GNUNET_SYSERR if it wasn't - */ -int -PERF_TALER_MINTDB_refresh_session_copy (struct TALER_MINTDB_RefreshSession *session, - struct TALER_MINTDB_RefreshSession *copy); - - -/** - * Frees memory of a refresh_session - */ -int -PERF_TALER_MINTDB_refresh_session_free ( - struct TALER_MINTDB_RefreshSession *refresh_session); - - -/** - * Create a melt operation - * - * @param session the refresh session - * @param dki the denomination the melted coin uses - * @return a pointer to a #TALER_MINTDB_RefreshMelt - */ -struct TALER_MINTDB_RefreshMelt * -PERF_TALER_MINTDB_refresh_melt_init (struct GNUNET_HashCode *session, - struct PERF_TALER_MINTDB_Coin *coin); - - -/** - * Copies the internals of a #TALER_MINTDB_RefreshMelt - * - * @param melt the refresh melt to copy - * @return an copy of @ melt - */ -struct TALER_MINTDB_RefreshMelt * -PERF_TALER_MINTDB_refresh_melt_copy (const struct TALER_MINTDB_RefreshMelt *melt); - - -/** - * Free the internal memory of a #TALER_MINTDB_RefreshMelt - * - * @param melt the #TALER_MINTDB_RefreshMelt to free - * @return #GNUNET_OK if the operation was successful, #GNUNET_SYSERROR - */ -int -PERF_TALER_MINTDB_refresh_melt_free (struct TALER_MINTDB_RefreshMelt *melt); - - -/** - * Create a #TALER_MINTDB_RefreshCommitCoin - */ -struct TALER_MINTDB_RefreshCommitCoin * -PERF_TALER_MINTDB_refresh_commit_coin_init (void); - - -/** - * Copies a #TALER_MINTDB_RefreshCommitCoin - * - * @param commit_coin the commit to copy - * @return a copy of @a commit_coin - */ -struct TALER_MINTDB_RefreshCommitCoin * -PERF_TALER_MINTDB_refresh_commit_coin_copy (struct TALER_MINTDB_RefreshCommitCoin *commit_coin); - - -/** - * Free a #TALER_MINTDB_RefreshCommitCoin - * - * @param commit_coin the coin to free - */ -void -PERF_TALER_MINTDB_refresh_commit_coin_free (struct TALER_MINTDB_RefreshCommitCoin *commit_coin); - -#endif diff --git a/src/mintdb/perf_taler_mintdb_interpreter.c b/src/mintdb/perf_taler_mintdb_interpreter.c deleted file mode 100644 index 293d5f35f..000000000 --- a/src/mintdb/perf_taler_mintdb_interpreter.c +++ /dev/null @@ -1,1998 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> - */ -/** - * @file mintdb/perf_taler_mintdb_interpreter.c - * @brief Interpreter library for mint database performance analysis - * @author Nicolas Fournier - */ -#include "platform.h" -#include "perf_taler_mintdb_interpreter.h" -#include "perf_taler_mintdb_init.h" -#include "gauger.h" - - -/** - * Represents the state of the interpreter - */ -struct PERF_TALER_MINTDB_interpreter_state -{ - /** - * State of the commands - */ - struct PERF_TALER_MINTDB_Cmd *cmd; - - /** - * Database plugin - */ - struct TALER_MINTDB_Plugin *plugin; - - /** - * Current database session - */ - struct TALER_MINTDB_Session *session; - - /** - * The current index of the interpreter - */ - unsigned int i; -}; - - -/** - * Free the memory of @a data - */ -static void -data_free (struct PERF_TALER_MINTDB_Data *data) -{ - switch (data->type) - { - case PERF_TALER_MINTDB_TIME: - if (NULL == data->data.time) - break; - GNUNET_free (data->data.time); - data->data.time = NULL; - break; - - case PERF_TALER_MINTDB_DEPOSIT: - if (NULL == data->data.deposit) - break; - PERF_TALER_MINTDB_deposit_free (data->data.deposit); - data->data.deposit = NULL; - break; - - case PERF_TALER_MINTDB_COIN: - if (NULL == data->data.coin) - break; - PERF_TALER_MINTDB_coin_free (data->data.coin); - data->data.coin = NULL; - break; - - case PERF_TALER_MINTDB_RESERVE: - if (NULL == data->data.reserve) - break; - PERF_TALER_MINTDB_reserve_free (data->data.reserve); - data->data.reserve = NULL; - break; - - case PERF_TALER_MINTDB_DENOMINATION_INFO: - if (NULL == data->data.dki) - break; - PERF_TALER_MINTDB_denomination_free (data->data.dki); - data->data.dki = NULL; - break; - - case PERF_TALER_MINTDB_REFRESH_HASH: - if (NULL == data->data.session_hash) - break; - GNUNET_free (data->data.session_hash); - data->data.session_hash = NULL; - break; - - case PERF_TALER_MINTDB_REFRESH_MELT: - if (NULL == data->data.refresh_melt) - break; - PERF_TALER_MINTDB_refresh_melt_free (data->data.refresh_melt); - data->data.refresh_melt = NULL; - break; - - case PERF_TALER_MINTDB_NONE: - break; - } -} - - -/** - * Copies @a data into @a copy - * - * @param data the data to be copied - * @param[out] copy the copy made - */ -static void -data_copy (const struct PERF_TALER_MINTDB_Data *data, - struct PERF_TALER_MINTDB_Data *copy) -{ - copy->type = data->type; - switch (data->type) - { - case PERF_TALER_MINTDB_TIME: - copy->data.time = GNUNET_new (struct GNUNET_TIME_Absolute); - *copy->data.time = *data->data.time; - return; - - case PERF_TALER_MINTDB_DEPOSIT: - copy->data.deposit - = PERF_TALER_MINTDB_deposit_copy (data->data.deposit); - return; - - case PERF_TALER_MINTDB_COIN: - copy->data.coin - = PERF_TALER_MINTDB_coin_copy (data->data.coin); - return; - - case PERF_TALER_MINTDB_RESERVE: - copy->data.reserve - = PERF_TALER_MINTDB_reserve_copy (data->data.reserve); - return; - - case PERF_TALER_MINTDB_DENOMINATION_INFO: - copy->data.dki - = PERF_TALER_MINTDB_denomination_copy (data->data.dki); - return; - - case PERF_TALER_MINTDB_REFRESH_HASH: - copy-> data.session_hash = GNUNET_new (struct GNUNET_HashCode); - *copy->data.session_hash - = *data->data.session_hash; - break; - - case PERF_TALER_MINTDB_REFRESH_MELT: - copy->data.refresh_melt - = PERF_TALER_MINTDB_refresh_melt_copy (data->data.refresh_melt); - break; - - case PERF_TALER_MINTDB_NONE: - break; - } -} - - -/** - * Finds the first command in cmd with the name search - * - * @return the index of the first command with name search - * #GNUNET_SYSERR if none found - */ -static int -cmd_find (const struct PERF_TALER_MINTDB_Cmd *cmd, - const char *search) -{ - unsigned int i; - - for (i=0; PERF_TALER_MINTDB_CMD_END != cmd[i].command; i++) - if (0 == strcmp (cmd[i].label, search)) - return i; - return GNUNET_SYSERR; -} - - -/** - * Initialization of a command array - * and check for the type of the label - * - * @param cmd the comand array initialized - * @return #GNUNET_OK if the initialization was sucessful - * #GNUNET_SYSERR if there was a probleb. See the log for details - */ -static int -cmd_init (struct PERF_TALER_MINTDB_Cmd cmd[]) -{ - unsigned int i; - - for (i=0; PERF_TALER_MINTDB_CMD_END != cmd[i].command; i++) - { - switch (cmd[i].command) - { - case PERF_TALER_MINTDB_CMD_END_LOOP: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.end_loop.label_loop); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.end_loop.label_loop); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_CMD_LOOP != cmd[ret].command) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.end_loop.label_loop); - return GNUNET_SYSERR; - } - cmd[i].details.end_loop.index_loop = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_SAVE_ARRAY: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.save_array.label_save); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.save_array.label_save); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_NONE == cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.save_array.label_save); - return GNUNET_SYSERR; - } - cmd[i].details.save_array.index_save = ret; - - ret = cmd_find (cmd, - cmd[i].details.save_array.label_loop); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.save_array.label_loop); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_CMD_LOOP != cmd[ret].command) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.save_array.label_loop); - return GNUNET_SYSERR; - } - cmd[i].details.save_array.index_loop = ret; - - GNUNET_assert (NULL == cmd[i].details.save_array.data_saved); - cmd[i].details.save_array.data_saved = - GNUNET_new_array (cmd[i].details.save_array.nb_saved, - struct PERF_TALER_MINTDB_Data); - cmd[i].details.save_array.type_saved = - cmd[cmd[i].details.save_array.index_save].exposed.type; - } - break; - - case PERF_TALER_MINTDB_CMD_LOAD_ARRAY: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.load_array.label_save); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.load_array.label_save); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_CMD_SAVE_ARRAY != cmd[ret].command) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.load_array.label_save); - return GNUNET_SYSERR; - } - cmd[i].details.load_array.index_save = ret; - - ret = cmd_find (cmd, - cmd[i].details.load_array.label_loop); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.load_array.label_loop); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_CMD_LOOP != cmd[ret].command) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.load_array.label_loop); - return GNUNET_SYSERR; - } - cmd[i].details.load_array.index_loop = ret; - - cmd[i].details.load_array.permutation = - GNUNET_CRYPTO_random_permute ( - GNUNET_CRYPTO_QUALITY_WEAK, - cmd[cmd[i].details.load_array.index_save].details.save_array.nb_saved); - GNUNET_assert (NULL != cmd[i].details.load_array.permutation); - - cmd[i].exposed.type = cmd[cmd[i].details.load_array.index_save].details.save_array.type_saved; - } - break; - - case PERF_TALER_MINTDB_CMD_LOAD_RANDOM: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.load_random.label_save); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.load_random.label_save); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_CMD_SAVE_ARRAY != cmd[ret].command) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.load_random.label_save); - return GNUNET_SYSERR; - } - cmd[i].details.load_random.index_save = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GAUGER: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.gauger.label_start); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.gauger.label_start); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_TIME != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.gauger.label_start); - return GNUNET_SYSERR; - } - cmd[i].details.gauger.index_start = ret; - - ret = cmd_find (cmd, - cmd[i].details.gauger.label_stop); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.gauger.label_stop); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_TIME != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.gauger.label_stop); - return GNUNET_SYSERR; - } - cmd[i].details.gauger.index_stop = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_DENOMINATION: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.insert_denomination.label_denom); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_denomination.label_denom); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_DENOMINATION_INFO != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_denomination.label_denom); - return GNUNET_SYSERR; - } - cmd[i].details.insert_denomination.index_denom = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_DENOMINATION: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.get_denomination.label_denom); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_denomination.label_denom); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_DENOMINATION_INFO != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_denomination.label_denom); - return GNUNET_SYSERR; - } - cmd[i].details.get_denomination.index_denom = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_RESERVE: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.insert_reserve.label_reserve); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_reserve.label_reserve); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_RESERVE != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_reserve.label_reserve); - return GNUNET_SYSERR; - } - cmd[i].details.insert_reserve.index_reserve = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_RESERVE: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.get_reserve.label_reserve); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_reserve.label_reserve); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_RESERVE != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_reserve.label_reserve); - return GNUNET_SYSERR; - } - cmd[i].details.get_reserve.index_reserve = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_RESERVE_HISTORY: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.get_reserve_history.label_reserve); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_reserve_history.label_reserve); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_RESERVE != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_reserve_history.label_reserve); - return GNUNET_SYSERR; - } - cmd[i].details.get_reserve_history.index_reserve = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_CREATE_WITHDRAW: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.create_withdraw.label_dki); - { - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.create_withdraw.label_dki); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_DENOMINATION_INFO != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.create_withdraw.label_dki); - return GNUNET_SYSERR; - } - } - cmd[i].details.create_withdraw.index_dki = ret; - ret = cmd_find (cmd, - cmd[i].details.create_withdraw.label_reserve); - { - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.create_withdraw.label_reserve); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_RESERVE != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.create_withdraw.label_reserve); - return GNUNET_SYSERR; - } - } - cmd[i].details.create_withdraw.index_reserve = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_WITHDRAW: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.insert_withdraw.label_coin); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_withdraw.label_coin); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_COIN != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_withdraw.label_coin); - return GNUNET_SYSERR; - } - cmd[i].details.insert_withdraw.index_coin = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_WITHDRAW: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.get_withdraw.label_coin); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_withdraw.label_coin); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_COIN != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_withdraw.label_coin); - return GNUNET_SYSERR; - } - cmd[i].details.get_withdraw.index_coin = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_COIN_TRANSACTION: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_coin_transaction.label_coin); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_coin_transaction.label_coin); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_COIN != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_coin_transaction.label_coin); - return GNUNET_SYSERR; - } - cmd[i].details.get_coin_transaction.index_coin = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_CREATE_DEPOSIT: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.create_deposit.label_coin); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.create_deposit.label_coin); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_COIN != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.create_deposit.label_coin); - return GNUNET_SYSERR; - } - cmd[i].details.create_deposit.index_coin = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_DEPOSIT: - { - int ret; - - ret = cmd_find( cmd, - cmd[i].details.insert_deposit.label_deposit); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_deposit.label_deposit); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_DEPOSIT != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_deposit.label_deposit); - return GNUNET_SYSERR; - } - cmd[i].details.insert_deposit.index_deposit = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_DEPOSIT: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.get_deposit.label_deposit); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_deposit.label_deposit); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_DEPOSIT != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_deposit.label_deposit); - return GNUNET_SYSERR; - } - cmd[i].details.get_deposit.index_deposit = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_SESSION: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.get_refresh_session.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_refresh_session.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_refresh_session.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_refresh_session.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_MELT: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_melt.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_melt.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_melt.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_melt.index_hash = ret; - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_melt.label_coin); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_melt.label_coin); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_COIN != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_melt.label_coin); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_melt.index_coin = ret; } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_MELT: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_refresh_melt.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_refresh_melt.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_refresh_melt.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_refresh_melt.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_ORDER: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_order.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_order.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_order.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_order.index_hash = ret; - - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_order.label_denom); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_order.label_denom); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_DENOMINATION_INFO != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_order.label_denom); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_order.index_denom = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_ORDER: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_refresh_order.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_refresh_order.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_refresh_order.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_refresh_order.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_COMMIT_COIN: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_commit_coin.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_commit_coin.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_commit_coin.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_commit_coin.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_COMMIT_COIN: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_refresh_commit_coin.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_refresh_commit_coin.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_refresh_commit_coin.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_refresh_commit_coin.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_COMMIT_LINK: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_commit_link.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_commit_link.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_commit_link.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_commit_link.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_COMMIT_LINK: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_refresh_commit_link.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_refresh_commit_link.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_refresh_commit_link.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_refresh_commit_link.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_MELT_COMMITMENT: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_melt_commitment.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_melt_commitment.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_melt_commitment.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_melt_commitment.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_OUT: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_out.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_out.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_out.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_out.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_LINK_DATA_LIST: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_link_data_list.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_link_data_list.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_link_data_list.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_link_data_list.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_TRANSFER: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_transfer.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_transfer.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_MINTDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_transfer.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_transfer.index_hash = ret; - } - break; - - case PERF_TALER_MINTDB_CMD_END: - case PERF_TALER_MINTDB_CMD_DEBUG: - case PERF_TALER_MINTDB_CMD_LOOP: - case PERF_TALER_MINTDB_CMD_NEW_SESSION: - case PERF_TALER_MINTDB_CMD_START_TRANSACTION: - case PERF_TALER_MINTDB_CMD_COMMIT_TRANSACTION: - case PERF_TALER_MINTDB_CMD_ABORT_TRANSACTION: - case PERF_TALER_MINTDB_CMD_GET_TIME: - case PERF_TALER_MINTDB_CMD_CREATE_DENOMINATION: - case PERF_TALER_MINTDB_CMD_CREATE_RESERVE: - case PERF_TALER_MINTDB_CMD_CREATE_REFRESH_SESSION: - break; - } - } - return GNUNET_OK; -} - - -/** - * Free the memory of the command chain - */ -static int -cmd_clean (struct PERF_TALER_MINTDB_Cmd cmd[]) -{ - unsigned int i; - - for (i=0; PERF_TALER_MINTDB_CMD_END != cmd[i].command; i++) - { - switch (cmd[i].command) - { - case PERF_TALER_MINTDB_CMD_SAVE_ARRAY: - { - unsigned int j; - - for (j = 0; j < cmd[i].details.save_array.nb_saved; j++) - { - data_free (&cmd[i].details.save_array.data_saved[j]); - } - GNUNET_free (cmd[i].details.save_array.data_saved); - cmd[i].details.save_array.data_saved = NULL; - } - break; - - case PERF_TALER_MINTDB_CMD_LOAD_ARRAY: - GNUNET_free (cmd[i].details.load_array.permutation); - cmd[i].details.load_array.permutation = NULL; - break; - - default: - break; - } - data_free (&cmd[i].exposed); - } - return GNUNET_OK; -} - - -/** - * Handles the command #PERF_TALER_MINTDB_CMD_END_LOOP for the interpreter - * Cleans the memory at the end of the loop - */ -static void -interpret_end_loop (struct PERF_TALER_MINTDB_interpreter_state *state) -{ - unsigned int i; - int jump; - - jump = state->cmd[state->i].details.end_loop.index_loop; - // Cleaning up the memory in the loop - for (i = jump; i < state->i; i++) - data_free (&state->cmd[i].exposed); - - state->cmd[jump].details.loop.curr_iteration++; - /* If the loop is not finished */ - if (state->cmd[jump].details.loop.max_iterations > - state->cmd[jump].details.loop.curr_iteration) - { - /* jump back to the start */ - state->i = jump; - } - else - { - /* Reset the loop counter and continue running */ - state->cmd[jump].details.loop.curr_iteration = 0; - } -} - - -/** - * Part of the interpreter specific to - * #PERF_TALER_MINTDB_CMD_SAVE_ARRAY - * Saves the data exposed by another command into - * an array in the command specific struct. - */ -static void -interpret_save_array (struct PERF_TALER_MINTDB_interpreter_state *state) -{ - struct PERF_TALER_MINTDB_Cmd *cmd = &state->cmd[state->i]; - struct PERF_TALER_MINTDB_Cmd *save_ref; - struct PERF_TALER_MINTDB_Cmd *loop_ref; - int loop_index; - int save_index; - unsigned int selection_chance; - - loop_index = cmd->details.save_array.index_loop; - save_index = cmd->details.save_array.index_save; - loop_ref = &state->cmd[loop_index]; - save_ref = &state->cmd[save_index]; - /* Array initialization on first loop iteration - Alows for nested loops */ - if (0 == cmd->details.loop.curr_iteration) - { - cmd->details.save_array.index = 0; - } - /* The probability distribution of the saved items will be a little biased - against the few last items but it should not be a big problem. */ - selection_chance = loop_ref->details.loop.max_iterations / - cmd->details.save_array.nb_saved; - /* - * If the remaining space is equal to the remaining number of - * iterations, the item is automaticly saved. - * - * Else it is saved only if the random numbre generated is 0 - */ - if ( (0 < (cmd->details.save_array.nb_saved - - cmd->details.save_array.index) ) && - ( ((loop_ref->details.loop.max_iterations - - loop_ref->details.loop.curr_iteration) == - (cmd->details.save_array.nb_saved - - cmd->details.save_array.index)) || - (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, - selection_chance)) ) ) - { - struct PERF_TALER_MINTDB_Data *save_location; - struct PERF_TALER_MINTDB_Data *item_saved; - - save_location = &cmd->details.save_array.data_saved[cmd->details.save_array.index]; - item_saved = &save_ref->exposed; - data_copy (item_saved, save_location); - cmd->details.save_array.index++; - } -} - - -/** - * Part of the interpreter specific to - * #PERF_TALER_MINTDB_CMD_LOAD_ARRAY - * Gets data from a #PERF_TALER_MINTDB_CMD_SAVE_ARRAY and exposes a copy - */ -static void -interpret_load_array (struct PERF_TALER_MINTDB_interpreter_state *state) -{ - struct PERF_TALER_MINTDB_Cmd *cmd = &state->cmd[state->i]; - unsigned int loop_iter; - int loop_index; - int save_index; - struct PERF_TALER_MINTDB_Data *loaded_data; - - loop_index = cmd->details.load_array.index_loop; - save_index = cmd->details.load_array.index_save; - loop_iter = state->cmd[loop_index].details.loop.curr_iteration; - { - unsigned int i; - unsigned int quotient; - - /* In case the iteration number is higher than the amount saved, - * the number is run several times in the permutation array */ - quotient = loop_iter / state->cmd[save_index].details.save_array.nb_saved; - loop_iter = loop_iter % state->cmd[save_index].details.save_array.nb_saved; - for (i=0; i<=quotient; i++) - loop_iter = cmd->details.load_array.permutation[loop_iter]; - } - /* Extracting the data from the loop_indexth indice in save_index - * array. - */ - loaded_data = &state->cmd[save_index].details.save_array.data_saved[loop_iter]; - data_copy (loaded_data, - &cmd->exposed); -} - - -/** - * Part of the interpreter specific to - * #PERF_TALER_MINTDB_CMD_LOAD_RANDOM - * Get a random element from a #PERF_TALER_MINTDB_CMD_SAVE_ARRAY and exposes it - */ -static void -interprete_load_random (struct PERF_TALER_MINTDB_interpreter_state *state) -{ - struct PERF_TALER_MINTDB_Cmd *cmd = &state->cmd[state->i]; - unsigned int index; - int save_index; - - save_index = cmd->details.load_random.index_save; - index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, - state->cmd[save_index].details.save_array.nb_saved); - data_copy (&state->cmd[save_index].details.save_array.data_saved[index], - &cmd->exposed); -} - - -/** - * Iterate over the commands, acting accordingly at each step - * - * @param state the current state of the interpreter - */ -static int -interpret (struct PERF_TALER_MINTDB_interpreter_state *state) -{ - for (state->i=0; PERF_TALER_MINTDB_CMD_END != state->cmd[state->i].command; state->i++) - { - switch (state->cmd[state->i].command) - { - case PERF_TALER_MINTDB_CMD_END: - return GNUNET_YES; - - case PERF_TALER_MINTDB_CMD_DEBUG: - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "%s\n", - state->cmd[state->i].label); - break; - - case PERF_TALER_MINTDB_CMD_LOOP: - break; - - case PERF_TALER_MINTDB_CMD_END_LOOP: - interpret_end_loop (state); - break; - - case PERF_TALER_MINTDB_CMD_GET_TIME: - state->cmd[state->i].exposed.data.time = - GNUNET_new (struct GNUNET_TIME_Absolute); - *state->cmd[state->i].exposed.data.time = - GNUNET_TIME_absolute_get (); - break; - - case PERF_TALER_MINTDB_CMD_GAUGER: - { - unsigned int start_index; - unsigned int stop_index; - float ips; - struct GNUNET_TIME_Absolute start; - struct GNUNET_TIME_Absolute stop; - struct GNUNET_TIME_Relative elapsed; - - start_index = state->cmd[state->i].details.gauger.index_start; - stop_index = state->cmd[state->i].details.gauger.index_stop; - start = *state->cmd[start_index].exposed.data.time; - stop = *state->cmd[stop_index].exposed.data.time; - elapsed = GNUNET_TIME_absolute_get_difference (start, - stop); - ips = (1.0 * state->cmd[state->i].details.gauger.divide) / (elapsed.rel_value_us/1000000.0); - GAUGER (state->cmd[state->i].details.gauger.category, - state->cmd[state->i].details.gauger.description, - ips, - state->cmd[state->i].details.gauger.unit); - } - break; - - case PERF_TALER_MINTDB_CMD_NEW_SESSION: - state->session = state->plugin->get_session (state->plugin->cls, GNUNET_YES); - break; - - case PERF_TALER_MINTDB_CMD_START_TRANSACTION: - state->plugin->start (state->plugin->cls, state->session); - break; - - case PERF_TALER_MINTDB_CMD_COMMIT_TRANSACTION: - state->plugin->commit (state->plugin->cls, state->session); - break; - - case PERF_TALER_MINTDB_CMD_ABORT_TRANSACTION: - state->plugin->rollback (state->plugin->cls, - state->session); - break; - - case PERF_TALER_MINTDB_CMD_SAVE_ARRAY: - interpret_save_array (state); - break; - - case PERF_TALER_MINTDB_CMD_LOAD_ARRAY: - interpret_load_array (state); - break; - - case PERF_TALER_MINTDB_CMD_LOAD_RANDOM: - interprete_load_random (state); - break; - - case PERF_TALER_MINTDB_CMD_CREATE_DEPOSIT: - { - int coin_index; - struct TALER_MINTDB_Deposit *deposit; - - coin_index = state->cmd[state->i].details.create_deposit.index_coin; - deposit = PERF_TALER_MINTDB_deposit_init (state->cmd[coin_index].exposed.data.coin); - GNUNET_assert (NULL != deposit); - state->cmd[state->i].exposed.data.deposit = deposit; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_DEPOSIT: - { - int deposit_index; - int ret; - struct TALER_MINTDB_Deposit *deposit; - - deposit_index = state->cmd[state->i].details.insert_deposit.index_deposit; - deposit = state->cmd[deposit_index].exposed.data.deposit; - ret = state->plugin->insert_deposit (state->plugin->cls, - state->session, - deposit); - GNUNET_assert (GNUNET_SYSERR != ret); - state->cmd[state->i].exposed.data.deposit = deposit; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_DEPOSIT: - { - unsigned int source_index; - int ret; - struct PERF_TALER_MINTDB_Data *data; - - source_index = state->cmd[state->i].details.get_deposit.index_deposit; - data = &state->cmd[source_index].exposed; - ret = state->plugin->have_deposit (state->plugin->cls, - state->session, - data->data.deposit); - GNUNET_assert (GNUNET_SYSERR != ret); - } - break; - - case PERF_TALER_MINTDB_CMD_CREATE_RESERVE: - { - struct PERF_TALER_MINTDB_Reserve *reserve; - - reserve = PERF_TALER_MINTDB_reserve_init (); - state->cmd[state->i].exposed.data.reserve = reserve; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_RESERVE: - { - unsigned int reserve_index; - int ret; - struct PERF_TALER_MINTDB_Reserve *reserve; - json_t *details = NULL; - - reserve_index = state->cmd[state->i].details.insert_reserve.index_reserve; - reserve = state->cmd[reserve_index].exposed.data.reserve; - details = json_pack ("{s:i}","justification", - GNUNET_CRYPTO_random_u32 ( - GNUNET_CRYPTO_QUALITY_WEAK, - UINT32_MAX)); - GNUNET_assert (NULL != details); - ret = state->plugin->reserves_in_insert (state->plugin->cls, - state->session, - &reserve->reserve.pub, - &reserve->reserve.balance, - GNUNET_TIME_absolute_get (), - details); - GNUNET_assert (GNUNET_SYSERR != ret); - json_decref (details); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_RESERVE: - { - unsigned int reserve_index; - int ret; - struct PERF_TALER_MINTDB_Data *data; - - - reserve_index = state->cmd[state->i].details.get_reserve.index_reserve; - data = &state->cmd[reserve_index].exposed; - ret = state->plugin->reserve_get (state->plugin->cls, - state->session, - &data->data.reserve->reserve); - GNUNET_assert (GNUNET_OK == ret); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_RESERVE_HISTORY: - { - unsigned int reserve_index; - struct TALER_MINTDB_ReserveHistory *history; - struct PERF_TALER_MINTDB_Data *data; - - reserve_index = state->cmd[state->i].details.get_reserve_history.index_reserve; - data = &state->cmd[reserve_index].exposed; - history = state->plugin->get_reserve_history (state->plugin->cls, - state->session, - &data->data.reserve->reserve.pub); - GNUNET_assert (NULL != history); - state->plugin->free_reserve_history (state->plugin->cls, - history); - } - break; - - case PERF_TALER_MINTDB_CMD_CREATE_DENOMINATION: - { - struct TALER_MINTDB_DenominationKeyIssueInformation *dki = - PERF_TALER_MINTDB_denomination_init (); - GNUNET_assert (NULL != dki); - state->cmd[state->i].exposed.data.dki = dki; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_DENOMINATION: - { - unsigned int denom_index; - int ret; - struct TALER_MINTDB_DenominationKeyIssueInformation *dki ; - - denom_index = state->cmd[state->i].details.insert_denomination.index_denom; - dki = state->cmd[denom_index].exposed.data.dki; - ret = state->plugin->insert_denomination_info (state->plugin->cls, - state->session, - &dki->denom_pub, - &dki->issue); - GNUNET_assert (GNUNET_SYSERR != ret); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_DENOMINATION: - { - unsigned int denom_index; - int ret; - struct PERF_TALER_MINTDB_Data *data; - - denom_index = state->cmd[state->i].details.get_denomination.index_denom; - data = &state->cmd[denom_index].exposed; - ret = state->plugin->get_denomination_info (state->plugin->cls, - state->session, - &data->data.dki->denom_pub, - &data->data.dki->issue); - GNUNET_assert (GNUNET_SYSERR != ret); - } - break; - - case PERF_TALER_MINTDB_CMD_CREATE_WITHDRAW: - { - unsigned int dki_index; - unsigned int reserve_index; - struct PERF_TALER_MINTDB_Coin *coin ; - - dki_index = state->cmd[state->i].details.create_withdraw.index_dki; - reserve_index = state->cmd[state->i].details.create_withdraw.index_reserve; - coin = PERF_TALER_MINTDB_coin_init (state->cmd[dki_index].exposed.data.dki, - state->cmd[reserve_index].exposed.data.reserve); - GNUNET_assert (NULL != coin); - state->cmd[state->i].exposed.data.coin = coin; - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_WITHDRAW: - { - unsigned int coin_index; - int ret; - struct PERF_TALER_MINTDB_Coin *coin ; - - coin_index = state->cmd[state->i].details.insert_withdraw.index_coin; - coin = state->cmd[coin_index].exposed.data.coin; - ret = state->plugin->insert_withdraw_info (state->plugin->cls, - state->session, - &coin->blind); - GNUNET_assert (GNUNET_SYSERR != ret); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_WITHDRAW: - { - unsigned int source_index; - int ret; - struct PERF_TALER_MINTDB_Data *data; - - source_index = state->cmd[state->i].details.get_denomination.index_denom; - data = &state->cmd[source_index].exposed; - ret = state->plugin->get_withdraw_info (state->plugin->cls, - state->session, - &data->data.coin->blind.h_coin_envelope, - &data->data.coin->blind); - GNUNET_assert (GNUNET_SYSERR != ret); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_COIN_TRANSACTION: - { - unsigned int coin_index; - struct PERF_TALER_MINTDB_Coin *coin; - struct TALER_MINTDB_TransactionList *transactions; - - coin_index = state->cmd[state->i].details.get_coin_transaction.index_coin; - coin = state->cmd[coin_index].exposed.data.coin; - transactions = state->plugin->get_coin_transactions (state->plugin->cls, - state->session, - &coin->public_info.coin_pub); - GNUNET_assert (transactions != NULL); - state->plugin->free_coin_transaction_list (state->plugin->cls, - transactions); - } - break; - - case PERF_TALER_MINTDB_CMD_CREATE_REFRESH_SESSION: - { - struct GNUNET_HashCode *hash; - struct TALER_MINTDB_RefreshSession *refresh_session; - - hash = GNUNET_new (struct GNUNET_HashCode); - refresh_session = PERF_TALER_MINTDB_refresh_session_init (); - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, - hash); - state->plugin->create_refresh_session (state->session, - state->session, - hash, - refresh_session); - state->cmd[state->i].exposed.data.session_hash = hash; - PERF_TALER_MINTDB_refresh_session_free (refresh_session); - GNUNET_free (refresh_session); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_SESSION: - { - unsigned int hash_index; - struct GNUNET_HashCode *hash; - struct TALER_MINTDB_RefreshSession refresh; - - hash_index = state->cmd[state->i].details.get_refresh_session.index_hash; - hash = state->cmd[hash_index].exposed.data.session_hash; - state->plugin->get_refresh_session (state->session, - state->session, - hash, - &refresh); - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_MELT: - { - unsigned int hash_index; - unsigned int coin_index; - struct GNUNET_HashCode *hash; - struct TALER_MINTDB_RefreshMelt *melt; - struct PERF_TALER_MINTDB_Coin *coin; - - hash_index = state->cmd[state->i].details.insert_refresh_melt.index_hash; - coin_index = state->cmd[state->i].details.insert_refresh_melt.index_coin; - hash = state->cmd[hash_index].exposed.data.session_hash; - coin = state->cmd[coin_index].exposed.data.coin; - melt = PERF_TALER_MINTDB_refresh_melt_init (hash, - coin); - state->plugin->insert_refresh_melt (state->plugin->cls, - state->session, - 1, - melt); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_MELT: - { - int ret; - unsigned int hash_index; - struct GNUNET_HashCode *hash; - struct TALER_MINTDB_RefreshMelt melt; - - hash_index = cmd_find (state->cmd, - state->cmd[state->i].details.get_refresh_melt.label_hash); - hash = state->cmd[hash_index].exposed.data.session_hash; - ret = state->plugin->get_refresh_melt (state->plugin->cls, - state->session, - hash, - 1, - &melt); - GNUNET_assert (GNUNET_SYSERR != ret); - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_ORDER: - { - unsigned int hash_index; - unsigned int denom_index; - struct GNUNET_HashCode *session_hash; - struct TALER_MINTDB_DenominationKeyIssueInformation *denom; - - hash_index = state->cmd[state->i].details.insert_refresh_order.index_hash; - denom_index = state->cmd[state->i].details.insert_refresh_order.index_denom; - session_hash = state->cmd[hash_index].exposed.data.session_hash; - denom = state->cmd[denom_index].exposed.data.dki; - state->plugin->insert_refresh_order (state->plugin->cls, - state->session, - session_hash, - 1, - &denom->denom_pub); - - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_ORDER: - { - int hash_index; - struct GNUNET_HashCode *hash; - struct TALER_DenominationPublicKey denom_pub; - - hash_index = state->cmd[state->i].details.get_refresh_order.index_hash; - hash = state->cmd[hash_index].exposed.data.session_hash; - state->plugin->get_refresh_order (state->plugin->cls, - state->session, - hash, - 1, - &denom_pub); - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_COMMIT_COIN: - { - int ret; - unsigned int hash_index; - struct TALER_MINTDB_RefreshCommitCoin *refresh_commit; - - hash_index = state->cmd[state->i].details.insert_refresh_commit_coin.index_hash; - refresh_commit = PERF_TALER_MINTDB_refresh_commit_coin_init (); - ret = state->plugin->insert_refresh_commit_coins (state->plugin->cls, - state->session, - state->cmd[hash_index].exposed.data.session_hash, - 1, - 1, - refresh_commit); - GNUNET_assert (GNUNET_OK == ret); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_COMMIT_COIN: - { - unsigned int hash_index; - struct TALER_MINTDB_RefreshCommitCoin refresh_commit; - - hash_index = state->cmd[state->i].details.insert_refresh_commit_coin.index_hash; - state->plugin->get_refresh_commit_coins (state->plugin->cls, - state->session, - state->cmd[hash_index].exposed.data.session_hash, - 1, - 1, - &refresh_commit); - - } - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_COMMIT_LINK: - { -// unsigned int hash_index; -// -// hash_index = state->cmd[state->i].details.insert_refresh_commit_link.index_hash; - } - break; - - case PERF_TALER_MINTDB_CMD_GET_REFRESH_COMMIT_LINK: - { - int ret; - unsigned int hash_index; - struct TALER_MINTDB_RefreshCommitCoin commit_coin; - - hash_index = state->cmd[state->i].details.get_refresh_commit_link.index_hash; - ret = state->plugin->get_refresh_commit_coins(state->plugin->cls, - state->session, - state->cmd[hash_index].exposed.data.session_hash, - 1, - 1, - &commit_coin); - GNUNET_assert (GNUNET_SYSERR != ret); - } - break; - - case PERF_TALER_MINTDB_CMD_GET_MELT_COMMITMENT: - break; - - case PERF_TALER_MINTDB_CMD_INSERT_REFRESH_OUT: - break; - - case PERF_TALER_MINTDB_CMD_GET_LINK_DATA_LIST: - break; - - case PERF_TALER_MINTDB_CMD_GET_TRANSFER: - break; - - } - } - return GNUNET_OK; -} - - -/** - * Runs the commands given in @a cmd, working with - * the database referenced by @a db_plugin - * - * @param db_plugin the connection to the database - * @param cmd the commands to run - */ -int -PERF_TALER_MINTDB_interpret (struct TALER_MINTDB_Plugin *db_plugin, - struct PERF_TALER_MINTDB_Cmd cmd[]) -{ - int ret; - struct PERF_TALER_MINTDB_interpreter_state state = - {.i = 0, .cmd = cmd, .plugin = db_plugin}; - - ret = cmd_init (cmd); - if (GNUNET_SYSERR == ret) - return ret; - state.session = db_plugin->get_session (db_plugin->cls, - GNUNET_YES); - GNUNET_assert (NULL != state.session); - ret = interpret (&state); - cmd_clean (cmd); - return ret; -} - - -/** - * Initialize the database and run the benchmark - * - * @param benchmark_name the name of the benchmark, displayed in the logs - * @param configuration_file path to the taler configuration file to use - * @param init the commands to use for the database initialisation, - * if #NULL the standard initialization is used - * @param benchmark the commands for the benchmark - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure - */ -int -PERF_TALER_MINTDB_run_benchmark (const char *benchmark_name, - const char *configuration_file, - struct PERF_TALER_MINTDB_Cmd *init, - struct PERF_TALER_MINTDB_Cmd *benchmark) -{ - struct TALER_MINTDB_Plugin *plugin; - struct GNUNET_CONFIGURATION_Handle *config; - int ret = 0; - struct PERF_TALER_MINTDB_Cmd init_def[] = - { - // Denomination used to create coins - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("00 - Start of interpreter"), - - PERF_TALER_MINTDB_INIT_CMD_LOOP ("01 - denomination loop", - PERF_TALER_MINTDB_NB_DENOMINATION_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_CREATE_DENOMINATION ("01 - denomination"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_DENOMINATION ("01 - insert", - "01 - denomination"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("01 - save denomination", - "01 - denomination loop", - "01 - denomination", - PERF_TALER_MINTDB_NB_DENOMINATION_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "01 - denomination loop"), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("01 - init denomination complete"), - // End of initialization - // Reserve initialization - PERF_TALER_MINTDB_INIT_CMD_LOOP ("02 - init reserve loop", - PERF_TALER_MINTDB_NB_RESERVE_INIT), - PERF_TALER_MINTDB_INIT_CMD_CREATE_RESERVE ("02 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_RESERVE ("02 - insert", - "02 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("02 - save reserve", - "02 - init reserve loop", - "02 - reserve", - PERF_TALER_MINTDB_NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "02 - init reserve loop"), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("02 - reserve init complete"), - // End reserve init - // Withdrawal initialization - PERF_TALER_MINTDB_INIT_CMD_LOOP ("03 - init withdraw loop", - PERF_TALER_MINTDB_NB_WITHDRAW_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("03 - denomination load", - "03 - init withdraw loop", - "01 - save denomination"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("03 - reserve load", - "03 - init withdraw loop", - "02 - save reserve"), - PERF_TALER_MINTDB_INIT_CMD_CREATE_WITHDRAW ("03 - withdraw", - "03 - denomination load", - "03 - reserve load"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_WITHDRAW ("03 - insert", - "03 - withdraw"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION (""), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("03 - save coin", - "03 - init withdraw loop", - "03 - withdraw", - PERF_TALER_MINTDB_NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("", - "03 - init withdraw loop"), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("03 - withdraw init complete"), - //End of withdrawal initialization - //Deposit initialization - PERF_TALER_MINTDB_INIT_CMD_LOOP ("04 - deposit init loop", - PERF_TALER_MINTDB_NB_DEPOSIT_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION ("04 - start transaction"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("04 - denomination load", - "04 - deposit init loop", - "03 - save coin"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_DEPOSIT ("04 - deposit", - "04 - denomination load"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION ("04 - commit transaction"), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("04 - deposit array", - "04 - deposit init loop", - "04 - deposit", - PERF_TALER_MINTDB_NB_DEPOSIT_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("04 - deposit init loop end", - "04 - deposit init loop"), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("04 - deposit init complete"), - // End of deposit initialization - PERF_TALER_MINTDB_INIT_CMD_END ("end") - }; - - GNUNET_log_setup (benchmark_name, - "INFO", - NULL); - config = GNUNET_CONFIGURATION_create (); - - ret = GNUNET_CONFIGURATION_load (config, - configuration_file); - if (GNUNET_OK != ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing configuration file\n"); - return GNUNET_SYSERR; - } - plugin = TALER_MINTDB_plugin_load (config); - if (NULL == plugin) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error connectiong to the database\n"); - return ret; - } - ret = plugin->create_tables (plugin->cls, - GNUNET_YES); - if (GNUNET_OK != ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error while creating the database architecture\n"); - return ret; - } - /* - * Running the initialization - */ - if (NULL == init) - { - init = init_def; - } - ret = PERF_TALER_MINTDB_interpret (plugin, - init); - if (GNUNET_OK != ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error during database initialization\n"); - return ret; - } - /* - * Running the benchmark - */ - ret = PERF_TALER_MINTDB_interpret (plugin, - benchmark); - if (GNUNET_OK != ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error while runing the benchmark\n"); - return ret; - } - /* Drop tables */ - { - struct TALER_MINTDB_Session *session; - - session = plugin->get_session (plugin->cls, - GNUNET_YES); - ret = plugin->drop_temporary (plugin->cls, - session); - if (GNUNET_OK != ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error cleaning the database\n"); - return ret; - } - } - TALER_MINTDB_plugin_unload (plugin); - GNUNET_CONFIGURATION_destroy (config); - return ret; -} diff --git a/src/mintdb/perf_taler_mintdb_interpreter.h b/src/mintdb/perf_taler_mintdb_interpreter.h deleted file mode 100644 index 3510e3dd4..000000000 --- a/src/mintdb/perf_taler_mintdb_interpreter.h +++ /dev/null @@ -1,1319 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file mintdb/perf_taler_mintdb_interpreter.h - * @brief Library for performance analysis of the Taler database - * @author Nicolas Fournier - * - * This library contains functions and macro alowing Taler performance analysis - * to be written with ease. - * To do so, create a #PERF_TALER_MINTDB_Cmd array and fill it with the commands - * to execute in chronological order. Some command have an exposed variable wich - * can be reused in other commands. - * Macros are available to make the use much easier so feel free to use them - * to initialize your own command array. - */ - -#ifndef __PERF_TALER_MINTDB_INTERPRETER_H__ -#define __PERF_TALER_MINTDB_INTERPRETER_H__ - -#include <sys/time.h> -#include "taler_mintdb_plugin.h" - - -#define PERF_TALER_MINTDB_NB_DENOMINATION_INIT 10 -#define PERF_TALER_MINTDB_NB_DENOMINATION_SAVE 10 - -#define PERF_TALER_MINTDB_NB_RESERVE_INIT 100 -#define PERF_TALER_MINTDB_NB_RESERVE_SAVE 10 - -#define PERF_TALER_MINTDB_NB_DEPOSIT_INIT 100 -#define PERF_TALER_MINTDB_NB_DEPOSIT_SAVE 10 - -#define PERF_TALER_MINTDB_NB_WITHDRAW_INIT 100 -#define PERF_TALER_MINTDB_NB_WITHDRAW_SAVE 10 - - -/** - * Marks the end of the command chain - * - * @param _label The label of the command - */ -#define PERF_TALER_MINTDB_INIT_CMD_END(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_END, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE \ -} - - -/** - * Prints @ _label to stdout - * - * @param _label The label of the command, - * will be logged each time the command runs - */ -#define PERF_TALER_MINTDB_INIT_CMD_DEBUG(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_DEBUG, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE \ -} - -/** - * The begining of a loop - * - * @param _label the label of the loop - * @param _iter the number of iterations of the loop - */ -#define PERF_TALER_MINTDB_INIT_CMD_LOOP(_label, _iter) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_LOOP , \ - .label = _label , \ - .exposed.type = PERF_TALER_MINTDB_NONE , \ - .details.loop = { \ - .max_iterations = _iter , \ - .curr_iteration = 0 } \ -} - -/** - * Marks the end of the loop @_label_loop - * - * @param _label the label of the command - * @param _label_loop the label of the loop closed by this command - */ -#define PERF_TALER_MINTDB_INIT_CMD_END_LOOP(_label, _label_loop) \ -{\ - .command = PERF_TALER_MINTDB_CMD_END_LOOP , \ - .label = _label , \ - .exposed.type = PERF_TALER_MINTDB_NONE , \ - .details.end_loop.label_loop = _label_loop \ -} - -/** - * Saves the time of execution to use for logging with Gauger - * - * @param _label the label of the command - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_TIME(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_TIME, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_TIME \ -} - -/** - * Commits the duration between @a _label_start and @a _label_stop - * to Gauger with @a _description explaining what was measured. - * - * @param _label the label of this command - * @param _label_start label of the start of the measurment - * @param _label_stop label of the end of the measurment - * @param _description description of the measure displayed in Gauger - * @param _unit the unit of the data measured, typicly something/sec - * @param _divide number of measurments in the interval - */ -#define PERF_TALER_MINTDB_INIT_CMD_GAUGER(_label, _label_start, _label_stop, _category, _description, _unit, _divide) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GAUGER, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.gauger = { \ - .label_start = _label_start, \ - .label_stop = _label_stop, \ - .category = _category, \ - .description = _description, \ - .unit = _unit, \ - .divide = _divide, \ - } \ -} - -/** - * Initiate a database transaction - * - * @param _label the label of the command - */ -#define PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_START_TRANSACTION, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ -} - -/** - * Commits a database transaction - * - * @param _label the label of the command - */ -#define PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_COMMIT_TRANSACTION, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ -} - -/** - * Abort the current transaction - * - * @param _label the label of the command - */ -#define PERF_TALER_MINTDB_INIT_CMD_ABORT_TRANSACTION(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_ABORT_TRANSACTION, \ - .label = _label, - -/** - * Saves randomly selected items from @a _label_save - * Saved items can latter be access using #PERF_TALER_MINTDB_CMD_LOAD_ARRAY - * - * @param _label the label of the command, used by other commands to reference it - * @param _label_loop the label of the loop the array iterates over - * @param _label_save the label of the command which outout is saved by this command - * @param _nb_saved the total number of items to be saved - */ -#define PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY(_label, _label_loop, _label_save, _nb_saved) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_SAVE_ARRAY, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.save_array = { \ - .label_loop = _label_loop, \ - .label_save = _label_save, \ - .nb_saved = _nb_saved, \ - } \ -} - -/** - * Loads data from a #PERF_TALER_MINTDB_CMD_SAVE_ARRAY to allow other - * commands to access it - * - * @param _label the label of this command, referenced by commands to access it's outpout - * @param _label_loop the label of the loop to iterate over - * @param _label_save the label of the #PERF_TALER_MINTDB_CMD_SAVE_ARRAY providing data - */ -#define PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY(_label, _label_loop, _label_save) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_LOAD_ARRAY, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.load_array = { \ - .label_loop = _label_loop, \ - .label_save = _label_save \ - } \ -} - -/** - * Create a denomination key to use - * Exposes a #PERF_TALER_MINTDB_DENOMINATION_INFO to be used by other commands - * @exposed #PERF_TALER_MINTDB_DENOMINATION_INFO - * - * @param _label the label of this command - */ -#define PERF_TALER_MINTDB_INIT_CMD_CREATE_DENOMINATION(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_CREATE_DENOMINATION, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_DENOMINATION_INFO, \ -} - -/** - * Inserts informations about a denomination key in the database - * - * @param _label the label of this command - * @param _label_denom the label of the denomination to insert - */ -#define PERF_TALER_MINTDB_INIT_CMD_INSERT_DENOMINATION(_label, _label_denom) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_INSERT_DENOMINATION, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.insert_denomination.label_denom = _label_denom, \ -} - -/** - * Polls the database about informations regarding a specific denomination key - * - * @param _label the label of this command - * @param _label_denom the label of the command providing information about the denomination key - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_DENOMINATION(_label, _label_denom) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_DENOMINATION, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.get_denomination.label_denom = _label_denom \ -} - -/** - * Create a reserve to be used later - * Exposes a #PERF_TALER_MINTDB_RESERVE - * - * @param _label the label of the command - */ -#define PERF_TALER_MINTDB_INIT_CMD_CREATE_RESERVE(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_CREATE_RESERVE, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_RESERVE \ -} - -/** - * Insert a new reserve in the database containing 1000 Euros - * - * @param _label the name of this command - * @param _label_reserve the label of the reserve to insert - */ -#define PERF_TALER_MINTDB_INIT_CMD_INSERT_RESERVE(_label, _label_reserve) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_INSERT_RESERVE, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.insert_reserve.label_reserve = _label_reserve \ -} - -/** - * Polls the database for a secific reserve's details - * - * @param _label the label of this command - * @param _label_reserve the reserve to poll - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_RESERVE(_label, _label_reserve) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_RESERVE, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.get_reserve.label_reserve = _label_reserve \ -} - -/** - * Polls the database for the history of a reserve - * - * @param _label the label of the command - * @param _label_reserve the reserve to examine - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_RESERVE_HISTORY(_label, _label_reserve) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_RESERVE_HISTORY, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.get_reserve_history.label_reserve = _label_reserve \ -} - -/** - * Creates a coin to be used later - * - * @param _label the label of this command - * @param _label_dki denomination key used to sign the coin - * @param _label_reserve reserve used to emmit the coin - */ -#define PERF_TALER_MINTDB_INIT_CMD_CREATE_WITHDRAW(_label, _label_dki, _label_reserve) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_CREATE_WITHDRAW, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_COIN, \ - .details.create_withdraw = {\ - .label_dki = _label_dki, \ - .label_reserve = _label_reserve, \ - } \ -} - -/** - * Inserts informations about a withdrawal in the database - * - * @exposes #PERF_TALER_MINTDB_COIN - * - * @param _label the label of this command - * @param _label_coin the coin to insert - */ -#define PERF_TALER_MINTDB_INIT_CMD_INSERT_WITHDRAW(_label, _label_coin) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_INSERT_WITHDRAW, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.insert_withdraw.label_coin = _label_coin\ -} - - -/** - * Polls the database about informations regarding a specific withdrawal - * - * @param _label the label of this command - * @param _label_coin the coin to check - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_WITHDRAW(_label, _label_coin) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_WITHDRAW, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.get_withdraw.label_coin = _label_coin, \ -} - - -/** - * The /reserve/withdraw api call - * - * Exposes #PERF_TALER_MINTDB_COIN - * - * @param _label the label of this command - * @param _label_dki the denomination of the created coin - * @param _label_reserve the reserve used to provide currency - */ -#define PERF_TALER_MINTDB_INIT_CMD_WITHDRAW_SIGN(_label, _label_dki, _label_reserve) \ - PERF_TALER_MINTDB_INIT_CMD_CREATE_WITHDRAW (_label "withdraw", \ - _label_dki, \ - _label_reserve), \ - PERF_TALER_MINTDB_INIT_CMD_GET_DENOMINATION(_label "withdraw info", \ - _label_dki), \ - PERF_TALER_MINTDB_INIT_CMD_GET_RESERVE_HISTORY(_label "reserve_history", \ - _label_reserve), \ - PERF_TALER_MINTDB_INIT_CMD_INSERT_WITHDRAW(_label "insert withdraw", \ - _label "withdraw") - -/** - * Create a deposit for use later - * @exposes #PERF_TALER_MINTDB_DEPOSIT - * - * @param _label the label of this command - * @param _label_coin the coin used to pay - */ -#define PERF_TALER_MINTDB_INIT_CMD_CREATE_DEPOSIT(_label, _label_coin) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_CREATE_DEPOSIT, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_DEPOSIT, \ - .details.create_deposit.label_coin = _label_coin, \ -} - -/** - * Insert a deposit into the database - * - * @param _label the label of this command - * @param _label_deposit the deposit inseerted - */ -#define PERF_TALER_MINTDB_INIT_CMD_INSERT_DEPOSIT(_label, _label_deposit) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_INSERT_DEPOSIT,\ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.insert_deposit.label_deposit = _label_deposit, \ -} - -/** - * Check if a deposit is in the database - * - * @param _label the label of this command - * @param _label_deposit the deposit to use - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_DEPOSIT(_label, _label_deposit) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_DEPOSIT, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.get_deposit.label_deposit = _label_deposit \ -} - -/** - * Access the transaction history of a coin - * - * @param _label the label of the command - * @param _label_coin the coin which history is checked - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_COIN_TRANSACTION(_label, _label_coin) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_COIN_TRANSACTION, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE, \ - .details.get_coin_transaction.label_coin = _label_coin \ -} - -/** - * The /deposit api call - * - * @param _label the label of the command - * @param _label_coin the coin used for the deposit - */ -#define PERF_TALER_MINTDB_INIT_CMD_DEPOSIT(_label, _label_coin) \ - PERF_TALER_MINTDB_INIT_CMD_GET_COIN_TRANSACTION (_label "coin history", \ - _label_coin), \ - PERF_TALER_MINTDB_INIT_CMD_CREATE_DEPOSIT (_label "deposit", \ - _label_coin), \ - PERF_TALER_MINTDB_INIT_CMD_INSERT_DEPOSIT (_label "insert", \ - _label "deposit") -/** - * Insert informations about a refresh session - * melts one coin into another - * - * @param _label the label of the command - */ -#define PERF_TALER_MINTDB_INIT_CMD_CREATE_REFRESH_SESSION(_label) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_CREATE_REFRESH_SESSION, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_REFRESH_HASH \ -} - -/** - * Get informations about a refresh session - * - * @param _label the label of the command - * @param _label_hash the label of the hash to search - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_REFRESH_SESSION(_label, \ - _label_hash) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_REFRESH_SESSION, \ - .label = _label, \ - .exposed.type = PERF_TALER_MINTDB_NONE \ -} - -/** - * Insert a melt operation in the database - * - * @param _label the label of the command - * @param _label_hash the label of the hash of the session - * @param _label_coin the label of the coin to melt - */ -#define PERF_TALER_MINTDB_INIT_CMD_INSERT_REFRESH_MELT(_label, \ - _label_hash, \ - _label_coin) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_INSERT_REFRESH_MELT, \ - .label = _label, \ - .details.insert_refresh_melt.label_hash = _label_hash, \ - .details.insert_refresh_melt.label_coin = _label_coin, \ - .exposed.type = PERF_TALER_MINTDB_NONE \ -} - -/** - * Get informations about a melt operation - * - * @param _label the label of the command - * @param _label_hash the label of the hash of the refresh session - */ -#define PERF_TALER_MINTDB_INIT_CMD_GET_REFRESH_MELT(_label, \ - _label_hash) \ -{ \ - .command = PERF_TALER_MINTDB_CMD_GET_REFRESH_MELT, \ - .label = _label, \ - .detail.get_refresh_melt.label_hash = _label_hash, \ - .exposed.type = PERF_TALER_MINTDB_NONE \ -} - -/** - * The type of data stored in #PERF_TALER_MINTDB_Memory - */ -enum PERF_TALER_MINTDB_Type -{ - PERF_TALER_MINTDB_NONE, - PERF_TALER_MINTDB_TIME, - PERF_TALER_MINTDB_DENOMINATION_INFO, - PERF_TALER_MINTDB_RESERVE, - PERF_TALER_MINTDB_COIN, - PERF_TALER_MINTDB_DEPOSIT, - PERF_TALER_MINTDB_REFRESH_HASH, - PERF_TALER_MINTDB_REFRESH_MELT -}; - - -/** - * Structure used to handle several data type - */ -struct PERF_TALER_MINTDB_Data -{ - enum PERF_TALER_MINTDB_Type type; - - /** - * Storage for a variety of data type - * The data saved should match #type - */ - union PERF_TALER_MINTDB_Memory - { - /** #PERF_TALER_MINTDB_TIME */ - struct GNUNET_TIME_Absolute *time; - /** #PERF_TALER_MINTDB_DEPOSIT */ - struct TALER_MINTDB_Deposit *deposit; - /** #PERF_TALER_MINTDB_COIN */ - struct PERF_TALER_MINTDB_Coin *coin; - /** #PERF_TALER_MINTDB_RESERVE */ - struct PERF_TALER_MINTDB_Reserve *reserve; - /** #PERF_TALER_MINTDB_DENOMINATION_INFO */ - struct TALER_MINTDB_DenominationKeyIssueInformation *dki; - /** #PERF_TALER_MINTDB_REFRESH_HASH */ - struct GNUNET_HashCode *session_hash; - /** #PERF_TALER_MINTDB_REFRESH_MELT */ - struct TALER_MINTDB_RefreshMelt *refresh_melt; - } data; -}; - - -/** - * Name of the command - */ -enum PERF_TALER_MINTDB_CMD_Name -{ - /** - * All comand chain must hace this as their last command - */ - PERF_TALER_MINTDB_CMD_END, - - /** - * Prints it's label - */ - PERF_TALER_MINTDB_CMD_DEBUG, - - /** - * Define the start of al command chain loop - */ - PERF_TALER_MINTDB_CMD_LOOP, - - /** - * Define the end of a command chain loop - */ - PERF_TALER_MINTDB_CMD_END_LOOP, - - /** - * Save the time at which the command was executed - */ - PERF_TALER_MINTDB_CMD_GET_TIME, - - /** - * Upload performance to Gauger - */ - PERF_TALER_MINTDB_CMD_GAUGER, - - /** - * Start a new session - */ - PERF_TALER_MINTDB_CMD_NEW_SESSION, - - /** - * Start a database transaction - */ - PERF_TALER_MINTDB_CMD_START_TRANSACTION, - - /** - * End a database transaction - */ - PERF_TALER_MINTDB_CMD_COMMIT_TRANSACTION, - - /** - * Abort a transaction started with #PERF_TALER_MINTDB_CMD_START_TRANSACTION - */ - PERF_TALER_MINTDB_CMD_ABORT_TRANSACTION, - - /** - * Saves random deposits from a loop - */ - PERF_TALER_MINTDB_CMD_SAVE_ARRAY, - - /** - * Load items saved earlier in a #PERF_TALER_MINTDB_CMD_SAVE_ARRAY - * The items are loaded in a random order, but all of them will be loaded - */ - PERF_TALER_MINTDB_CMD_LOAD_ARRAY, - - /** - * Loads a random item from a #PERF_TALER_MINTDB_CMD_SAVE_ARRAY - * A random item is loaded each time the command is run - */ - PERF_TALER_MINTDB_CMD_LOAD_RANDOM, - - /** - * Create a denomination to be used later - */ - PERF_TALER_MINTDB_CMD_CREATE_DENOMINATION, - - /** - * Insert informations about a denomination key in the database - */ - PERF_TALER_MINTDB_CMD_INSERT_DENOMINATION, - - /** - * Polls the database for informations about a specific denomination key - */ - PERF_TALER_MINTDB_CMD_GET_DENOMINATION, - - /** - * Create a reserve to be used later - */ - PERF_TALER_MINTDB_CMD_CREATE_RESERVE, - - /** - * Insert currency in a reserve / Create a reserve - */ - PERF_TALER_MINTDB_CMD_INSERT_RESERVE, - - /** - * Get Informations about a reserve - */ - PERF_TALER_MINTDB_CMD_GET_RESERVE, - - /** - * Get the history of a reserve - */ - PERF_TALER_MINTDB_CMD_GET_RESERVE_HISTORY, - - /** - * Create a withdrawal to be used later - */ - PERF_TALER_MINTDB_CMD_CREATE_WITHDRAW, - - /** - * Insert informations about a withdrawal in the database - */ - PERF_TALER_MINTDB_CMD_INSERT_WITHDRAW, - - /** - * Pulls informations about a withdrawal from the database - */ - PERF_TALER_MINTDB_CMD_GET_WITHDRAW, - - /** - * Get the list of all transactions the coin has been in - */ - PERF_TALER_MINTDB_CMD_GET_COIN_TRANSACTION, - - /** - * Create a deposit to be used later - */ - PERF_TALER_MINTDB_CMD_CREATE_DEPOSIT, - - /** - * Insert a deposit into the database - */ - PERF_TALER_MINTDB_CMD_INSERT_DEPOSIT, - - /** - * Check if a deposit is in the database - */ - PERF_TALER_MINTDB_CMD_GET_DEPOSIT, - - /** - * Create a refresh session - * The number of melted coins is 1, - * The number of minted coins is 1 - */ - PERF_TALER_MINTDB_CMD_CREATE_REFRESH_SESSION, - - /** - * Get a refresh session informations - */ - PERF_TALER_MINTDB_CMD_GET_REFRESH_SESSION, - - /** - * Insert a refresh melt - */ - PERF_TALER_MINTDB_CMD_INSERT_REFRESH_MELT, - - /** - * Get informations about a refresh melt operation - */ - PERF_TALER_MINTDB_CMD_GET_REFRESH_MELT, - - /** - * Insert a melt refresh order - */ - PERF_TALER_MINTDB_CMD_INSERT_REFRESH_ORDER, - - /** - * Get informations about a refresh order - */ - PERF_TALER_MINTDB_CMD_GET_REFRESH_ORDER, - - /** - * Insert refresh commit coin - */ - PERF_TALER_MINTDB_CMD_INSERT_REFRESH_COMMIT_COIN, - - /** - * Get refresh commit coin - */ - PERF_TALER_MINTDB_CMD_GET_REFRESH_COMMIT_COIN, - - /** - * Insert refresh commit link - */ - PERF_TALER_MINTDB_CMD_INSERT_REFRESH_COMMIT_LINK, - - /** - * Get refresh commit link - */ - PERF_TALER_MINTDB_CMD_GET_REFRESH_COMMIT_LINK, - - /** - * Get information avout the melt commit - */ - PERF_TALER_MINTDB_CMD_GET_MELT_COMMITMENT, - - /** - * Insert a new coin into the database after a melt operation - */ - PERF_TALER_MINTDB_CMD_INSERT_REFRESH_OUT, - - /** - * Get the link data list of a coin - */ - PERF_TALER_MINTDB_CMD_GET_LINK_DATA_LIST, - - /** - * Get the shared secret and the transfere public key - */ - PERF_TALER_MINTDB_CMD_GET_TRANSFER - -}; - - -/** - * Contains extra data required for any command - */ -union PERF_TALER_MINTDB_CMD_Details -{ - /** - * Extra data requiered for the #PERF_TALER_MINTDB_CMD_LOOP command - */ - struct PERF_TALER_MINTDB_CMD_loopDetails - { - /** - * Maximum number of iteration in the loop - */ - const unsigned int max_iterations; - - /** - * The current iteration of the loop - */ - unsigned int curr_iteration; - } loop; - - /** - * Extra data requiered by the #PERF_TALER_MINTDB_CMD_END_LOOP command - */ - struct PERF_TALER_MINTDB_CMD_endLoopDetails - { - /** - * Label of the loop closed by the command - */ - const char *label_loop; - unsigned int index_loop; - } end_loop; - - /** - * Details about the #PERF_TALER_MINTDB_CMD_GAUGER command - */ - struct PERF_TALER_MINTDB_CMD_gaugerDetails - { - /** - * Label of the starting timestamp - */ - const char *label_start; - unsigned int index_start; - - /** - * Label of the ending timestamp - */ - const char *label_stop; - unsigned int index_stop; - - /** - * The category of the measurment - */ - const char *category; - - /** - * Description of the metric, used in Gauger - */ - const char *description; - - /** - * The name of the metric beeing used - */ - const char *unit; - - /** - * Constant the result needs to be divided by - * to get the result per unit - */ - float divide; - } gauger; - - /** - * Contains extra data requiered by the #PERF_TALER_MINTDB_CMD_SAVE_ARRAY command - */ - struct PERF_TALER_MINTDB_CMD_saveArrayDetails - { - /** - * Number of items to save - */ - unsigned int nb_saved; - - /** - * Number of items already saved - */ - unsigned int index; - - /** - * Label of the loop it is attached to - */ - const char *label_loop; - unsigned int index_loop; - - /** - * Label of the command exposing the item - */ - const char *label_save; - unsigned int index_save; - - /** - * Array of data saved - */ - struct PERF_TALER_MINTDB_Data *data_saved; - - /** - * Type of the data that will be stored in @a data_saved, for - * 'static' type checking. - */ - enum PERF_TALER_MINTDB_Type type_saved; - - } save_array; - - /** - * Extra data required for the #PERF_TALER_MINTDB_CMD_LOAD_ARRAY command - */ - struct PERF_TALER_MINTDB_CMD_loadArrayDetails - { - /** - * The loop in which the command is located - */ - const char *label_loop; - unsigned int index_loop; - - /** - * Label of the command where the items were saved - */ - const char *label_save; - unsigned int index_save; - - /** - * A permutation array used to randomize the order the items are loaded in - */ - unsigned int *permutation; - } load_array; - - /** - * Contains data for the #PERF_TALER_MINTDB_CMD_LOAD_RANDOM command - */ - struct PERF_TALER_MINTDB_CMD_loadRandomDetails - { - /** - * The label of the #PERF_TALER_MINTDB_CMD_SAVE_ARRAY the items will be extracted from - */ - const char *label_save; - unsigned int index_save; - } load_random; - - /** - * Extra data requiered by the #PERF_TALER_MINTDB_CMD_INSERT_DENOMINATION command - */ - struct PERF_TALER_MINTDB_CMD_insertDenominationDetails - { - /** - * The label of the source of the denomination to insert - */ - const char *label_denom; - unsigned int index_denom; - } insert_denomination; - - /** - * Extra data requiered by the #PERF_TALER_MINTDB_CMD_GET_DENOMINATION command - */ - struct PERF_TALER_MINTDB_CMD_getDenominationDetails - { - /** - * The label of the source of the denomination to check - */ - const char *label_denom; - unsigned int index_denom; - } get_denomination; - - /** - * Extra data requiered for the #PERF_TALER_MINTDB_CMD_INSERT_RESERVE command - */ - struct PERF_TALER_MINTDB_CMD_insertReserveDetails - { - /** - * The label of the source of the reserve to insert - */ - const char *label_reserve; - unsigned int index_reserve; - } insert_reserve; - - /** - * Extra data requiered for the #PERF_TALER_MINTDB_CMD_GET_RESERVE command - */ - struct PERF_TALER_MINTDB_CMD_getReserveDetails - { - /** - * The label of the source of the reserve to check - */ - const char *label_reserve; - unsigned int index_reserve; - } get_reserve; - - /** - * Extra data requiered for the #PERF_TALER_MINTDB_CMD_GET_RESERVE_HISTORY command - */ - struct PERF_TALER_MINTDB_CMD_getReserveHistoryDetails - { - /** - * The label of the source of the reserve to check - */ - const char *label_reserve; - unsigned int index_reserve; - } get_reserve_history; - - /** - * Extra data related to the #PERF_TALER_MINTDB_CMD_CREATE_WITHDRAW command - */ - struct PERF_TALER_MINTDB_CMD_createWithdrawDetails - { - /** - * label of the denomination key used to sign the coin - */ - const char *label_dki; - unsigned int index_dki; - - /** - * label of the reserve the money to mint the coin comes from - */ - const char *label_reserve; - unsigned int index_reserve; - } create_withdraw; - - /** - * data requiered for the #PERF_TALER_MINTDB_CMD_INSERT_WITHDRAW - */ - struct PERF_TALER_MINTDB_CMD_insertWithdrawDetails - { - /** - * label of the source for the coin information - */ - const char *label_coin; - unsigned int index_coin; - } insert_withdraw; - - /** - * data requiered for the #PERF_TALER_MINTDB_CMD_GET_WITHDRAW - */ - struct PERF_TALER_MINTDB_CMD_getWithdraw - { - /** - * label of the source for the coin information - */ - const char *label_coin; - unsigned int index_coin; - } get_withdraw; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_GET_COIN_TRANSACTION command - */ - struct PERF_TALER_MINTDB_CMD_getCoinTransactionDetails - { - /** - * The coin which history is checked - */ - const char *label_coin; - unsigned int index_coin; - } get_coin_transaction; - - /** - * Data used by the #PERF_TALER_MINTDB_CMD_CREATE_DEPOSIT command - */ - struct PERF_TALER_MINTDB_CMD_createDepositDetails - { - /** - * Label of the source where the reserve used to create the coin is - */ - const char *label_coin; - unsigned int index_coin; - } create_deposit; - - /** - * Extra data requiered for the #PERF_TALER_MINTDB_CMD_INSERT_DEPOSIT command - */ - struct PERF_TALER_MINTDB_CMD_insertDepositDetails - { - /** - * The label of the source of the deposit to check - */ - const char *label_deposit; - unsigned int index_deposit; - } insert_deposit; - - /** - * Extra data requiered for the #PERF_TALER_MINTDB_CMD_GET_DEPOSIT command - */ - struct PERF_TALER_MINTDB_CMD_getDepositDetails - { - /** - * The label of the source of the deposit to check - */ - const char *label_deposit; - unsigned int index_deposit; - } get_deposit; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_GET_REFRESH_SESSION command - */ - struct PERF_TALER_MINTDB_CMD_getRefreshSessionDetails - { - /** - * label of the source of the hash of the session - */ - const char *label_hash; - unsigned int index_hash; - } get_refresh_session; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_INSERT_REFRESH_MELT command - */ - struct PERF_TALER_MINTDB_CMD_insertRefreshMeltDetails - { - /** - * The label of the hash of the refresh session - */ - const char *label_hash; - unsigned int index_hash; - - /** - * The label of the coin to melt - */ - const char *label_coin; - unsigned int index_coin; - } insert_refresh_melt; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_GET_REFRESH_MELT command - */ - struct PERF_TALER_MINTDB_CMD_getRefreshMeltDetails - { - /** - * The label of the hash of the session - */ - const char *label_hash; - unsigned int index_hash; - } get_refresh_melt; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_INSERT_REFRESH_ORDER command - */ - struct PERF_TALER_MINTDB_CMD_insertRefreshOrderDetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - - /** - * The new coin denomination - */ - const char *label_denom; - unsigned int index_denom; - } insert_refresh_order; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_GET_REFRESH_ORDER command - */ - struct PERF_TALER_MINTDB_CMD_getRefreshOrderDetails - { - /** - * The session hash - */ - const char *label_hash; - unsigned int index_hash; - - } get_refresh_order; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_INSERT_REFRESH_COMMIT_COIN command - */ - struct PERF_TALER_MINTDB_CMD_insertRefreshCommitCoinDetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - - } insert_refresh_commit_coin; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_GET_REFRESH_COMMIT_COIN command - */ - struct PERF_TALER_MINTDB_CMD_getRefreshCommitCoinDetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - - } get_refresh_commit_coin; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_INSERT_REFRESH_COMMIT_LINK command - */ - struct PERF_TALER_MINTDB_CMD_insertRefreshCommitLinkDetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - - } insert_refresh_commit_link; - - /** - * Data requiered by the #PERF_TALER_MINTDB_CMD_GET_REFRESH_COMMIT_LINK command - */ - struct PERF_TALER_MINTDB_CMD_getRefreshCommitLinkDetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - } get_refresh_commit_link; - - /** - * Data requiered for the #PERF_TALER_MINTDB_CMD_GET_MELT_COMMITMENT command - */ - struct PERF_TALER_MINTDB_CMD_getMeltCommitmentDaetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - } get_melt_commitment; - - /** - * Data requiered by the #PERF_TALER_MINTDB_CMD_INSERT_REFRESH_OUT command - */ - struct PERF_TALER_MINTDB_CMD_insertRefreshOutDetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - } insert_refresh_out; - - /** - * Data requiered by the #PERF_TALER_MINTDB_CMD_GET_LINK_DATA_LIST command - */ - struct PERF_TALER_MINTDB_CMD_getLinkDataListDetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - } get_link_data_list; - - /** - * Data requiered by the #PERF_TALER_MINTDB_CMD_GET_TRANSFER command - */ - struct PERF_TALER_MINTDB_CMD_getTransferDetails - { - /** - * The refresh session hash - */ - const char *label_hash; - unsigned int index_hash; - } get_transfer; - -}; - - -/** - * Command to be interpreted. - */ -struct PERF_TALER_MINTDB_Cmd -{ - /** - * Type of the command - */ - enum PERF_TALER_MINTDB_CMD_Name command; - - /** - * Label to refer to the command - */ - const char *label; - - /** - * Command specific data - */ - union PERF_TALER_MINTDB_CMD_Details details; - - /** - * Data easily accessible - */ - struct PERF_TALER_MINTDB_Data exposed; -}; - - -/** - * Run a benchmark - * - * @param benchmark_name the name of the benchmark, displayed in the logs - * @param configuration_file path to the taler configuration file to use - * @param init the commands to use for the database initialisation, - * if #NULL the standard initialization is used - * @param benchmark the commands for the benchmark - * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure - */ -int -PERF_TALER_MINTDB_run_benchmark (const char *benchmark_name, - const char *configuration_file, - struct PERF_TALER_MINTDB_Cmd *init, - struct PERF_TALER_MINTDB_Cmd *benchmark); - - -/** - * Runs the command array @a cmd - * using @a db_plugin to connect to the database - * - * @param db_plugin the connection to the database - * @param cmd the commands to run - */ -int -PERF_TALER_MINTDB_interpret( - struct TALER_MINTDB_Plugin *db_plugin, - struct PERF_TALER_MINTDB_Cmd cmd[]); - - -/** - * Check if the given command array is syntaxicly correct - * This will check if the label are corrects but will not check if - * they are pointing to an apropriate command. - * - * @param cmd the command array to check - * @return #GNUNET_OK is @a cmd is correct; #GNUNET_SYSERR if it is'nt - */ -int -PERF_TALER_MINTDB_check (const struct PERF_TALER_MINTDB_Cmd *cmd); - -#endif diff --git a/src/mintdb/perf_taler_mintdb_values.h b/src/mintdb/perf_taler_mintdb_values.h deleted file mode 100644 index 35f87f5b0..000000000 --- a/src/mintdb/perf_taler_mintdb_values.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> - */ -/** - * @file mintdb/perf_taler_mintdb_values.h - * @brief Values for tweaking the performance analysis - * @author Nicolas Fournier - */ -#ifndef __PERF_TALER_MINTDB__VALUES_H__ -#define __PERF_TALER_MINTDB__VALUES_H__ - - -#endif diff --git a/src/mintdb/plugin_mintdb_common.c b/src/mintdb/plugin_mintdb_common.c deleted file mode 100644 index 1f2fdc58b..000000000 --- a/src/mintdb/plugin_mintdb_common.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file mintdb/plugin_mintdb_common.c - * @brief Functions shared across plugins, this file is meant to be - * included in each plugin. - * @author Christian Grothoff - */ - -/** - * Free memory associated with the given reserve history. - * - * @param cls the @e cls of this struct with the plugin-specific state (unused) - * @param rh history to free. - */ -static void -common_free_reserve_history (void *cls, - struct TALER_MINTDB_ReserveHistory *rh) -{ - struct TALER_MINTDB_BankTransfer *bt; - struct TALER_MINTDB_CollectableBlindcoin *cbc; - struct TALER_MINTDB_ReserveHistory *backref; - - while (NULL != rh) - { - switch(rh->type) - { - case TALER_MINTDB_RO_BANK_TO_MINT: - bt = rh->details.bank; - if (NULL != bt->wire) - json_decref (bt->wire); - GNUNET_free (bt); - break; - case TALER_MINTDB_RO_WITHDRAW_COIN: - cbc = rh->details.withdraw; - GNUNET_CRYPTO_rsa_signature_free (cbc->sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (cbc->denom_pub.rsa_public_key); - GNUNET_free (cbc); - break; - } - backref = rh; - rh = rh->next; - GNUNET_free (backref); - } -} - - -/** - * Free memory of the link data list. - * - * @param cls the @e cls of this struct with the plugin-specific state (unused) - * @param ldl link data list to release - */ -static void -common_free_link_data_list (void *cls, - struct TALER_MINTDB_LinkDataList *ldl) -{ - struct TALER_MINTDB_LinkDataList *next; - - while (NULL != ldl) - { - next = ldl->next; - GNUNET_free (ldl->link_data_enc); - GNUNET_free (ldl); - ldl = next; - } -} - - -/** - * Free linked list of transactions. - * - * @param cls the @e cls of this struct with the plugin-specific state (unused) - * @param list list to free - */ -static void -common_free_coin_transaction_list (void *cls, - struct TALER_MINTDB_TransactionList *list) -{ - struct TALER_MINTDB_TransactionList *next; - - while (NULL != list) - { - next = list->next; - - switch (list->type) - { - case TALER_MINTDB_TT_DEPOSIT: - json_decref (list->details.deposit->wire); - GNUNET_CRYPTO_rsa_public_key_free (list->details.deposit->coin.denom_pub.rsa_public_key); - GNUNET_CRYPTO_rsa_signature_free (list->details.deposit->coin.denom_sig.rsa_signature); - GNUNET_free (list->details.deposit); - break; - case TALER_MINTDB_TT_REFRESH_MELT: - GNUNET_free (list->details.melt); - break; - } - GNUNET_free (list); - list = next; - } -} - - -/** - * Free melt commitment data. - * - * @param cls the @e cls of this struct with the plugin-specific state (unused) - * @param mc data structure to free - */ -static void -common_free_melt_commitment (void *cls, - struct TALER_MINTDB_MeltCommitment *mc) -{ - unsigned int i; - unsigned int k; - - if (NULL != mc->melts) - { - for (i=0;i<mc->num_oldcoins;i++) - { - GNUNET_CRYPTO_rsa_signature_free (mc->melts[i].coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (mc->melts[i].coin.denom_pub.rsa_public_key); - } - GNUNET_free (mc->melts); - } - if (NULL != mc->denom_pubs) - { - for (i=0;i<mc->num_newcoins;i++) - if (NULL != mc->denom_pubs[i].rsa_public_key) - GNUNET_CRYPTO_rsa_public_key_free (mc->denom_pubs[i].rsa_public_key); - GNUNET_free (mc->denom_pubs); - } - for (k=0;k<TALER_CNC_KAPPA;k++) - { - if (NULL != mc->commit_coins[k]) - { - for (i=0;i<mc->num_newcoins;i++) - { - GNUNET_free (mc->commit_coins[k][i].refresh_link); - GNUNET_free (mc->commit_coins[k][i].coin_ev); - } - GNUNET_free (mc->commit_coins[k]); - } - GNUNET_free_non_null (mc->commit_links[k]); - } - GNUNET_free (mc); -} - -/* end of plugin_mintdb_common.c */ diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c deleted file mode 100644 index 772b86e83..000000000 --- a/src/mintdb/plugin_mintdb_postgres.c +++ /dev/null @@ -1,4295 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015, 2016 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> -*/ - -/** - * @file plugin_mintdb_postgres.c - * @brief Low-level (statement-level) Postgres database access for the mint - * @author Florian Dold - * @author Christian Grothoff - * @author Sree Harsha Totakura - */ -#include "platform.h" -#include "taler_pq_lib.h" -#include "taler_mintdb_plugin.h" -#include <pthread.h> -#include <libpq-fe.h> - -#include "plugin_mintdb_common.c" - -/** - * For testing / experiments, we set the Postgres schema to - * #TALER_TEMP_SCHEMA_NAME so we can easily purge everything - * associated with a test. We *also* should use the database - * "talercheck" instead of "taler" for testing, but we're doing - * both: better safe than sorry. - */ -#define TALER_TEMP_SCHEMA_NAME "taler_temporary" - -/** - * Log a query error. - * - * @param result PQ result object of the query that failed - */ -#define QUERY_ERR(result) \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Query failed at %s:%u: %s\n", __FILE__, __LINE__, PQresultErrorMessage (result)) - - -/** - * Log a really unexpected PQ error. - * - * @param result PQ result object of the PQ operation that failed - */ -#define BREAK_DB_ERR(result) do { \ - GNUNET_break (0); \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Database failure: %s\n", PQresultErrorMessage (result)); \ - } while (0) - - -/** - * Shorthand for exit jumps. Logs the current line number - * and jumps to the "EXITIF_exit" label. - * - * @param cond condition that must be TRUE to exit with an error - */ -#define EXITIF(cond) \ - do { \ - if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ - } while (0) - - -/** - * Execute an SQL statement and log errors on failure. Must be - * run in a function that has an "SQLEXEC_fail" label to jump - * to in case the SQL statement failed. - * - * @param conn database connection - * @param sql SQL statement to run - */ -#define SQLEXEC_(conn, sql) \ - do { \ - PGresult *result = PQexec (conn, sql); \ - if (PGRES_COMMAND_OK != PQresultStatus (result)) \ - { \ - BREAK_DB_ERR (result); \ - PQclear (result); \ - goto SQLEXEC_fail; \ - } \ - PQclear (result); \ - } while (0) - - -/** - * Run an SQL statement, ignoring errors and clearing the result. - * - * @param conn database connection - * @param sql SQL statement to run - */ -#define SQLEXEC_IGNORE_ERROR_(conn, sql) \ - do { \ - PGresult *result = PQexec (conn, sql); \ - PQclear (result); \ - } while (0) - - -/** - * Handle for a database session (per-thread, for transactions). - */ -struct TALER_MINTDB_Session -{ - /** - * Postgres connection handle. - */ - PGconn *conn; -}; - - -/** - * Type of the "cls" argument given to each of the functions in - * our API. - */ -struct PostgresClosure -{ - - /** - * Thread-local database connection. - * Contains a pointer to `PGconn` or NULL. - */ - pthread_key_t db_conn_threadlocal; - - /** - * Database connection string, as read from - * the configuration. - */ - char *connection_cfg_str; -}; - - - -/** - * Set the given connection to use a temporary schema - * - * @param db the database connection - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon error - */ -static int -set_temporary_schema (PGconn *db) -{ - SQLEXEC_(db, - "CREATE SCHEMA IF NOT EXISTS " TALER_TEMP_SCHEMA_NAME ";" - "SET search_path to " TALER_TEMP_SCHEMA_NAME ";"); - return GNUNET_OK; - SQLEXEC_fail: - return GNUNET_SYSERR; -} - - -/** - * Drop the temporary taler schema. This is only useful for testcases - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database session to use - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure - */ -static int -postgres_drop_temporary (void *cls, - struct TALER_MINTDB_Session *session) -{ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Dropping temporary tables\n"); - SQLEXEC_ (session->conn, - "DROP SCHEMA " TALER_TEMP_SCHEMA_NAME " CASCADE;"); - return GNUNET_OK; - SQLEXEC_fail: - return GNUNET_SYSERR; -} - - -/** - * Function called by libpq whenever it wants to log something. - * We already log whenever we care, so this function does nothing - * and merely exists to silence the libpq logging. - * - * @param arg NULL - * @param res information about some libpq event - */ -static void -pq_notice_receiver_cb (void *arg, - const PGresult *res) -{ - /* do nothing, intentionally */ -} - - -/** - * Function called by libpq whenever it wants to log something. - * We log those using the Taler logger. - * - * @param arg NULL - * @param message information about some libpq event - */ -static void -pq_notice_processor_cb (void *arg, - const char *message) -{ - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, - "pq", - "%s", - message); -} - - -/** - * Create the necessary tables if they are not present - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param temporary should we use a temporary schema - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure - */ -static int -postgres_create_tables (void *cls, - int temporary) -{ - struct PostgresClosure *pc = cls; - PGconn *conn; - - conn = PQconnectdb (pc->connection_cfg_str); - if (CONNECTION_OK != PQstatus (conn)) - { - TALER_LOG_ERROR ("Database connection failed: %s\n", - PQerrorMessage (conn)); - PQfinish (conn); - return GNUNET_SYSERR; - } - PQsetNoticeReceiver (conn, - &pq_notice_receiver_cb, - NULL); - PQsetNoticeProcessor (conn, - &pq_notice_processor_cb, - NULL); - if ( (GNUNET_YES == temporary) && - (GNUNET_SYSERR == set_temporary_schema (conn))) - { - PQfinish (conn); - return GNUNET_SYSERR; - } -#define SQLEXEC(sql) SQLEXEC_(conn, sql); -#define SQLEXEC_INDEX(sql) SQLEXEC_IGNORE_ERROR_(conn, sql); - /* Denomination table for holding the publicly available information of - denominations keys. The denominations are to be referred to by using - foreign keys. The denominations are deleted by a housekeeping tool; - hence, do not use `ON DELETE CASCADE' on these rows in the tables - referencing these rows */ - SQLEXEC ("CREATE TABLE IF NOT EXISTS denominations" - "(pub BYTEA PRIMARY KEY" - ",master_pub BYTEA NOT NULL CHECK (LENGTH(master_pub)=32)" - ",master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)" - ",valid_from INT8 NOT NULL" - ",expire_withdraw INT8 NOT NULL" - ",expire_spend INT8 NOT NULL" - ",expire_legal INT8 NOT NULL" - ",coin_val INT8 NOT NULL" /* value of this denom */ - ",coin_frac INT4 NOT NULL" /* fractional value of this denom */ - ",coin_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" /* assuming same currency for fees */ - ",fee_withdraw_val INT8 NOT NULL" - ",fee_withdraw_frac INT4 NOT NULL" - ",fee_withdraw_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",fee_deposit_val INT8 NOT NULL" - ",fee_deposit_frac INT4 NOT NULL" - ",fee_deposit_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",fee_refresh_val INT8 NOT NULL" - ",fee_refresh_frac INT4 NOT NULL" - ",fee_refresh_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ")"); - /* reserves table is for summarization of a reserve. It is updated when new - funds are added and existing funds are withdrawn. The 'expiration_date' - can be used to eventually get rid of reserves that have not been used - for a very long time (either by refunding the owner or by greedily - grabbing the money, depending on the Mint's terms of service) */ - SQLEXEC ("CREATE TABLE IF NOT EXISTS reserves" - "(reserve_pub BYTEA PRIMARY KEY" - ",current_balance_val INT8 NOT NULL" - ",current_balance_frac INT4 NOT NULL" - ",current_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",expiration_date INT8 NOT NULL" - ")"); - /* index on reserves table */ - SQLEXEC_INDEX ("CREATE INDEX reserves_reserve_pub_index ON " - "reserves (reserve_pub)"); - /* reserves_in table collects the transactions which transfer funds - into the reserve. The rows of this table correspond to each - incoming transaction. */ - SQLEXEC("CREATE TABLE IF NOT EXISTS reserves_in" - "(reserve_pub BYTEA REFERENCES reserves (reserve_pub) ON DELETE CASCADE" - ",balance_val INT8 NOT NULL" - ",balance_frac INT4 NOT NULL" - ",balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",details TEXT NOT NULL " - ",execution_date INT8 NOT NULL" - ",PRIMARY KEY (reserve_pub,details)" - ");"); - /* Create indices on reserves_in */ - SQLEXEC_INDEX ("CREATE INDEX reserves_in_reserve_pub_index" - " ON reserves_in (reserve_pub);"); - SQLEXEC_INDEX ("CREATE INDEX reserves_in_reserve_pub_details_index" - " ON reserves_in (reserve_pub,details);"); - SQLEXEC_INDEX ("CREATE INDEX execution_index" - " ON reserves_in (execution_date);"); - /* Table with the withdraw operations that have been performed on a reserve. - The 'h_blind_ev' is the hash of the blinded coin. It serves as a primary - key, as (broken) clients that use a non-random coin and blinding factor - should fail to even withdraw, as otherwise the coins will fail to deposit - (as they really must be unique). */ - SQLEXEC ("CREATE TABLE IF NOT EXISTS reserves_out" - "(h_blind_ev BYTEA PRIMARY KEY" - ",denom_pub BYTEA NOT NULL REFERENCES denominations (pub)" - ",denom_sig BYTEA NOT NULL" - ",reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32) REFERENCES reserves (reserve_pub) ON DELETE CASCADE" - ",reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)" - ",execution_date INT8 NOT NULL" - ",amount_with_fee_val INT8 NOT NULL" - ",amount_with_fee_frac INT4 NOT NULL" - ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",withdraw_fee_val INT8 NOT NULL" - ",withdraw_fee_frac INT4 NOT NULL" - ",withdraw_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ");"); - /* Index blindcoins(reserve_pub) for get_reserves_out statement */ - SQLEXEC_INDEX ("CREATE INDEX reserves_out_reserve_pub_index ON" - " reserves_out (reserve_pub)"); - SQLEXEC_INDEX ("CREATE INDEX reserves_out_h_blind_ev_index ON " - "reserves_out (h_blind_ev)"); - /* Table with coins that have been (partially) spent, used to track - coin information only once. */ - SQLEXEC("CREATE TABLE IF NOT EXISTS known_coins " - "(coin_pub BYTEA NOT NULL PRIMARY KEY" - ",denom_pub BYTEA NOT NULL REFERENCES denominations (pub)" - ",denom_sig BYTEA NOT NULL" - ")"); - /** - * The DB will show negative values for some values of the following fields as - * we use them as 16 bit unsigned integers - * @a num_oldcoins - * @a num_newcoins - * Do not do arithmetic in SQL on these fields. - * NOTE: maybe we should instead forbid values >= 2^15 categorically? - */ - SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_sessions " - "(session_hash BYTEA PRIMARY KEY CHECK (LENGTH(session_hash)=64)" - ",num_oldcoins INT2 NOT NULL" - ",num_newcoins INT2 NOT NULL" - ",noreveal_index INT2 NOT NULL" - ")"); - /* Table with coins that have been melted. Gives the coin's public - key (coin_pub), the melting session, the index of this coin in that - session, the signature affirming the melting and the amount that - this coin contributed to the melting session. - */ - SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_melts " - "(coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)" - ",session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash)" - ",oldcoin_index INT2 NOT NULL" - ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)" - ",amount_with_fee_val INT8 NOT NULL" - ",amount_with_fee_frac INT4 NOT NULL" - ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",melt_fee_val INT8 NOT NULL" - ",melt_fee_frac INT4 NOT NULL" - ",melt_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",PRIMARY KEY (session_hash, oldcoin_index)" /* a coin can be used only - once in a refresh session */ - ") "); - /* Table with information about the desired denominations to be created - during a refresh operation; contains the denomination key for each - of the coins (for a given refresh session) */ - SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_order " - "(session_hash BYTEA NOT NULL CHECK (LENGTH(session_hash)=64) REFERENCES refresh_sessions (session_hash)" - ",newcoin_index INT2 NOT NULL " - ",denom_pub BYTEA NOT NULL REFERENCES denominations (pub)" - ",PRIMARY KEY (session_hash, newcoin_index)" - ")"); - - /* Table with the commitments for a refresh operation; includes - the session_hash for which this is the link information, the - oldcoin index and the cut-and-choose index (from 0 to #TALER_CNC_KAPPA-1), - as well as the actual link data (the transfer public key and the encrypted - link secret). - NOTE: We might want to simplify this and not have the oldcoin_index - and instead store all link secrets, one after the other, in one big BYTEA. - (#3814) */ - SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_link " - "(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash)" - ",transfer_pub BYTEA NOT NULL CHECK(LENGTH(transfer_pub)=32)" - ",link_secret_enc BYTEA NOT NULL" - ",oldcoin_index INT2 NOT NULL" - ",cnc_index INT2 NOT NULL" - ")"); - /* Table with the commitments for the new coins that are to be created - during a melting session. Includes the session, the cut-and-choose - index and the index of the new coin, and the envelope of the new - coin to be signed, as well as the encrypted information about the - private key and the blinding factor for the coin (for verification - in case this cnc_index is chosen to be revealed) - - NOTE: We might want to simplify this and not have the - newcoin_index and instead store all coin_evs and - link_vector_encs, one after the other, in two big BYTEAs. - (#3815) */ - SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_coin " - "(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash) " - ",cnc_index INT2 NOT NULL" - ",newcoin_index INT2 NOT NULL" - ",link_vector_enc BYTEA NOT NULL" - ",coin_ev BYTEA NOT NULL" - ")"); - /* Table with the signatures over coins generated during a refresh - operation. Needed to answer /refresh/link queries later. Stores - the coin signatures under the respective session hash and index. */ - SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_out " - "(session_hash BYTEA NOT NULL CHECK(LENGTH(session_hash)=64) REFERENCES refresh_sessions (session_hash) " - ",newcoin_index INT2 NOT NULL" - ",ev_sig BYTEA NOT NULL" - ")"); - /* This table contains the wire transfers the mint is supposed to - execute to transmit funds to the merchants (and manage refunds). */ - SQLEXEC("CREATE TABLE IF NOT EXISTS deposits " - "(serial_id BIGSERIAL PRIMARY KEY" - ",coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)" - ",denom_pub BYTEA NOT NULL REFERENCES denominations (pub)" - ",denom_sig BYTEA NOT NULL" - ",transaction_id INT8 NOT NULL" - ",amount_with_fee_val INT8 NOT NULL" - ",amount_with_fee_frac INT4 NOT NULL" - ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",deposit_fee_val INT8 NOT NULL" - ",deposit_fee_frac INT4 NOT NULL" - ",deposit_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",timestamp INT8 NOT NULL" - ",refund_deadline INT8 NOT NULL" - ",wire_deadline INT8 NOT NULL" - ",merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)" - ",h_contract BYTEA NOT NULL CHECK (LENGTH(h_contract)=64)" - ",h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64)" - ",coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)" - ",wire TEXT NOT NULL" - ",tiny BOOLEAN NOT NULL DEFAULT false" - ",done BOOLEAN NOT NULL DEFAULT false" - ")"); - /* Index for get_deposit statement on coin_pub, transaction_id and merchant_pub */ - SQLEXEC_INDEX("CREATE INDEX deposits_coin_pub_index " - "ON deposits(coin_pub, transaction_id, merchant_pub)"); - /* Table for the tracking API, mapping from wire transfer identifiers - to transactions and back */ - SQLEXEC("CREATE TABLE IF NOT EXISTS aggregation_tracking " - "(h_contract BYTEA CHECK (LENGTH(h_contract)=64)" - ",h_wire BYTEA CHECK (LENGTH(h_wire)=64)" - ",coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)" - ",merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)" - ",transaction_id INT8 NOT NULL" - ",wtid_raw BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=" TALER_WIRE_TRANSFER_IDENTIFIER_LEN_STR ")" - ",execution_time INT8 NOT NULL" - ",coin_amount_val INT8 NOT NULL" - ",coin_amount_frac INT4 NOT NULL" - ",coin_amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",coin_fee_val INT8 NOT NULL" - ",coin_fee_frac INT4 NOT NULL" - ",coin_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ")"); - /* Index for lookup_transactions statement on wtid */ - SQLEXEC_INDEX("CREATE INDEX aggregation_tracking_wtid_index " - "ON aggregation_tracking(wtid_raw)"); - /* Index for lookup_deposit_wtid statement */ - SQLEXEC_INDEX("CREATE INDEX aggregation_tracking_deposit_index " - "ON aggregation_tracking(coin_pub,h_contract,h_wire,transaction_id,merchant_pub)"); - - /* This table contains the pre-commit data for - wire transfers the mint is about to execute. */ - SQLEXEC("CREATE TABLE IF NOT EXISTS prewire " - "(serial_id BIGSERIAL PRIMARY KEY" - ",type TEXT NOT NULL" - ",finished BOOLEAN NOT NULL DEFAULT false" - ",buf BYTEA NOT NULL" - ")"); - /* Index for prepare_data_iterate statement */ - SQLEXEC_INDEX("CREATE INDEX prepare_iteration_index " - "ON prewire(type,finished)"); - - -#undef SQLEXEC -#undef SQLEXEC_INDEX - - PQfinish (conn); - return GNUNET_OK; - - SQLEXEC_fail: - PQfinish (conn); - return GNUNET_SYSERR; -} - - -/** - * Setup prepared statements. - * - * @param db_conn connection handle to initialize - * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure - */ -static int -postgres_prepare (PGconn *db_conn) -{ - PGresult *result; - -#define PREPARE(name, sql, ...) \ - do { \ - result = PQprepare (db_conn, name, sql, __VA_ARGS__); \ - if (PGRES_COMMAND_OK != PQresultStatus (result)) \ - { \ - BREAK_DB_ERR (result); \ - PQclear (result); result = NULL; \ - return GNUNET_SYSERR; \ - } \ - PQclear (result); result = NULL; \ - } while (0); - - /* Used in #postgres_insert_denomination_info() */ - PREPARE ("denomination_insert", - "INSERT INTO denominations " - "(pub" - ",master_pub" - ",master_sig" - ",valid_from" - ",expire_withdraw" - ",expire_spend" - ",expire_legal" - ",coin_val" /* value of this denom */ - ",coin_frac" /* fractional value of this denom */ - ",coin_curr" /* assuming same currency for fees */ - ",fee_withdraw_val" - ",fee_withdraw_frac" - ",fee_withdraw_curr" /* must match coin_curr */ - ",fee_deposit_val" - ",fee_deposit_frac" - ",fee_deposit_curr" /* must match coin_curr */ - ",fee_refresh_val" - ",fee_refresh_frac" - ",fee_refresh_curr" /* must match coin_curr */ - ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," - " $11, $12, $13, $14, $15, $16, $17, $18, $19);", - 19, NULL); - - /* Used in #postgres_get_denomination_info() */ - PREPARE ("denomination_get", - "SELECT" - " master_pub" - ",master_sig" - ",valid_from" - ",expire_withdraw" - ",expire_spend" - ",expire_legal" - ",coin_val" /* value of this denom */ - ",coin_frac" /* fractional value of this denom */ - ",coin_curr" /* assuming same currency for fees */ - ",fee_withdraw_val" - ",fee_withdraw_frac" - ",fee_withdraw_curr" /* must match coin_curr */ - ",fee_deposit_val" - ",fee_deposit_frac" - ",fee_deposit_curr" /* must match coin_curr */ - ",fee_refresh_val" - ",fee_refresh_frac" - ",fee_refresh_curr" /* must match coin_curr */ - " FROM denominations" - " WHERE pub=$1;", - 1, NULL); - - /* Used in #postgres_reserve_get() */ - PREPARE ("reserve_get", - "SELECT" - " current_balance_val" - ",current_balance_frac" - ",current_balance_curr" - ",expiration_date" - " FROM reserves" - " WHERE reserve_pub=$1" - " LIMIT 1;", - 1, NULL); - - /* Used in #postgres_reserves_in_insert() when the reserve is new */ - PREPARE ("reserve_create", - "INSERT INTO reserves " - "(reserve_pub" - ",current_balance_val" - ",current_balance_frac" - ",current_balance_curr" - ",expiration_date" - ") VALUES " - "($1, $2, $3, $4, $5);", - 5, NULL); - - /* Used in #postgres_reserves_update() when the reserve is updated */ - PREPARE ("reserve_update", - "UPDATE reserves" - " SET" - " expiration_date=$1 " - ",current_balance_val=$2 " - ",current_balance_frac=$3 " - "WHERE current_balance_curr=$4 AND reserve_pub=$5", - 5, NULL); - - /* Used in #postgres_reserves_in_insert() to store transaction details */ - PREPARE ("reserves_in_add_transaction", - "INSERT INTO reserves_in " - "(reserve_pub" - ",balance_val" - ",balance_frac" - ",balance_curr" - ",details" - ",execution_date" - ") VALUES " - "($1, $2, $3, $4, $5, $6);", - 6, NULL); - - /* Used in #postgres_get_reserve_history() to obtain inbound transactions - for a reserve */ - PREPARE ("reserves_in_get_transactions", - "SELECT" - " balance_val" - ",balance_frac" - ",balance_curr" - ",execution_date" - ",details" - " FROM reserves_in" - " WHERE reserve_pub=$1", - 1, NULL); - - /* Used in #postgres_insert_withdraw_info() to store - the signature of a blinded coin with the blinded coin's - details before returning it during /reserve/withdraw. We store - the coin's denomination information (public key, signature) - and the blinded message as well as the reserve that the coin - is being withdrawn from and the signature of the message - authorizing the withdrawal. */ - PREPARE ("insert_withdraw_info", - "INSERT INTO reserves_out " - "(h_blind_ev" - ",denom_pub" - ",denom_sig" - ",reserve_pub" - ",reserve_sig" - ",execution_date" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",withdraw_fee_val" - ",withdraw_fee_frac" - ",withdraw_fee_curr" - ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);", - 12, NULL); - - /* Used in #postgres_get_withdraw_info() to - locate the response for a /reserve/withdraw request - using the hash of the blinded message. Used to - make sure /reserve/withdraw requests are idempotent. */ - PREPARE ("get_withdraw_info", - "SELECT" - " denom_pub" - ",denom_sig" - ",reserve_sig" - ",reserve_pub" - ",execution_date" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",withdraw_fee_val" - ",withdraw_fee_frac" - ",withdraw_fee_curr" - " FROM reserves_out" - " WHERE h_blind_ev=$1", - 1, NULL); - - /* Used during #postgres_get_reserve_history() to - obtain all of the /reserve/withdraw operations that - have been performed on a given reserve. (i.e. to - demonstrate double-spending) */ - PREPARE ("get_reserves_out", - "SELECT" - " h_blind_ev" - ",denom_pub" - ",denom_sig" - ",reserve_sig" - ",execution_date" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",withdraw_fee_val" - ",withdraw_fee_frac" - ",withdraw_fee_curr" - " FROM reserves_out" - " WHERE reserve_pub=$1;", - 1, NULL); - - /* Used in #postgres_get_refresh_session() to fetch - high-level information about a refresh session */ - PREPARE ("get_refresh_session", - "SELECT" - " num_oldcoins" - ",num_newcoins" - ",noreveal_index" - " FROM refresh_sessions " - " WHERE session_hash=$1 ", - 1, NULL); - - /* Used in #postgres_create_refresh_session() to store - high-level information about a refresh session */ - PREPARE ("insert_refresh_session", - "INSERT INTO refresh_sessions " - "(session_hash " - ",num_oldcoins " - ",num_newcoins " - ",noreveal_index " - ") VALUES " - "($1, $2, $3, $4);", - 4, NULL); - - /* Used in #postgres_get_known_coin() to fetch - the denomination public key and signature for - a coin known to the mint. */ - PREPARE ("get_known_coin", - "SELECT" - " denom_pub" - ",denom_sig" - " FROM known_coins" - " WHERE coin_pub=$1", - 1, NULL); - - /* Used in #postgres_insert_known_coin() to store - the denomination public key and signature for - a coin known to the mint. */ - PREPARE ("insert_known_coin", - "INSERT INTO known_coins " - "(coin_pub" - ",denom_pub" - ",denom_sig" - ") VALUES " - "($1,$2,$3);", - 3, NULL); - - /* Store information about the desired denominations for a - refresh operation, used in #postgres_insert_refresh_order() */ - PREPARE ("insert_refresh_order", - "INSERT INTO refresh_order " - "(newcoin_index " - ",session_hash " - ",denom_pub " - ") VALUES " - "($1, $2, $3);", - 3, NULL); - - /* Obtain information about the desired denominations for a - refresh operation, used in #postgres_get_refresh_order() */ - PREPARE ("get_refresh_order", - "SELECT denom_pub" - " FROM refresh_order" - " WHERE session_hash=$1 AND newcoin_index=$2", - 2, NULL); - - /* Used in #postgres_insert_refresh_melt to store information - about melted coins */ - PREPARE ("insert_refresh_melt", - "INSERT INTO refresh_melts " - "(coin_pub " - ",session_hash" - ",oldcoin_index " - ",coin_sig " - ",amount_with_fee_val " - ",amount_with_fee_frac " - ",amount_with_fee_curr " - ",melt_fee_val " - ",melt_fee_frac " - ",melt_fee_curr " - ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);", - 10, NULL); - - /* Used in #postgres_get_refresh_melt to obtain information - about melted coins */ - PREPARE ("get_refresh_melt", - "SELECT" - " coin_pub" - ",coin_sig" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",melt_fee_val " - ",melt_fee_frac " - ",melt_fee_curr " - " FROM refresh_melts" - " WHERE session_hash=$1 AND oldcoin_index=$2", - 2, NULL); - - /* Query the 'refresh_melts' by coin public key */ - PREPARE ("get_refresh_melt_by_coin", - "SELECT" - " session_hash" - /* ",oldcoin_index" // not needed */ - ",coin_sig" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",melt_fee_val " - ",melt_fee_frac " - ",melt_fee_curr " - " FROM refresh_melts" - " WHERE coin_pub=$1", - 1, NULL); - - /* Used in #postgres_insert_refresh_commit_links() to - store commitments */ - PREPARE ("insert_refresh_commit_link", - "INSERT INTO refresh_commit_link " - "(session_hash" - ",transfer_pub" - ",cnc_index" - ",oldcoin_index" - ",link_secret_enc" - ") VALUES " - "($1, $2, $3, $4, $5);", - 5, NULL); - - /* Used in #postgres_get_refresh_commit_links() to - retrieve original commitments during /refresh/reveal */ - PREPARE ("get_refresh_commit_link", - "SELECT" - " transfer_pub" - ",link_secret_enc" - " FROM refresh_commit_link" - " WHERE session_hash=$1 AND cnc_index=$2 AND oldcoin_index=$3", - 3, NULL); - - /* Used in #postgres_insert_refresh_commit_coins() to - store coin commitments. */ - PREPARE ("insert_refresh_commit_coin", - "INSERT INTO refresh_commit_coin " - "(session_hash" - ",cnc_index" - ",newcoin_index" - ",link_vector_enc" - ",coin_ev" - ") VALUES " - "($1, $2, $3, $4, $5);", - 5, NULL); - - /* Used in #postgres_get_refresh_commit_coins() to - retrieve the original coin envelopes, to either be - verified or signed. */ - PREPARE ("get_refresh_commit_coin", - "SELECT" - " link_vector_enc" - ",coin_ev" - " FROM refresh_commit_coin" - " WHERE session_hash=$1 AND cnc_index=$2 AND newcoin_index=$3", - 3, NULL); - - /* Store information about a /deposit the mint is to execute. - Used in #postgres_insert_deposit(). */ - PREPARE ("insert_deposit", - "INSERT INTO deposits " - "(coin_pub" - ",denom_pub" - ",denom_sig" - ",transaction_id" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",deposit_fee_val" - ",deposit_fee_frac" - ",deposit_fee_curr" - ",timestamp" - ",refund_deadline" - ",wire_deadline" - ",merchant_pub" - ",h_contract" - ",h_wire" - ",coin_sig" - ",wire" - ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," - " $11, $12, $13, $14, $15, $16, $17, $18);", - 18, NULL); - - /* Fetch an existing deposit request, used to ensure idempotency - during /deposit processing. Used in #postgres_have_deposit(). */ - PREPARE ("get_deposit", - "SELECT" - " amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",timestamp" - ",refund_deadline" - ",wire_deadline" - ",h_contract" - ",h_wire" - " FROM deposits" - " WHERE (" - " (coin_pub=$1) AND" - " (transaction_id=$2) AND" - " (merchant_pub=$3)" - " )", - 3, NULL); - - /* Fetch an existing deposit request. - Used in #postgres_wire_lookup_deposit_wtid(). */ - PREPARE ("get_deposit_for_wtid", - "SELECT" - " amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",deposit_fee_val" - ",deposit_fee_frac" - ",deposit_fee_curr" - ",wire_deadline" - " FROM deposits" - " WHERE (" - " (coin_pub=$1) AND" - " (transaction_id=$2) AND" - " (merchant_pub=$3) AND" - " (h_contract=$4) AND" - " (h_wire=$5)" - " )", - 5, NULL); - - /* Used in #postgres_get_ready_deposit() */ - PREPARE ("deposits_get_ready", - "SELECT" - " serial_id" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",deposit_fee_val" - ",deposit_fee_frac" - ",deposit_fee_curr" - ",wire_deadline" - ",transaction_id" - ",h_contract" - ",wire" - ",merchant_pub" - ",coin_pub" - " FROM deposits" - " WHERE" - " tiny=false AND" - " done=false" - " ORDER BY wire_deadline ASC" - " LIMIT 1;", - 0, NULL); - - /* Used in #postgres_iterate_matching_deposits() */ - PREPARE ("deposits_iterate_matching", - "SELECT" - " serial_id" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",deposit_fee_val" - ",deposit_fee_frac" - ",deposit_fee_curr" - ",wire_deadline" - ",transaction_id" - ",h_contract" - ",coin_pub" - " FROM deposits" - " WHERE" - " merchant_pub=$1 AND" - " h_wire=$2 AND" - " done=false" - " ORDER BY wire_deadline ASC" - " LIMIT $3", - 3, NULL); - - /* Used in #postgres_mark_deposit_tiny() */ - PREPARE ("mark_deposit_tiny", - "UPDATE deposits" - " SET tiny=true" - " WHERE serial_id=$1", - 1, NULL); - - /* Used in #postgres_mark_deposit_done() */ - PREPARE ("mark_deposit_done", - "UPDATE deposits" - " SET done=true" - " WHERE serial_id=$1", - 1, NULL); - - /* Used in #postgres_get_coin_transactions() to obtain information - about how a coin has been spend with /deposit requests. */ - PREPARE ("get_deposit_with_coin_pub", - "SELECT" - " denom_pub" - ",denom_sig" - ",transaction_id" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",deposit_fee_val" - ",deposit_fee_frac" - ",deposit_fee_curr" - ",timestamp" - ",refund_deadline" - ",merchant_pub" - ",h_contract" - ",h_wire" - ",wire" - ",coin_sig" - " FROM deposits" - " WHERE coin_pub=$1", - 1, NULL); - - /* Used in #postgres_insert_refresh_out() to store the - generated signature(s) for future requests, i.e. /refresh/link */ - PREPARE ("insert_refresh_out", - "INSERT INTO refresh_out " - "(session_hash" - ",newcoin_index" - ",ev_sig" - ") VALUES " - "($1, $2, $3)", - 3, NULL); - - /* Used in #postgres_get_link_data_list(). We use the session_hash - to obtain the "noreveal_index" for that session, and then select - the encrypted link vectors (link_vector_enc) and the - corresponding signatures (ev_sig) and the denomination keys from - the respective tables (namely refresh_melts and refresh_order) - using the session_hash as the primary filter (on join) and the - 'noreveal_index' to constrain the selection on the commitment. - We also want to get the triplet for each of the newcoins, so we - have another constraint to ensure we get each triplet with - matching "newcoin_index" values. NOTE: This may return many - results, both for different sessions and for the different coins - being minted in the refresh ops. NOTE: There may be more - efficient ways to express the same query. */ - PREPARE ("get_link", - "SELECT link_vector_enc,ev_sig,ro.denom_pub" - " FROM refresh_melts rm " - " JOIN refresh_order ro USING (session_hash)" - " JOIN refresh_commit_coin rcc USING (session_hash)" - " JOIN refresh_sessions rs USING (session_hash)" - " JOIN refresh_out rc USING (session_hash)" - " WHERE ro.session_hash=$1" - " AND ro.newcoin_index=rcc.newcoin_index" - " AND ro.newcoin_index=rc.newcoin_index" - " AND rcc.cnc_index=rs.noreveal_index", - 1, NULL); - - /* Used in #postgres_get_transfer(). Given the public key of a - melted coin, we obtain the corresponding encrypted link secret - and the transfer public key. This is done by first finding - the session_hash(es) of all sessions the coin was melted into, - and then constraining the result to the selected "noreveal_index" - and the transfer public key to the corresponding index of the - old coin. - NOTE: This may (in theory) return multiple results, one per session - that the old coin was melted into. */ - PREPARE ("get_transfer", - "SELECT transfer_pub,link_secret_enc,session_hash" - " FROM refresh_melts rm" - " JOIN refresh_commit_link rcl USING (session_hash)" - " JOIN refresh_sessions rs USING (session_hash)" - " WHERE rm.coin_pub=$1" - " AND rm.oldcoin_index = rcl.oldcoin_index" - " AND rcl.cnc_index=rs.noreveal_index", - 1, NULL); - - /* Used in #postgres_lookup_wire_transfer */ - PREPARE ("lookup_transactions", - "SELECT" - " h_contract" - ",h_wire" - ",coin_pub" - ",merchant_pub" - ",transaction_id" - ",execution_time" - ",coin_amount_val" - ",coin_amount_frac" - ",coin_amount_curr" - ",coin_fee_val" - ",coin_fee_frac" - ",coin_fee_curr" - " FROM aggregation_tracking" - " WHERE wtid_raw=$1", - 1, NULL); - - /* Used in #postgres_wire_lookup_deposit_wtid */ - PREPARE ("lookup_deposit_wtid", - "SELECT" - " wtid_raw" - ",execution_time" - ",coin_amount_val" - ",coin_amount_frac" - ",coin_amount_curr" - ",coin_fee_val" - ",coin_fee_frac" - ",coin_fee_curr" - " FROM aggregation_tracking" - " WHERE" - " coin_pub=$1 AND" - " h_contract=$2 AND" - " h_wire=$3 AND" - " transaction_id=$4 AND" - " merchant_pub=$5", - 5, NULL); - - /* Used in #postgres_insert_aggregation_tracking */ - PREPARE ("insert_aggregation_tracking", - "INSERT INTO aggregation_tracking " - "(h_contract" - ",h_wire" - ",coin_pub" - ",merchant_pub" - ",transaction_id" - ",wtid_raw" - ",execution_time" - ",coin_amount_val" - ",coin_amount_frac" - ",coin_amount_curr" - ",coin_fee_val" - ",coin_fee_frac" - ",coin_fee_curr" - ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)", - 13, NULL); - - - /* Used in #postgres_wire_prepare_data_insert() to store - wire transfer information before actually committing it with the bank */ - PREPARE ("wire_prepare_data_insert", - "INSERT INTO prewire " - "(type" - ",buf" - ") VALUES " - "($1, $2)", - 2, NULL); - - /* Used in #postgres_wire_prepare_data_mark_finished() */ - PREPARE ("wire_prepare_data_mark_done", - "UPDATE prewire" - " SET finished=true" - " WHERE serial_id=$1", - 1, NULL); - - /* Used in #postgres_wire_prepare_data_get() */ - PREPARE ("wire_prepare_data_get", - "SELECT" - " serial_id" - ",buf" - " FROM prewire" - " WHERE" - " type=$1 AND" - " finished=false" - " ORDER BY serial_id ASC" - " LIMIT 1", - 1, NULL); - - return GNUNET_OK; -#undef PREPARE -} - - -/** - * Close thread-local database connection when a thread is destroyed. - * - * @param cls closure we get from pthreads (the db handle) - */ -static void -db_conn_destroy (void *cls) -{ - struct TALER_MINTDB_Session *session = cls; - PGconn *db_conn = session->conn; - - if (NULL != db_conn) - PQfinish (db_conn); - GNUNET_free (session); -} - - -/** - * Get the thread-local database-handle. - * Connect to the db if the connection does not exist yet. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param temporary #GNUNET_YES to use a temporary schema; #GNUNET_NO to use the - * database default one - * @return the database connection, or NULL on error - */ -static struct TALER_MINTDB_Session * -postgres_get_session (void *cls, - int temporary) -{ - struct PostgresClosure *pc = cls; - PGconn *db_conn; - struct TALER_MINTDB_Session *session; - - if (NULL != (session = pthread_getspecific (pc->db_conn_threadlocal))) - return session; - db_conn = PQconnectdb (pc->connection_cfg_str); - if (CONNECTION_OK != - PQstatus (db_conn)) - { - TALER_LOG_ERROR ("Database connection failed: %s\n", - PQerrorMessage (db_conn)); - GNUNET_break (0); - return NULL; - } - PQsetNoticeReceiver (db_conn, - &pq_notice_receiver_cb, - NULL); - PQsetNoticeProcessor (db_conn, - &pq_notice_processor_cb, - NULL); - if ( (GNUNET_YES == temporary) && - (GNUNET_SYSERR == set_temporary_schema(db_conn)) ) - { - GNUNET_break (0); - return NULL; - } - if (GNUNET_OK != - postgres_prepare (db_conn)) - { - GNUNET_break (0); - return NULL; - } - session = GNUNET_new (struct TALER_MINTDB_Session); - session->conn = db_conn; - if (0 != pthread_setspecific (pc->db_conn_threadlocal, - session)) - { - GNUNET_break (0); - PQfinish (db_conn); - GNUNET_free (session); - return NULL; - } - return session; -} - - -/** - * Start a transaction. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session the database connection - * @return #GNUNET_OK on success - */ -static int -postgres_start (void *cls, - struct TALER_MINTDB_Session *session) -{ - PGresult *result; - - result = PQexec (session->conn, - "BEGIN"); - if (PGRES_COMMAND_OK != - PQresultStatus (result)) - { - TALER_LOG_ERROR ("Failed to start transaction: %s\n", - PQresultErrorMessage (result)); - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - - PQclear (result); - return GNUNET_OK; -} - - -/** - * Roll back the current transaction of a database connection. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session the database connection - * @return #GNUNET_OK on success - */ -static void -postgres_rollback (void *cls, - struct TALER_MINTDB_Session *session) -{ - PGresult *result; - - result = PQexec (session->conn, - "ROLLBACK"); - GNUNET_break (PGRES_COMMAND_OK == - PQresultStatus (result)); - PQclear (result); -} - - -/** - * Commit the current transaction of a database connection. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session the database connection - * @return #GNUNET_OK on success - */ -static int -postgres_commit (void *cls, - struct TALER_MINTDB_Session *session) -{ - PGresult *result; - - result = PQexec (session->conn, - "COMMIT"); - if (PGRES_COMMAND_OK != - PQresultStatus (result)) - { - const char *sqlstate; - - sqlstate = PQresultErrorField (result, - PG_DIAG_SQLSTATE); - if (NULL == sqlstate) - { - /* very unexpected... */ - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - /* 40P01: deadlock, 40001: serialization failure */ - if ( (0 == strcmp (sqlstate, - "40P01")) || - (0 == strcmp (sqlstate, - "40001")) ) - { - /* These two can be retried and have a fair chance of working - the next time */ - PQclear (result); - return GNUNET_NO; - } - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Database commit failure: %s\n", - sqlstate); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Insert a denomination key's public information into the database for - * reference by auditors and other consistency checks. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to use - * @param denom_pub the public key used for signing coins of this denomination - * @param issue issuing information with value, fees and other info about the coin - * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure - */ -static int -postgres_insert_denomination_info (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_DenominationPublicKey *denom_pub, - const struct TALER_MINTDB_DenominationKeyInformationP *issue) -{ - PGresult *result; - int ret; - - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_rsa_public_key (denom_pub->rsa_public_key), - GNUNET_PQ_query_param_auto_from_type (&issue->properties.master), - GNUNET_PQ_query_param_auto_from_type (&issue->signature), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.start), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_withdraw), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_spend), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_legal), - TALER_PQ_query_param_amount_nbo (&issue->properties.value), - TALER_PQ_query_param_amount_nbo (&issue->properties.fee_withdraw), - TALER_PQ_query_param_amount_nbo (&issue->properties.fee_deposit), - TALER_PQ_query_param_amount_nbo (&issue->properties.fee_refresh), - GNUNET_PQ_query_param_end - }; - /* check fees match coin currency */ - GNUNET_assert (GNUNET_YES == - TALER_amount_cmp_currency_nbo (&issue->properties.value, - &issue->properties.fee_withdraw)); - GNUNET_assert (GNUNET_YES == - TALER_amount_cmp_currency_nbo (&issue->properties.value, - &issue->properties.fee_deposit)); - GNUNET_assert (GNUNET_YES == - TALER_amount_cmp_currency_nbo (&issue->properties.value, - &issue->properties.fee_refresh)); - - result = GNUNET_PQ_exec_prepared (session->conn, - "denomination_insert", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - ret = GNUNET_SYSERR; - BREAK_DB_ERR (result); - } - else - { - ret = GNUNET_OK; - } - PQclear (result); - return ret; -} - - -/** - * Fetch information about a denomination key. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to use - * @param denom_pub the public key used for signing coins of this denomination - * @param[out] issue set to issue information with value, fees and other info about the coin, can be NULL - * @return #GNUNET_OK on success; #GNUNET_NO if no record was found, #GNUNET_SYSERR on failure - */ -static int -postgres_get_denomination_info (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_DenominationPublicKey *denom_pub, - struct TALER_MINTDB_DenominationKeyInformationP *issue) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_rsa_public_key (denom_pub->rsa_public_key), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "denomination_get", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - QUERY_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 == PQntuples (result)) - { - PQclear (result); - return GNUNET_NO; - } - if (1 != PQntuples (result)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - if (NULL == issue) - { - PQclear (result); - return GNUNET_OK; - } - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("master_pub", - &issue->properties.master), - GNUNET_PQ_result_spec_auto_from_type ("master_sig", - &issue->signature), - GNUNET_PQ_result_spec_absolute_time_nbo ("valid_from", - &issue->properties.start), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_withdraw", - &issue->properties.expire_withdraw), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_spend", - &issue->properties.expire_spend), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_legal", - &issue->properties.expire_legal), - TALER_PQ_result_spec_amount_nbo ("coin", - &issue->properties.value), - TALER_PQ_result_spec_amount_nbo ("fee_withdraw", - &issue->properties.fee_withdraw), - TALER_PQ_result_spec_amount_nbo ("fee_deposit", - &issue->properties.fee_deposit), - TALER_PQ_result_spec_amount_nbo ("fee_refresh", - &issue->properties.fee_refresh), - GNUNET_PQ_result_spec_end - }; - - EXITIF (GNUNET_OK != - GNUNET_PQ_extract_result (result, - rs, - 0)); - } - PQclear (result); - return GNUNET_OK; - - EXITIF_exit: - PQclear (result); - return GNUNET_SYSERR; -} - - -/** - * Get the summary of a reserve. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session the database connection handle - * @param[in,out] reserve the reserve data. The public key of the reserve should be - * set in this structure; it is used to query the database. The balance - * and expiration are then filled accordingly. - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure - */ -static int -postgres_reserve_get (void *cls, - struct TALER_MINTDB_Session *session, - struct TALER_MINTDB_Reserve *reserve) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type(&reserve->pub), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "reserve_get", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - QUERY_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 == PQntuples (result)) - { - PQclear (result); - return GNUNET_NO; - } - { - struct GNUNET_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_amount("current_balance", &reserve->balance), - GNUNET_PQ_result_spec_absolute_time("expiration_date", &reserve->expiry), - GNUNET_PQ_result_spec_end - }; - - EXITIF (GNUNET_OK != - GNUNET_PQ_extract_result (result, - rs, - 0)); - } - PQclear (result); - return GNUNET_OK; - - EXITIF_exit: - PQclear (result); - return GNUNET_SYSERR; -} - - -/** - * Updates a reserve with the data from the given reserve structure. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session the database connection - * @param reserve the reserve structure whose data will be used to update the - * corresponding record in the database. - * @return #GNUNET_OK upon successful update; #GNUNET_SYSERR upon any error - */ -static int -reserves_update (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_MINTDB_Reserve *reserve) -{ - PGresult *result; - int ret; - - if (NULL == reserve) - return GNUNET_SYSERR; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_absolute_time (&reserve->expiry), - TALER_PQ_query_param_amount (&reserve->balance), - GNUNET_PQ_query_param_auto_from_type (&reserve->pub), - GNUNET_PQ_query_param_end - }; - result = GNUNET_PQ_exec_prepared (session->conn, - "reserve_update", - params); - if (PGRES_COMMAND_OK != PQresultStatus(result)) - { - QUERY_ERR (result); - ret = GNUNET_SYSERR; - } - else - { - ret = GNUNET_OK; - } - PQclear (result); - return ret; -} - - -/** - * Insert an incoming transaction into reserves. New reserves are also created - * through this function. Note that this API call starts (and stops) its - * own transaction scope (so the application must not do so). - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session the database connection handle - * @param reserve_pub public key of the reserve - * @param balance the amount that has to be added to the reserve - * @param execution_time when was the amount added - * @param details bank transaction details justifying the increment, - * must be unique for each incoming transaction - * @return #GNUNET_OK upon success; #GNUNET_NO if the given - * @a details are already known for this @a reserve_pub, - * #GNUNET_SYSERR upon failures (DB error, incompatible currency) - */ -static int -postgres_reserves_in_insert (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_Amount *balance, - struct GNUNET_TIME_Absolute execution_time, - const json_t *details) -{ - PGresult *result; - int reserve_exists; - struct TALER_MINTDB_Reserve reserve; - struct GNUNET_TIME_Absolute expiry; - - if (GNUNET_OK != postgres_start (cls, - session)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - reserve.pub = *reserve_pub; - reserve_exists = postgres_reserve_get (cls, - session, - &reserve); - if (GNUNET_SYSERR == reserve_exists) - { - GNUNET_break (0); - goto rollback; - } - expiry = GNUNET_TIME_absolute_add (execution_time, - TALER_IDLE_RESERVE_EXPIRATION_TIME); - if (GNUNET_NO == reserve_exists) - { - /* New reserve, create balance for the first time; we do this - before adding the actual transaction to "reserves_in", as - for a new reserve it can't be a duplicate 'add' operation, - and as the 'add' operation may need the reserve entry - as a foreign key. */ - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (reserve_pub), - TALER_PQ_query_param_amount (balance), - GNUNET_PQ_query_param_absolute_time (&expiry), - GNUNET_PQ_query_param_end - }; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Reserve does not exist; creating a new one\n"); - result = GNUNET_PQ_exec_prepared (session->conn, - "reserve_create", - params); - if (PGRES_COMMAND_OK != PQresultStatus(result)) - { - QUERY_ERR (result); - PQclear (result); - goto rollback; - } - PQclear (result); - } - /* Create new incoming transaction, SQL "primary key" logic - is used to guard against duplicates. If a duplicate is - detected, we rollback (which really shouldn't undo - anything) and return #GNUNET_NO to indicate that this failure - is kind-of harmless (already executed). */ - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&reserve.pub), - TALER_PQ_query_param_amount (balance), - TALER_PQ_query_param_json (details), - GNUNET_PQ_query_param_absolute_time (&execution_time), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "reserves_in_add_transaction", - params); - } - if (PGRES_COMMAND_OK != PQresultStatus(result)) - { - const char *efield; - - efield = PQresultErrorField (result, - PG_DIAG_SQLSTATE); - if ( (PGRES_FATAL_ERROR == PQresultStatus(result)) && - (NULL != strstr ("23505", /* unique violation */ - efield)) ) - { - /* This means we had the same reserve/justification/details - before */ - PQclear (result); - postgres_rollback (cls, - session); - return GNUNET_NO; - } - QUERY_ERR (result); - PQclear (result); - goto rollback; - } - PQclear (result); - - if (GNUNET_YES == reserve_exists) - { - /* If the reserve already existed, we need to still update the - balance; we do this after checking for duplication, as - otherwise we might have to actually pay the cost to roll this - back for duplicate transactions; like this, we should virtually - never actually have to rollback anything. */ - struct TALER_MINTDB_Reserve updated_reserve; - - updated_reserve.pub = reserve.pub; - if (GNUNET_OK != - TALER_amount_add (&updated_reserve.balance, - &reserve.balance, - balance)) - { - /* currency overflow or incompatible currency */ - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Attempt to deposit incompatible amount into reserve\n"); - goto rollback; - } - updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry, - reserve.expiry); - if (GNUNET_OK != reserves_update (cls, - session, - &updated_reserve)) - goto rollback; - } - if (GNUNET_OK != postgres_commit (cls, - session)) - return GNUNET_SYSERR; - return GNUNET_OK; - - rollback: - postgres_rollback (cls, - session); - return GNUNET_SYSERR; -} - - -/** - * Locate the response for a /reserve/withdraw request under the - * key of the hash of the blinded message. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection to use - * @param h_blind hash of the blinded coin to be signed (will match - * `h_coin_envelope` in the @a collectable to be returned) - * @param collectable corresponding collectable coin (blind signature) - * if a coin is found - * @return #GNUNET_SYSERR on internal error - * #GNUNET_NO if the collectable was not found - * #GNUNET_YES on success - */ -static int -postgres_get_withdraw_info (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *h_blind, - struct TALER_MINTDB_CollectableBlindcoin *collectable) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (h_blind), - GNUNET_PQ_query_param_end - }; - int ret; - - ret = GNUNET_SYSERR; - result = GNUNET_PQ_exec_prepared (session->conn, - "get_withdraw_info", - params); - - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - QUERY_ERR (result); - goto cleanup; - } - if (0 == PQntuples (result)) - { - ret = GNUNET_NO; - goto cleanup; - } - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &collectable->denom_pub.rsa_public_key), - GNUNET_PQ_result_spec_rsa_signature ("denom_sig", - &collectable->sig.rsa_signature), - GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", - &collectable->reserve_sig), - GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", - &collectable->reserve_pub), - TALER_PQ_result_spec_amount ("amount_with_fee", - &collectable->amount_with_fee), - TALER_PQ_result_spec_amount ("withdraw_fee", - &collectable->withdraw_fee), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - goto cleanup; - } - } - collectable->h_coin_envelope = *h_blind; - ret = GNUNET_YES; - - cleanup: - PQclear (result); - return ret; -} - - -/** - * Store collectable bit coin under the corresponding - * hash of the blinded message. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection to use - * @param collectable corresponding collectable coin (blind signature) - * if a coin is found - * @return #GNUNET_SYSERR on internal error - * #GNUNET_NO if the collectable was not found - * #GNUNET_YES on success - */ -static int -postgres_insert_withdraw_info (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_MINTDB_CollectableBlindcoin *collectable) -{ - PGresult *result; - struct TALER_MINTDB_Reserve reserve; - int ret = GNUNET_SYSERR; - struct GNUNET_TIME_Absolute now; - struct GNUNET_TIME_Absolute expiry; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&collectable->h_coin_envelope), - GNUNET_PQ_query_param_rsa_public_key (collectable->denom_pub.rsa_public_key), - GNUNET_PQ_query_param_rsa_signature (collectable->sig.rsa_signature), - GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_pub), - GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig), - GNUNET_PQ_query_param_absolute_time (&now), - TALER_PQ_query_param_amount (&collectable->amount_with_fee), - TALER_PQ_query_param_amount (&collectable->withdraw_fee), - GNUNET_PQ_query_param_end - }; - - now = GNUNET_TIME_absolute_get (); - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_withdraw_info", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - QUERY_ERR (result); - goto cleanup; - } - reserve.pub = collectable->reserve_pub; - if (GNUNET_OK != postgres_reserve_get (cls, - session, - &reserve)) - { - /* Should have been checked before we got here... */ - GNUNET_break (0); - goto cleanup; - } - if (GNUNET_SYSERR == - TALER_amount_subtract (&reserve.balance, - &reserve.balance, - &collectable->amount_with_fee)) - { - /* Should have been checked before we got here... */ - GNUNET_break (0); - goto cleanup; - } - expiry = GNUNET_TIME_absolute_add (now, - TALER_IDLE_RESERVE_EXPIRATION_TIME); - reserve.expiry = GNUNET_TIME_absolute_max (expiry, - reserve.expiry); - if (GNUNET_OK != reserves_update (cls, - session, - &reserve)) - { - GNUNET_break (0); - goto cleanup; - } - ret = GNUNET_OK; - cleanup: - PQclear (result); - return ret; -} - - -/** - * Get all of the transaction history associated with the specified - * reserve. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session connection to use - * @param reserve_pub public key of the reserve - * @return known transaction history (NULL if reserve is unknown) - */ -static struct TALER_MINTDB_ReserveHistory * -postgres_get_reserve_history (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_ReservePublicKeyP *reserve_pub) -{ - PGresult *result; - struct TALER_MINTDB_ReserveHistory *rh; - struct TALER_MINTDB_ReserveHistory *rh_tail; - int rows; - int ret; - - rh = NULL; - rh_tail = NULL; - ret = GNUNET_SYSERR; - { - struct TALER_MINTDB_BankTransfer *bt; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (reserve_pub), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "reserves_in_get_transactions", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - QUERY_ERR (result); - goto cleanup; - } - if (0 == (rows = PQntuples (result))) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Asked to fetch history for an unknown reserve.\n"); - goto cleanup; - } - while (0 < rows) - { - bt = GNUNET_new (struct TALER_MINTDB_BankTransfer); - { - struct GNUNET_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_amount ("balance", - &bt->amount), - GNUNET_PQ_result_spec_absolute_time ("execution_date", - &bt->execution_date), - TALER_PQ_result_spec_json ("details", - &bt->wire), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_YES != - GNUNET_PQ_extract_result (result, rs, --rows)) - { - GNUNET_break (0); - GNUNET_free (bt); - PQclear (result); - goto cleanup; - } - } - bt->reserve_pub = *reserve_pub; - if (NULL != rh_tail) - { - rh_tail->next = GNUNET_new (struct TALER_MINTDB_ReserveHistory); - rh_tail = rh_tail->next; - } - else - { - rh_tail = GNUNET_new (struct TALER_MINTDB_ReserveHistory); - rh = rh_tail; - } - rh_tail->type = TALER_MINTDB_RO_BANK_TO_MINT; - rh_tail->details.bank = bt; - } - PQclear (result); - } - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (reserve_pub), - GNUNET_PQ_query_param_end - }; - - GNUNET_assert (NULL != rh); - GNUNET_assert (NULL != rh_tail); - GNUNET_assert (NULL == rh_tail->next); - result = GNUNET_PQ_exec_prepared (session->conn, - "get_reserves_out", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - QUERY_ERR (result); - PQclear (result); - goto cleanup; - } - rows = PQntuples (result); - while (0 < rows) - { - struct TALER_MINTDB_CollectableBlindcoin *cbc; - - cbc = GNUNET_new (struct TALER_MINTDB_CollectableBlindcoin); - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev", - &cbc->h_coin_envelope), - GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &cbc->denom_pub.rsa_public_key), - GNUNET_PQ_result_spec_rsa_signature ("denom_sig", - &cbc->sig.rsa_signature), - GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", - &cbc->reserve_sig), - TALER_PQ_result_spec_amount ("amount_with_fee", - &cbc->amount_with_fee), - TALER_PQ_result_spec_amount ("withdraw_fee", - &cbc->withdraw_fee), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_YES != - GNUNET_PQ_extract_result (result, rs, --rows)) - { - GNUNET_break (0); - GNUNET_free (cbc); - PQclear (result); - goto cleanup; - } - cbc->reserve_pub = *reserve_pub; - } - rh_tail->next = GNUNET_new (struct TALER_MINTDB_ReserveHistory); - rh_tail = rh_tail->next; - rh_tail->type = TALER_MINTDB_RO_WITHDRAW_COIN; - rh_tail->details.withdraw = cbc; - } - ret = GNUNET_OK; - PQclear (result); - } - cleanup: - if (GNUNET_SYSERR == ret) - { - common_free_reserve_history (cls, - rh); - rh = NULL; - } - return rh; -} - - -/** - * Check if we have the specified deposit already in the database. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param deposit deposit to search for - * @return #GNUNET_YES if we know this operation, - * #GNUNET_NO if this exact deposit is unknown to us - * #GNUNET_SYSERR on DB error - */ -static int -postgres_have_deposit (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_MINTDB_Deposit *deposit) -{ - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub), - GNUNET_PQ_query_param_uint64 (&deposit->transaction_id), - GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub), - GNUNET_PQ_query_param_end - }; - PGresult *result; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_deposit", - params); - if (PGRES_TUPLES_OK != - PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 == PQntuples (result)) - { - PQclear (result); - return GNUNET_NO; - } - - /* Now we check that the other information in @a deposit - also matches, and if not report inconsistencies. */ - { - struct TALER_MINTDB_Deposit deposit2; - struct GNUNET_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_amount ("amount_with_fee", - &deposit2.amount_with_fee), - GNUNET_PQ_result_spec_absolute_time ("timestamp", - &deposit2.timestamp), - GNUNET_PQ_result_spec_absolute_time ("refund_deadline", - &deposit2.refund_deadline), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", - &deposit2.wire_deadline), - GNUNET_PQ_result_spec_auto_from_type ("h_contract", - &deposit2.h_contract), - GNUNET_PQ_result_spec_auto_from_type ("h_wire", - &deposit2.h_wire), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - if ( (0 != TALER_amount_cmp (&deposit->amount_with_fee, - &deposit2.amount_with_fee)) || - (deposit->timestamp.abs_value_us != - deposit2.timestamp.abs_value_us) || - (deposit->refund_deadline.abs_value_us != - deposit2.refund_deadline.abs_value_us) || - (0 != memcmp (&deposit->h_contract, - &deposit2.h_contract, - sizeof (struct GNUNET_HashCode))) || - (0 != memcmp (&deposit->h_wire, - &deposit2.h_wire, - sizeof (struct GNUNET_HashCode))) ) - { - /* Inconsistencies detected! Does not match! (We might want to - expand the API with a 'get_deposit' function to return the - original transaction details to be used for an error message - in the future!) #3838 */ - PQclear (result); - return GNUNET_NO; - } - } - PQclear (result); - return GNUNET_YES; -} - - -/** - * Mark a deposit as tiny, thereby declaring that it cannot be - * executed by itself and should no longer be returned by - * @e iterate_ready_deposits() - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to the database - * @param deposit_rowid identifies the deposit row to modify - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -static int -postgres_mark_deposit_tiny (void *cls, - struct TALER_MINTDB_Session *session, - unsigned long long rowid) -{ - uint64_t serial_id = rowid; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&serial_id), - GNUNET_PQ_query_param_end - }; - PGresult *result; - - result = GNUNET_PQ_exec_prepared (session->conn, - "mark_deposit_tiny", - params); - if (PGRES_COMMAND_OK != - PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Mark a deposit as done, thereby declaring that it cannot be - * executed at all anymore, and should no longer be returned by - * @e iterate_ready_deposits() or @e iterate_matching_deposits(). - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to the database - * @param deposit_rowid identifies the deposit row to modify - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -static int -postgres_mark_deposit_done (void *cls, - struct TALER_MINTDB_Session *session, - unsigned long long rowid) -{ - uint64_t serial_id = rowid; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&serial_id), - GNUNET_PQ_query_param_end - }; - PGresult *result; - - result = GNUNET_PQ_exec_prepared (session->conn, - "mark_deposit_done", - params); - if (PGRES_COMMAND_OK != - PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Obtain information about deposits that are ready to be executed. - * Such deposits must not be marked as "tiny" or "done", and the - * execution time must be in the past. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to the database - * @param deposit_cb function to call for ONE such deposit - * @param deposit_cb_cls closure for @a deposit_cb - * @return number of rows processed, 0 if none exist, - * #GNUNET_SYSERR on error - */ -static int -postgres_get_ready_deposit (void *cls, - struct TALER_MINTDB_Session *session, - TALER_MINTDB_DepositIterator deposit_cb, - void *deposit_cb_cls) -{ - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_end - }; - PGresult *result; - unsigned int n; - int ret; - - result = GNUNET_PQ_exec_prepared (session->conn, - "deposits_get_ready", - params); - if (PGRES_TUPLES_OK != - PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 == (n = PQntuples (result))) - { - PQclear (result); - return 0; - } - GNUNET_break (1 == n); - { - struct TALER_Amount amount_with_fee; - struct TALER_Amount deposit_fee; - struct GNUNET_TIME_Absolute wire_deadline; - struct GNUNET_HashCode h_contract; - struct TALER_MerchantPublicKeyP merchant_pub; - struct TALER_CoinSpendPublicKeyP coin_pub; - uint64_t transaction_id; - uint64_t serial_id; - json_t *wire; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("serial_id", - &serial_id), - GNUNET_PQ_result_spec_uint64 ("transaction_id", - &transaction_id), - TALER_PQ_result_spec_amount ("amount_with_fee", - &amount_with_fee), - TALER_PQ_result_spec_amount ("deposit_fee", - &deposit_fee), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", - &wire_deadline), - GNUNET_PQ_result_spec_auto_from_type ("h_contract", - &h_contract), - GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", - &merchant_pub), - GNUNET_PQ_result_spec_auto_from_type ("coin_pub", - &coin_pub), - TALER_PQ_result_spec_json ("wire", - &wire), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - ret = deposit_cb (deposit_cb_cls, - serial_id, - &merchant_pub, - &coin_pub, - &amount_with_fee, - &deposit_fee, - transaction_id, - &h_contract, - wire_deadline, - wire); - GNUNET_PQ_cleanup_result (rs); - PQclear (result); - } - return (GNUNET_OK == ret) ? 1 : 0; -} - - -/** - * Obtain information about other pending deposits for the same - * destination. Those deposits must not already be "done". - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to the database - * @param h_wire destination of the wire transfer - * @param merchant_pub public key of the merchant - * @param deposit_cb function to call for each deposit - * @param deposit_cb_cls closure for @a deposit_cb - * @param limit maximum number of matching deposits to return - * @return number of rows processed, 0 if none exist, - * #GNUNET_SYSERR on error - */ -static int -postgres_iterate_matching_deposits (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *h_wire, - const struct TALER_MerchantPublicKeyP *merchant_pub, - TALER_MINTDB_DepositIterator deposit_cb, - void *deposit_cb_cls, - uint32_t limit) -{ - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (merchant_pub), - GNUNET_PQ_query_param_auto_from_type (h_wire), - GNUNET_PQ_query_param_uint32 (&limit), - GNUNET_PQ_query_param_end - }; - PGresult *result; - unsigned int i; - unsigned int n; - - result = GNUNET_PQ_exec_prepared (session->conn, - "deposits_iterate_matching", - params); - if (PGRES_TUPLES_OK != - PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 == (n = PQntuples (result))) - { - PQclear (result); - return 0; - } - if (n > limit) - n = limit; - for (i=0;i<n;i++) - { - struct TALER_Amount amount_with_fee; - struct TALER_Amount deposit_fee; - struct GNUNET_TIME_Absolute wire_deadline; - struct GNUNET_HashCode h_contract; - struct TALER_MerchantPublicKeyP merchant_pub; - struct TALER_CoinSpendPublicKeyP coin_pub; - uint64_t transaction_id; - uint64_t serial_id; - int ret; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("serial_id", - &serial_id), - GNUNET_PQ_result_spec_uint64 ("transaction_id", - &transaction_id), - TALER_PQ_result_spec_amount ("amount_with_fee", - &amount_with_fee), - TALER_PQ_result_spec_amount ("deposit_fee", - &deposit_fee), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", - &wire_deadline), - GNUNET_PQ_result_spec_auto_from_type ("h_contract", - &h_contract), - GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", - &merchant_pub), - GNUNET_PQ_result_spec_auto_from_type ("coin_pub", - &coin_pub), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, i)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - ret = deposit_cb (deposit_cb_cls, - serial_id, - &merchant_pub, - &coin_pub, - &amount_with_fee, - &deposit_fee, - transaction_id, - &h_contract, - wire_deadline, - NULL); - GNUNET_PQ_cleanup_result (rs); - PQclear (result); - if (GNUNET_OK != ret) - break; - } - return i; -} - - -/** - * Insert information about deposited coin into the database. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session connection to the database - * @param deposit deposit information to store - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -static int -postgres_insert_deposit (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_MINTDB_Deposit *deposit) -{ - PGresult *result; - int ret; - - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub), - GNUNET_PQ_query_param_rsa_public_key (deposit->coin.denom_pub.rsa_public_key), - GNUNET_PQ_query_param_rsa_signature (deposit->coin.denom_sig.rsa_signature), - GNUNET_PQ_query_param_uint64 (&deposit->transaction_id), - TALER_PQ_query_param_amount (&deposit->amount_with_fee), - TALER_PQ_query_param_amount (&deposit->deposit_fee), - GNUNET_PQ_query_param_absolute_time (&deposit->timestamp), - GNUNET_PQ_query_param_absolute_time (&deposit->refund_deadline), - GNUNET_PQ_query_param_absolute_time (&deposit->wire_deadline), - GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub), - GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract), - GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire), - GNUNET_PQ_query_param_auto_from_type (&deposit->csig), - TALER_PQ_query_param_json (deposit->wire), - GNUNET_PQ_query_param_end - }; - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_deposit", - params); - } - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - ret = GNUNET_SYSERR; - } - else - { - ret = GNUNET_OK; - } - PQclear (result); - return ret; -} - - -/** - * Lookup refresh session data under the given @a session_hash. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database handle to use - * @param session_hash hash over the melt to use to locate the session - * @param[out] refresh_session where to store the result, can be NULL - * to just check if the session exists - * @return #GNUNET_YES on success, - * #GNUNET_NO if not found, - * #GNUNET_SYSERR on DB failure - */ -static int -postgres_get_refresh_session (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - struct TALER_MINTDB_RefreshSession *refresh_session) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_session", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 == PQntuples (result)) - { - PQclear (result); - return GNUNET_NO; - } - GNUNET_assert (1 == PQntuples (result)); - if (NULL == refresh_session) - { - /* We're done if the caller is only interested in whether the - * session exists or not */ - PQclear (result); - return GNUNET_YES; - } - memset (refresh_session, - 0, - sizeof (struct TALER_MINTDB_RefreshSession)); - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint16 ("num_oldcoins", - &refresh_session->num_oldcoins), - GNUNET_PQ_result_spec_uint16 ("num_newcoins", - &refresh_session->num_newcoins), - GNUNET_PQ_result_spec_uint16 ("noreveal_index", - &refresh_session->noreveal_index), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - } - PQclear (result); - return GNUNET_YES; -} - - -/** - * Store new refresh session data under the given @a session_hash. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database handle to use - * @param session_hash hash over the melt to use to locate the session - * @param refresh_session session data to store - * @return #GNUNET_YES on success, - * #GNUNET_SYSERR on DB failure - */ -static int -postgres_create_refresh_session (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - const struct TALER_MINTDB_RefreshSession *refresh_session) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&refresh_session->num_oldcoins), - GNUNET_PQ_query_param_uint16 (&refresh_session->num_newcoins), - GNUNET_PQ_query_param_uint16 (&refresh_session->noreveal_index), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_refresh_session", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Insert a coin we know of into the DB. The coin can then be referenced by - * tables for deposits, lock and refresh functionality. - * - * @param cls plugin closure - * @param session the shared database session - * @param coin_info the public coin info - * @return #GNUNET_SYSERR upon error; #GNUNET_OK upon success - */ -static int -insert_known_coin (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_CoinPublicInfo *coin_info) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&coin_info->coin_pub), - GNUNET_PQ_query_param_rsa_public_key (coin_info->denom_pub.rsa_public_key), - GNUNET_PQ_query_param_rsa_signature (coin_info->denom_sig.rsa_signature), - GNUNET_PQ_query_param_end - }; - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_known_coin", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Retrieve the record for a known coin. - * - * @param cls the plugin closure - * @param session the database session handle - * @param coin_pub the public key of the coin to search for - * @param coin_info place holder for the returned coin information object - * @return #GNUNET_SYSERR upon error; #GNUNET_NO if no coin is found; #GNUNET_OK - * if upon succesfullying retrieving the record data info @a - * coin_info - */ -static int -get_known_coin (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - struct TALER_CoinPublicInfo *coin_info) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (coin_pub), - GNUNET_PQ_query_param_end - }; - int nrows; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_known_coin", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - nrows = PQntuples (result); - if (0 == nrows) - { - PQclear (result); - return GNUNET_NO; - } - GNUNET_assert (1 == nrows); /* due to primary key */ - if (NULL == coin_info) - return GNUNET_YES; - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &coin_info->denom_pub.rsa_public_key), - GNUNET_PQ_result_spec_rsa_signature ("denom_sig", - &coin_info->denom_sig.rsa_signature), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, 0)) - { - PQclear (result); - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - PQclear (result); - coin_info->coin_pub = *coin_pub; - return GNUNET_OK; -} - - -/** - * Store the given /refresh/melt request in the database. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param oldcoin_index index of the coin to store - * @param melt melt operation details to store; includes - * the session hash of the melt - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on internal error - */ -static int -postgres_insert_refresh_melt (void *cls, - struct TALER_MINTDB_Session *session, - uint16_t oldcoin_index, - const struct TALER_MINTDB_RefreshMelt *melt) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&melt->coin.coin_pub), - GNUNET_PQ_query_param_auto_from_type (&melt->session_hash), - GNUNET_PQ_query_param_uint16 (&oldcoin_index), - GNUNET_PQ_query_param_auto_from_type (&melt->coin_sig), - TALER_PQ_query_param_amount (&melt->amount_with_fee), - TALER_PQ_query_param_amount (&melt->melt_fee), - GNUNET_PQ_query_param_end - }; - int ret; - - /* check if the coin is already known */ - ret = get_known_coin (cls, - session, - &melt->coin.coin_pub, - NULL); - if (GNUNET_SYSERR == ret) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (GNUNET_NO == ret) /* if not, insert it */ - { - ret = insert_known_coin (cls, - session, - &melt->coin); - if (ret == GNUNET_SYSERR) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - /* insert the melt */ - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_refresh_melt", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Get information about melted coin details from the database. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param session_hash session hash of the melt operation - * @param oldcoin_index index of the coin to retrieve - * @param melt melt data to fill in, can be NULL - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on internal error - */ -static int -postgres_get_refresh_melt (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t oldcoin_index, - struct TALER_MINTDB_RefreshMelt *melt) -{ - PGresult *result; - struct TALER_CoinPublicInfo coin; - struct TALER_CoinSpendSignatureP coin_sig; - struct TALER_Amount amount_with_fee; - struct TALER_Amount melt_fee; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&oldcoin_index), - GNUNET_PQ_query_param_end - }; - int nrows; - - /* check if the melt record exists and get it */ - result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_melt", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - nrows = PQntuples (result); - if (0 == nrows) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "get_refresh_melt() returned 0 matching rows\n"); - PQclear (result); - return GNUNET_NO; - } - GNUNET_assert (1 == nrows); /* due to primary key constraint */ - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("coin_pub", &coin.coin_pub), - GNUNET_PQ_result_spec_auto_from_type ("coin_sig", &coin_sig), - TALER_PQ_result_spec_amount ("amount_with_fee", &amount_with_fee), - TALER_PQ_result_spec_amount ("melt_fee", &melt_fee), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - } - /* fetch the coin info and denomination info */ - if (GNUNET_OK != get_known_coin (cls, - session, - &coin.coin_pub, - &coin)) - return GNUNET_SYSERR; - if (NULL == melt) - { - GNUNET_CRYPTO_rsa_signature_free (coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (coin.denom_pub.rsa_public_key); - return GNUNET_OK; - } - melt->coin = coin; - melt->coin_sig = coin_sig; - melt->session_hash = *session_hash; - melt->amount_with_fee = amount_with_fee; - melt->melt_fee = melt_fee; - return GNUNET_OK; -} - - -/** - * Store in the database which coin(s) we want to create - * in a given refresh operation. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param session_hash hash to identify refresh session - * @param num_newcoins number of coins to generate, size of the @a denom_pubs array - * @param denom_pubs array denominations of the coins to create - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on internal error - */ -static int -postgres_insert_refresh_order (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t num_newcoins, - const struct TALER_DenominationPublicKey *denom_pubs) -{ - unsigned int i; - - for (i=0;i<(unsigned int) num_newcoins;i++) - { - uint16_t newcoin_off = (uint16_t) i; - PGresult *result; - - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint16 (&newcoin_off), - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_rsa_public_key (denom_pubs[i].rsa_public_key), - GNUNET_PQ_query_param_end - }; - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_refresh_order", - params); - } - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 != strcmp ("1", PQcmdTuples (result))) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - PQclear (result); - } - return GNUNET_OK; -} - - -/** - * We allocated some @a denom_pubs information, but now need - * to abort. Free allocated memory. - * - * @param denom_pubs data to free (but not the array itself) - * @param denom_pubs_len length of @a denom_pubs array - */ -static void -free_dpk_result (struct TALER_DenominationPublicKey *denom_pubs, - unsigned int denom_pubs_len) -{ - unsigned int i; - - for (i=0;i<denom_pubs_len;i++) - { - GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[i].rsa_public_key); - denom_pubs[i].rsa_public_key = NULL; - } -} - - -/** - * Lookup in the database the coins that we want to - * create in the given refresh operation. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param session_hash hash to identify refresh session - * @param num_newcoins size of the array of the @a denom_pubs array - * @param denom_pubs where to store the deomination keys - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on internal error - */ -static int -postgres_get_refresh_order (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t num_newcoins, - struct TALER_DenominationPublicKey *denom_pubs) -{ - unsigned int i; - - for (i=0;i<(unsigned int) num_newcoins;i++) - { - uint16_t newcoin_off = (uint16_t) i; - PGresult *result; - - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&newcoin_off), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_order", - params); - } - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - free_dpk_result (denom_pubs, i); - return GNUNET_SYSERR; - } - if (0 == PQntuples (result)) - { - PQclear (result); - /* FIXME: may want to distinguish between different error cases! */ - free_dpk_result (denom_pubs, i); - return GNUNET_SYSERR; - } - GNUNET_assert (1 == PQntuples (result)); - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &denom_pubs[i].rsa_public_key), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, 0)) - { - PQclear (result); - GNUNET_break (0); - free_dpk_result (denom_pubs, i); - return GNUNET_SYSERR; - } - PQclear (result); - } - } - return GNUNET_OK; -} - - -/** - * Store information about the commitment of the - * given coin for the given refresh session in the database. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection to use - * @param session_hash hash to identify refresh session - * @param cnc_index cut and choose index (1st dimension) - * @param num_newcoins coin index size of the @a commit_coins array - * @param commit_coins array of coin commitments to store - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on error - */ -static int -postgres_insert_refresh_commit_coins (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t cnc_index, - uint16_t num_newcoins, - const struct TALER_MINTDB_RefreshCommitCoin *commit_coins) -{ - char *rle; - size_t rle_size; - PGresult *result; - unsigned int i; - uint16_t coin_off; - - for (i=0;i<(unsigned int) num_newcoins;i++) - { - rle = TALER_refresh_link_encrypted_encode (commit_coins[i].refresh_link, - &rle_size); - if (NULL == rle) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - coin_off = (uint16_t) i; - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&cnc_index), - GNUNET_PQ_query_param_uint16 (&coin_off), - GNUNET_PQ_query_param_fixed_size (rle, - rle_size), - GNUNET_PQ_query_param_fixed_size (commit_coins[i].coin_ev, - commit_coins[i].coin_ev_size), - GNUNET_PQ_query_param_end - }; - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_refresh_commit_coin", - params); - } - GNUNET_free (rle); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 != strcmp ("1", PQcmdTuples (result))) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - } - return GNUNET_OK; -} - - -/** - * We allocated some @a commit_coin information, but now need - * to abort. Free allocated memory. - * - * @param commit_coins data to free (but not the array itself) - * @param commit_coins_len length of @a commit_coins array - */ -static void -free_cc_result (struct TALER_MINTDB_RefreshCommitCoin *commit_coins, - unsigned int commit_coins_len) -{ - unsigned int i; - - for (i=0;i<commit_coins_len;i++) - { - GNUNET_free (commit_coins[i].refresh_link); - commit_coins[i].refresh_link = NULL; - GNUNET_free (commit_coins[i].coin_ev); - commit_coins[i].coin_ev = NULL; - commit_coins[i].coin_ev_size = 0; - } -} - - -/** - * Obtain information about the commitment of the - * given coin of the given refresh session from the database. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection to use - * @param session_hash hash to identify refresh session - * @param cnc_index set index (1st dimension) - * @param num_newcoins size of the @a commit_coins array - * @param[out] commit_coins array of coin commitments to return - * @return #GNUNET_OK on success - * #GNUNET_NO if not found - * #GNUNET_SYSERR on error - */ -static int -postgres_get_refresh_commit_coins (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t cnc_index, - uint16_t num_newcoins, - struct TALER_MINTDB_RefreshCommitCoin *commit_coins) -{ - unsigned int i; - - for (i=0;i<(unsigned int) num_newcoins;i++) - { - uint16_t newcoin_off = (uint16_t) i; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&cnc_index), - GNUNET_PQ_query_param_uint16 (&newcoin_off), - GNUNET_PQ_query_param_end - }; - void *c_buf; - size_t c_buf_size; - void *rl_buf; - size_t rl_buf_size; - struct TALER_RefreshLinkEncrypted *rl; - PGresult *result; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_commit_coin", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - free_cc_result (commit_coins, i); - return GNUNET_SYSERR; - } - if (0 == PQntuples (result)) - { - PQclear (result); - free_cc_result (commit_coins, i); - return GNUNET_NO; - } - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_variable_size ("link_vector_enc", - &rl_buf, - &rl_buf_size), - GNUNET_PQ_result_spec_variable_size ("coin_ev", - &c_buf, - &c_buf_size), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_YES != - GNUNET_PQ_extract_result (result, rs, 0)) - { - PQclear (result); - free_cc_result (commit_coins, i); - return GNUNET_SYSERR; - } - } - PQclear (result); - if (rl_buf_size < sizeof (struct TALER_CoinSpendPrivateKeyP)) - { - GNUNET_free (c_buf); - GNUNET_free (rl_buf); - free_cc_result (commit_coins, i); - return GNUNET_SYSERR; - } - rl = TALER_refresh_link_encrypted_decode (rl_buf, - rl_buf_size); - GNUNET_free (rl_buf); - commit_coins[i].refresh_link = rl; - commit_coins[i].coin_ev = c_buf; - commit_coins[i].coin_ev_size = c_buf_size; - } - return GNUNET_YES; -} - - -/** - * Store the commitment to the given (encrypted) refresh link data - * for the given refresh session. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection to use - * @param session_hash hash to identify refresh session - * @param cnc_index cut and choose index (1st dimension) - * @param num_links size of the @a links array to return - * @param[out] links array of link information to store return - * @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success - */ -static int -postgres_insert_refresh_commit_links (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t cnc_index, - uint16_t num_links, - const struct TALER_RefreshCommitLinkP *links) -{ - uint16_t i; - - for (i=0;i<num_links;i++) - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_auto_from_type (&links[i].transfer_pub), - GNUNET_PQ_query_param_uint16 (&cnc_index), - GNUNET_PQ_query_param_uint16 (&i), - GNUNET_PQ_query_param_auto_from_type (&links[i].shared_secret_enc), - GNUNET_PQ_query_param_end - }; - - PGresult *result = GNUNET_PQ_exec_prepared (session->conn, - "insert_refresh_commit_link", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - - if (0 != strcmp ("1", PQcmdTuples (result))) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - PQclear (result); - } - return GNUNET_OK; -} - - -/** - * Obtain the commited (encrypted) refresh link data - * for the given refresh session. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection to use - * @param session_hash hash to identify refresh session - * @param cnc_index cut and choose index (1st dimension) - * @param num_links size of the @a commit_link array - * @param[out] links array of link information to return - * @return #GNUNET_SYSERR on internal error, - * #GNUNET_NO if commitment was not found - * #GNUNET_OK on success - */ -static int -postgres_get_refresh_commit_links (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t cnc_index, - uint16_t num_links, - struct TALER_RefreshCommitLinkP *links) -{ - uint16_t i; - - for (i=0;i<num_links;i++) - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&cnc_index), - GNUNET_PQ_query_param_uint16 (&i), - GNUNET_PQ_query_param_end - }; - PGresult *result; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_commit_link", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 == PQntuples (result)) - { - PQclear (result); - return GNUNET_NO; - } - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("transfer_pub", - &links[i].transfer_pub), - GNUNET_PQ_result_spec_auto_from_type ("link_secret_enc", - &links[i].shared_secret_enc), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_YES != - GNUNET_PQ_extract_result (result, rs, 0)) - { - PQclear (result); - return GNUNET_SYSERR; - } - } - PQclear (result); - } - return GNUNET_OK; -} - - -/** - * Get all of the information from the given melt commit operation. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session database connection to use - * @param session_hash hash to identify refresh session - * @return NULL if the @a session_hash does not correspond to any known melt - * operation - */ -static struct TALER_MINTDB_MeltCommitment * -postgres_get_melt_commitment (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash) -{ - struct TALER_MINTDB_RefreshSession rs; - struct TALER_MINTDB_MeltCommitment *mc; - uint16_t cnc_index; - unsigned int i; - - if (GNUNET_OK != - postgres_get_refresh_session (cls, - session, - session_hash, - &rs)) - return NULL; - mc = GNUNET_new (struct TALER_MINTDB_MeltCommitment); - mc->num_newcoins = rs.num_newcoins; - mc->num_oldcoins = rs.num_oldcoins; - mc->melts = GNUNET_malloc (mc->num_oldcoins * - sizeof (struct TALER_MINTDB_RefreshMelt)); - for (i=0;i<mc->num_oldcoins;i++) - if (GNUNET_OK != - postgres_get_refresh_melt (cls, - session, - session_hash, - (uint16_t) i, - &mc->melts[i])) - goto cleanup; - mc->denom_pubs = GNUNET_malloc (mc->num_newcoins * - sizeof (struct TALER_DenominationPublicKey)); - if (GNUNET_OK != - postgres_get_refresh_order (cls, - session, - session_hash, - mc->num_newcoins, - mc->denom_pubs)) - goto cleanup; - for (cnc_index=0;cnc_index<TALER_CNC_KAPPA;cnc_index++) - { - mc->commit_coins[cnc_index] - = GNUNET_malloc (mc->num_newcoins * - sizeof (struct TALER_MINTDB_RefreshCommitCoin)); - if (GNUNET_OK != - postgres_get_refresh_commit_coins (cls, - session, - session_hash, - cnc_index, - mc->num_newcoins, - mc->commit_coins[cnc_index])) - goto cleanup; - mc->commit_links[cnc_index] - = GNUNET_malloc (mc->num_oldcoins * - sizeof (struct TALER_RefreshCommitLinkP)); - if (GNUNET_OK != - postgres_get_refresh_commit_links (cls, - session, - session_hash, - cnc_index, - mc->num_oldcoins, - mc->commit_links[cnc_index])) - goto cleanup; - } - return mc; - - cleanup: - common_free_melt_commitment (cls, mc); - return NULL; -} - - -/** - * Insert signature of a new coin generated during refresh into - * the database indexed by the refresh session and the index - * of the coin. This data is later used should an old coin - * be used to try to obtain the private keys during "/refresh/link". - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param session_hash hash to identify refresh session - * @param newcoin_index coin index - * @param ev_sig coin signature - * @return #GNUNET_OK on success - */ -static int -postgres_insert_refresh_out (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t newcoin_index, - const struct TALER_DenominationSignature *ev_sig) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&newcoin_index), - GNUNET_PQ_query_param_rsa_signature (ev_sig->rsa_signature), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_refresh_out", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Obtain the link data of a coin, that is the encrypted link - * information, the denomination keys and the signatures. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param session_hash refresh session to get linkage data for - * @return all known link data for the session - */ -static struct TALER_MINTDB_LinkDataList * -postgres_get_link_data_list (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash) -{ - struct TALER_MINTDB_LinkDataList *ldl; - struct TALER_MINTDB_LinkDataList *pos; - int i; - int nrows; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_end - }; - PGresult *result; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_link", - params); - - ldl = NULL; - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return NULL; - } - nrows = PQntuples (result); - if (0 == nrows) - { - PQclear (result); - return NULL; - } - - for (i = 0; i < nrows; i++) - { - struct TALER_RefreshLinkEncrypted *link_enc; - struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub; - struct GNUNET_CRYPTO_rsa_Signature *sig; - void *ld_buf; - size_t ld_buf_size; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_variable_size ("link_vector_enc", - &ld_buf, - &ld_buf_size), - GNUNET_PQ_result_spec_rsa_signature ("ev_sig", - &sig), - GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &denom_pub), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, i)) - { - PQclear (result); - GNUNET_break (0); - common_free_link_data_list (cls, - ldl); - return NULL; - } - if (ld_buf_size < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) - { - PQclear (result); - GNUNET_free (ld_buf); - common_free_link_data_list (cls, - ldl); - return NULL; - } - link_enc = TALER_refresh_link_encrypted_decode (ld_buf, - ld_buf_size); - GNUNET_free (ld_buf); - pos = GNUNET_new (struct TALER_MINTDB_LinkDataList); - pos->next = ldl; - pos->link_data_enc = link_enc; - pos->denom_pub.rsa_public_key = denom_pub; - pos->ev_sig.rsa_signature = sig; - ldl = pos; - } - return ldl; -} - - -/** - * Obtain shared secret and transfer public key from the public key of - * the coin. This information and the link information returned by - * #postgres_get_link_data_list() enable the owner of an old coin to - * determine the private keys of the new coins after the melt. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param coin_pub public key of the coin - * @param tdc function to call for each session the coin was melted into - * @param tdc_cls closure for @a tdc - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure (not found) - * #GNUNET_SYSERR on internal failure (database issue) - */ -static int -postgres_get_transfer (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - TALER_MINTDB_TransferDataCallback tdc, - void *tdc_cls) -{ - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (coin_pub), - GNUNET_PQ_query_param_end - }; - PGresult *result; - int nrows; - int i; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_transfer", - params); - if (PGRES_TUPLES_OK != - PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - nrows = PQntuples (result); - if (0 == nrows) - { - /* no matches found */ - PQclear (result); - return GNUNET_NO; - } - for (i=0;i<nrows;i++) - { - struct GNUNET_HashCode session_hash; - struct TALER_TransferPublicKeyP transfer_pub; - struct TALER_EncryptedLinkSecretP shared_secret_enc; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("transfer_pub", &transfer_pub), - GNUNET_PQ_result_spec_auto_from_type ("link_secret_enc", &shared_secret_enc), - GNUNET_PQ_result_spec_auto_from_type ("session_hash", &session_hash), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, 0)) - { - PQclear (result); - GNUNET_break (0); - return GNUNET_SYSERR; - } - tdc (tdc_cls, - &session_hash, - &transfer_pub, - &shared_secret_enc); - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Compile a list of all (historic) transactions performed - * with the given coin (/refresh/melt and /deposit operations). - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param coin_pub coin to investigate - * @return list of transactions, NULL if coin is fresh - */ -static struct TALER_MINTDB_TransactionList * -postgres_get_coin_transactions (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_CoinSpendPublicKeyP *coin_pub) -{ - struct TALER_MINTDB_TransactionList *head; - - head = NULL; - /* check deposits */ - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&coin_pub->eddsa_pub), - GNUNET_PQ_query_param_end - }; - int nrows; - int i; - PGresult *result; - struct TALER_MINTDB_TransactionList *tl; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_deposit_with_coin_pub", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - QUERY_ERR (result); - PQclear (result); - goto cleanup; - } - nrows = PQntuples (result); - for (i = 0; i < nrows; i++) - { - struct TALER_MINTDB_Deposit *deposit; - - deposit = GNUNET_new (struct TALER_MINTDB_Deposit); - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &deposit->coin.denom_pub.rsa_public_key), - GNUNET_PQ_result_spec_rsa_signature ("denom_sig", - &deposit->coin.denom_sig.rsa_signature), - GNUNET_PQ_result_spec_uint64 ("transaction_id", - &deposit->transaction_id), - TALER_PQ_result_spec_amount ("amount_with_fee", - &deposit->amount_with_fee), - TALER_PQ_result_spec_amount ("deposit_fee", - &deposit->deposit_fee), - GNUNET_PQ_result_spec_absolute_time ("timestamp", - &deposit->timestamp), - GNUNET_PQ_result_spec_absolute_time ("refund_deadline", - &deposit->refund_deadline), - GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", - &deposit->merchant_pub), - GNUNET_PQ_result_spec_auto_from_type ("h_contract", - &deposit->h_contract), - GNUNET_PQ_result_spec_auto_from_type ("h_wire", - &deposit->h_wire), - TALER_PQ_result_spec_json ("wire", - &deposit->wire), - GNUNET_PQ_result_spec_auto_from_type ("coin_sig", - &deposit->csig), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, i)) - { - GNUNET_break (0); - GNUNET_free (deposit); - PQclear (result); - goto cleanup; - } - deposit->coin.coin_pub = *coin_pub; - } - tl = GNUNET_new (struct TALER_MINTDB_TransactionList); - tl->next = head; - tl->type = TALER_MINTDB_TT_DEPOSIT; - tl->details.deposit = deposit; - head = tl; - continue; - } - PQclear (result); - } - /* Handle refreshing */ - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&coin_pub->eddsa_pub), - GNUNET_PQ_query_param_end - }; - int nrows; - int i; - PGresult *result; - struct TALER_MINTDB_TransactionList *tl; - - /* check if the melt record exists and get it */ - result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_melt_by_coin", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - goto cleanup; - } - nrows = PQntuples (result); - for (i=0;i<nrows;i++) - { - struct TALER_MINTDB_RefreshMelt *melt; - - melt = GNUNET_new (struct TALER_MINTDB_RefreshMelt); - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("session_hash", - &melt->session_hash), - /* oldcoin_index not needed */ - GNUNET_PQ_result_spec_auto_from_type ("coin_sig", - &melt->coin_sig), - TALER_PQ_result_spec_amount ("amount_with_fee", - &melt->amount_with_fee), - TALER_PQ_result_spec_amount ("melt_fee", - &melt->melt_fee), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - GNUNET_free (melt); - PQclear (result); - goto cleanup; - } - melt->coin.coin_pub = *coin_pub; - } - tl = GNUNET_new (struct TALER_MINTDB_TransactionList); - tl->next = head; - tl->type = TALER_MINTDB_TT_REFRESH_MELT; - tl->details.melt = melt; - head = tl; - continue; - } - PQclear (result); - } - return head; - cleanup: - if (NULL != head) - common_free_coin_transaction_list (cls, - head); - return NULL; -} - - -/** - * Lookup the list of Taler transactions that were aggregated - * into a wire transfer by the respective @a wtid. - * - * @param cls closure - * @param session database connection - * @param wtid the raw wire transfer identifier we used - * @param cb function to call on each transaction found - * @param cb_cls closure for @a cb - * @return #GNUNET_OK on success, #GNUNET_SYSERR on database errors, - * #GNUNET_NO if we found no results - */ -static int -postgres_lookup_wire_transfer (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_WireTransferIdentifierRawP *wtid, - TALER_MINTDB_WireTransferDataCallback cb, - void *cb_cls) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (wtid), - GNUNET_PQ_query_param_end - }; - int nrows; - int i; - - /* check if the melt record exists and get it */ - result = GNUNET_PQ_exec_prepared (session->conn, - "lookup_transactions", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - nrows = PQntuples (result); - if (0 == nrows) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "lookup_wire_transfer() returned 0 matching rows\n"); - PQclear (result); - return GNUNET_NO; - } - for (i=0;i<nrows;i++) - { - struct GNUNET_HashCode h_contract; - struct GNUNET_HashCode h_wire; - struct TALER_CoinSpendPublicKeyP coin_pub; - struct TALER_MerchantPublicKeyP merchant_pub; - uint64_t transaction_id; - struct GNUNET_TIME_Absolute exec_time; - struct TALER_Amount coin_amount; - struct TALER_Amount coin_fee; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("h_contract", &h_contract), - GNUNET_PQ_result_spec_auto_from_type ("h_wire", &h_wire), - GNUNET_PQ_result_spec_auto_from_type ("coin_pub", &coin_pub), - GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", &merchant_pub), - GNUNET_PQ_result_spec_uint64 ("transaction_id", &transaction_id), - GNUNET_PQ_result_spec_absolute_time ("execution_time", &exec_time), - TALER_PQ_result_spec_amount ("coin_amount", &coin_amount), - TALER_PQ_result_spec_amount ("coin_fee", &coin_fee), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, i)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - cb (cb_cls, - &merchant_pub, - &h_wire, - &h_contract, - transaction_id, - &coin_pub, - &coin_amount, - &coin_fee); - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Try to find the wire transfer details for a deposit operation. - * If we did not execute the deposit yet, return when it is supposed - * to be executed. - * - * @param cls closure - * @param session database connection - * @param h_contract hash of the contract - * @param h_wire hash of merchant wire details - * @param coin_pub public key of deposited coin - * @param merchant_pub merchant public key - * @param transaction_id transaction identifier - * @param cb function to call with the result - * @param cb_cls closure to pass to @a cb - * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors, - * #GNUNET_NO if nothing was found - */ -static int -postgres_wire_lookup_deposit_wtid (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *h_contract, - const struct GNUNET_HashCode *h_wire, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_MerchantPublicKeyP *merchant_pub, - uint64_t transaction_id, - TALER_MINTDB_DepositWtidCallback cb, - void *cb_cls) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (coin_pub), - GNUNET_PQ_query_param_auto_from_type (h_contract), - GNUNET_PQ_query_param_auto_from_type (h_wire), - GNUNET_PQ_query_param_uint64 (&transaction_id), - GNUNET_PQ_query_param_auto_from_type (merchant_pub), - GNUNET_PQ_query_param_end - }; - int nrows; - - /* check if the melt record exists and get it */ - result = GNUNET_PQ_exec_prepared (session->conn, - "lookup_deposit_wtid", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - nrows = PQntuples (result); - if (0 == nrows) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "lookup_deposit_wtid returned 0 matching rows\n"); - PQclear (result); - - /* Check if transaction exists in deposits, so that we just - do not have a WTID yet, if so, do call the CB with a NULL wtid - and return GNUNET_YES! */ - { - struct GNUNET_PQ_QueryParam params2[] = { - GNUNET_PQ_query_param_auto_from_type (coin_pub), - GNUNET_PQ_query_param_uint64 (&transaction_id), - GNUNET_PQ_query_param_auto_from_type (merchant_pub), - GNUNET_PQ_query_param_auto_from_type (h_contract), - GNUNET_PQ_query_param_auto_from_type (h_wire), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "get_deposit_for_wtid", - params2); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - } - nrows = PQntuples (result); - if (0 == nrows) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "get_deposit_for_wtid returned 0 matching rows\n"); - PQclear (result); - return GNUNET_NO; - } - - /* Ok, we're aware of the transaction, but it has not yet been - executed */ - { - struct GNUNET_TIME_Absolute exec_time; - struct TALER_Amount coin_amount; - struct TALER_Amount coin_fee; - struct GNUNET_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_amount ("amount_with_fee", &coin_amount), - TALER_PQ_result_spec_amount ("deposit_fee", &coin_fee), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", &exec_time), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - cb (cb_cls, - NULL, - &coin_amount, - &coin_fee, - exec_time); - PQclear (result); - return GNUNET_YES; - } - } - if (1 != nrows) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - { - struct TALER_WireTransferIdentifierRawP wtid; - struct GNUNET_TIME_Absolute exec_time; - struct TALER_Amount coin_amount; - struct TALER_Amount coin_fee; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("wtid_raw", &wtid), - GNUNET_PQ_result_spec_absolute_time ("execution_time", &exec_time), - TALER_PQ_result_spec_amount ("coin_amount", &coin_amount), - TALER_PQ_result_spec_amount ("coin_fee", &coin_fee), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - cb (cb_cls, - &wtid, - &coin_amount, - &coin_fee, - exec_time); - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Function called to insert aggregation information into the DB. - * - * @param cls closure - * @param session database connection - * @param wtid the raw wire transfer identifier we used - * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls) - * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls) - * @param h_contract which contract was this payment about - * @param transaction_id merchant's transaction ID for the payment - * @param coin_pub which public key was this payment about - * @param coin_value amount contributed by this coin in total - * @param coin_fee deposit fee charged by mint for this coin - * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors - */ -static int -postgres_insert_aggregation_tracking (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct GNUNET_HashCode *h_wire, - const struct GNUNET_HashCode *h_contract, - uint64_t transaction_id, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *coin_value, - const struct TALER_Amount *coin_fee) -{ - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (h_contract), - GNUNET_PQ_query_param_auto_from_type (h_wire), - GNUNET_PQ_query_param_auto_from_type (coin_pub), - GNUNET_PQ_query_param_auto_from_type (merchant_pub), - GNUNET_PQ_query_param_uint64 (&transaction_id), - GNUNET_PQ_query_param_auto_from_type (wtid), - GNUNET_PQ_query_param_absolute_time (&execution_time), - TALER_PQ_query_param_amount (coin_value), - TALER_PQ_query_param_amount (coin_fee), - GNUNET_PQ_query_param_end - }; - PGresult *result; - - result = GNUNET_PQ_exec_prepared (session->conn, - "insert_aggregation_tracking", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 != strcmp ("1", PQcmdTuples (result))) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Function called to insert wire transfer commit data into the DB. - * - * @param cls closure - * @param session database connection - * @param type type of the wire transfer (i.e. "sepa") - * @param buf buffer with wire transfer preparation data - * @param buf_size number of bytes in @a buf - * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors - */ -static int -postgres_wire_prepare_data_insert (void *cls, - struct TALER_MINTDB_Session *session, - const char *type, - const char *buf, - size_t buf_size) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_fixed_size (type, strlen (type) + 1), - GNUNET_PQ_query_param_fixed_size (buf, buf_size), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "wire_prepare_data_insert", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Function called to mark wire transfer commit data as finished. - * - * @param cls closure - * @param session database connection - * @param rowid which entry to mark as finished - * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors - */ -static int -postgres_wire_prepare_data_mark_finished (void *cls, - struct TALER_MINTDB_Session *session, - unsigned long long rowid) -{ - uint64_t serial_id = rowid; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&serial_id), - GNUNET_PQ_query_param_end - }; - PGresult *result; - - result = GNUNET_PQ_exec_prepared (session->conn, - "wire_prepare_data_mark_done", - params); - if (PGRES_COMMAND_OK != - PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Function called to get an unfinished wire transfer - * preparation data. Fetches at most one item. - * - * @param cls closure - * @param session database connection - * @param type type fo the wire transfer (i.e. "sepa") - * @param cb function to call for ONE unfinished item - * @param cb_cls closure for @a cb - * @return #GNUNET_OK on success, - * #GNUNET_NO if there are no entries, - * #GNUNET_SYSERR on DB errors - */ -static int -postgres_wire_prepare_data_get (void *cls, - struct TALER_MINTDB_Session *session, - const char *type, - TALER_MINTDB_WirePreparationCallback cb, - void *cb_cls) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_fixed_size (type, strlen (type) + 1), - GNUNET_PQ_query_param_end - }; - - result = GNUNET_PQ_exec_prepared (session->conn, - "wire_prepare_data_get", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - QUERY_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - if (0 == PQntuples (result)) - { - PQclear (result); - return GNUNET_NO; - } - if (1 != PQntuples (result)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - - { - uint64_t serial_id; - void *buf = NULL; - size_t buf_size; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("serial_id", - &serial_id), - GNUNET_PQ_result_spec_variable_size ("buf", - &buf, - &buf_size), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, - rs, - 0)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - cb (cb_cls, - serial_id, - buf, - buf_size); - GNUNET_PQ_cleanup_result (rs); - } - PQclear (result); - return GNUNET_OK; -} - - -/** - * Initialize Postgres database subsystem. - * - * @param cls a configuration instance - * @return NULL on error, otherwise a `struct TALER_MINTDB_Plugin` - */ -void * -libtaler_plugin_mintdb_postgres_init (void *cls) -{ - struct GNUNET_CONFIGURATION_Handle *cfg = cls; - struct PostgresClosure *pg; - struct TALER_MINTDB_Plugin *plugin; - - pg = GNUNET_new (struct PostgresClosure); - - if (0 != pthread_key_create (&pg->db_conn_threadlocal, - &db_conn_destroy)) - { - TALER_LOG_ERROR ("Cannnot create pthread key.\n"); - GNUNET_free (pg); - return NULL; - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "mintdb-postgres", - "db_conn_str", - &pg->connection_cfg_str)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "mintdb-postgres", - "db_conn_str"); - GNUNET_free (pg); - return NULL; - } - plugin = GNUNET_new (struct TALER_MINTDB_Plugin); - plugin->cls = pg; - plugin->get_session = &postgres_get_session; - plugin->drop_temporary = &postgres_drop_temporary; - plugin->create_tables = &postgres_create_tables; - plugin->start = &postgres_start; - plugin->commit = &postgres_commit; - plugin->rollback = &postgres_rollback; - plugin->insert_denomination_info = &postgres_insert_denomination_info; - plugin->get_denomination_info = &postgres_get_denomination_info; - plugin->reserve_get = &postgres_reserve_get; - plugin->reserves_in_insert = &postgres_reserves_in_insert; - plugin->get_withdraw_info = &postgres_get_withdraw_info; - plugin->insert_withdraw_info = &postgres_insert_withdraw_info; - plugin->get_reserve_history = &postgres_get_reserve_history; - plugin->free_reserve_history = &common_free_reserve_history; - plugin->have_deposit = &postgres_have_deposit; - plugin->mark_deposit_tiny = &postgres_mark_deposit_tiny; - plugin->mark_deposit_done = &postgres_mark_deposit_done; - plugin->get_ready_deposit = &postgres_get_ready_deposit; - plugin->iterate_matching_deposits = &postgres_iterate_matching_deposits; - plugin->insert_deposit = &postgres_insert_deposit; - plugin->get_refresh_session = &postgres_get_refresh_session; - plugin->create_refresh_session = &postgres_create_refresh_session; - plugin->insert_refresh_melt = &postgres_insert_refresh_melt; - plugin->get_refresh_melt = &postgres_get_refresh_melt; - plugin->insert_refresh_order = &postgres_insert_refresh_order; - plugin->get_refresh_order = &postgres_get_refresh_order; - plugin->insert_refresh_commit_coins = &postgres_insert_refresh_commit_coins; - plugin->get_refresh_commit_coins = &postgres_get_refresh_commit_coins; - plugin->insert_refresh_commit_links = &postgres_insert_refresh_commit_links; - plugin->get_refresh_commit_links = &postgres_get_refresh_commit_links; - plugin->get_melt_commitment = &postgres_get_melt_commitment; - plugin->free_melt_commitment = &common_free_melt_commitment; - plugin->insert_refresh_out = &postgres_insert_refresh_out; - plugin->get_link_data_list = &postgres_get_link_data_list; - plugin->free_link_data_list = &common_free_link_data_list; - plugin->get_transfer = &postgres_get_transfer; - plugin->get_coin_transactions = &postgres_get_coin_transactions; - plugin->free_coin_transaction_list = &common_free_coin_transaction_list; - plugin->lookup_wire_transfer = &postgres_lookup_wire_transfer; - plugin->wire_lookup_deposit_wtid = &postgres_wire_lookup_deposit_wtid; - plugin->insert_aggregation_tracking = &postgres_insert_aggregation_tracking; - plugin->wire_prepare_data_insert = &postgres_wire_prepare_data_insert; - plugin->wire_prepare_data_mark_finished = &postgres_wire_prepare_data_mark_finished; - plugin->wire_prepare_data_get = &postgres_wire_prepare_data_get; - return plugin; -} - - -/** - * Shutdown Postgres database subsystem. - * - * @param cls a `struct TALER_MINTDB_Plugin` - * @return NULL (always) - */ -void * -libtaler_plugin_mintdb_postgres_done (void *cls) -{ - struct TALER_MINTDB_Plugin *plugin = cls; - struct PostgresClosure *pg = plugin->cls; - - GNUNET_free (pg->connection_cfg_str); - GNUNET_free (pg); - GNUNET_free (plugin); - return NULL; -} - -/* end of plugin_mintdb_postgres.c */ diff --git a/src/mintdb/test-mint-db-postgres.conf b/src/mintdb/test-mint-db-postgres.conf deleted file mode 100644 index 2bdb63eb0..000000000 --- a/src/mintdb/test-mint-db-postgres.conf +++ /dev/null @@ -1,8 +0,0 @@ -[mint] -#The DB plugin to use -DB = postgres - -[mintdb-postgres] - -#The connection string the plugin has to use for connecting to the database -DB_CONN_STR = postgres:///talercheck diff --git a/src/mintdb/test_mintdb.c b/src/mintdb/test_mintdb.c deleted file mode 100644 index 0938f8fab..000000000 --- a/src/mintdb/test_mintdb.c +++ /dev/null @@ -1,907 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015, 2016 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file mintdb/test_mintdb.c - * @brief test cases for DB interaction functions - * @author Sree Harsha Totakura <sreeharsha@totakura.in> - */ -#include "platform.h" -#include "taler_mintdb_lib.h" -#include "taler_mintdb_plugin.h" - -static int result; - -#define FAILIF(cond) \ - do { \ - if (!(cond)){ break;} \ - GNUNET_break (0); \ - goto drop; \ - } while (0) - - -#define RND_BLK(ptr) \ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr)) - -#define ZR_BLK(ptr) \ - memset (ptr, 0, sizeof (*ptr)) - - -#define CURRENCY "EUR" - -static struct TALER_MINTDB_Plugin *plugin; - -/** - * Checks if the given reserve has the given amount of balance and expiry - * - * @param session the database connection - * @param pub the public key of the reserve - * @param value balance value - * @param fraction balance fraction - * @param currency currency of the reserve - * @return #GNUNET_OK if the given reserve has the same balance and expiration - * as the given parameters; #GNUNET_SYSERR if not - */ -static int -check_reserve (struct TALER_MINTDB_Session *session, - const struct TALER_ReservePublicKeyP *pub, - uint64_t value, - uint32_t fraction, - const char *currency) -{ - struct TALER_MINTDB_Reserve reserve; - - reserve.pub = *pub; - - FAILIF (GNUNET_OK != - plugin->reserve_get (plugin->cls, - session, - &reserve)); - FAILIF (value != reserve.balance.value); - FAILIF (fraction != reserve.balance.fraction); - FAILIF (0 != strcmp (currency, reserve.balance.currency)); - - return GNUNET_OK; - drop: - return GNUNET_SYSERR; -} - - -struct DenomKeyPair -{ - struct TALER_DenominationPrivateKey priv; - struct TALER_DenominationPublicKey pub; -}; - - -/** - * Destroy a denomination key pair. The key is not necessarily removed from the DB. - * - * @param dkp the keypair to destroy - */ -static void -destroy_denom_key_pair (struct DenomKeyPair *dkp) -{ - GNUNET_CRYPTO_rsa_public_key_free (dkp->pub.rsa_public_key); - GNUNET_CRYPTO_rsa_private_key_free (dkp->priv.rsa_private_key); - GNUNET_free (dkp); -} - - -/** - * Create a denominaiton key pair by registering the denomination in the DB. - * - * @param size the size of the denomination key - * @param session the DB session - * @return the denominaiton key pair; NULL upon error - */ -static struct DenomKeyPair * -create_denom_key_pair (unsigned int size, - struct TALER_MINTDB_Session *session, - const struct TALER_Amount *value, - const struct TALER_Amount *fee_withdraw, - const struct TALER_Amount *fee_deposit, - const struct TALER_Amount *fee_refresh) -{ - struct DenomKeyPair *dkp; - struct TALER_MINTDB_DenominationKeyIssueInformation dki; - - dkp = GNUNET_new (struct DenomKeyPair); - dkp->priv.rsa_private_key = GNUNET_CRYPTO_rsa_private_key_create (size); - GNUNET_assert (NULL != dkp->priv.rsa_private_key); - dkp->pub.rsa_public_key - = GNUNET_CRYPTO_rsa_private_key_get_public (dkp->priv.rsa_private_key); - - /* Using memset() as fields like master key and signature - are not properly initialized for this test. */ - memset (&dki, - 0, - sizeof (struct TALER_MINTDB_DenominationKeyIssueInformation)); - dki.denom_pub = dkp->pub; - dki.issue.properties.start = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); - dki.issue.properties.expire_withdraw = GNUNET_TIME_absolute_hton - (GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), - GNUNET_TIME_UNIT_HOURS)); - dki.issue.properties.expire_spend = GNUNET_TIME_absolute_hton - (GNUNET_TIME_absolute_add - (GNUNET_TIME_absolute_get (), - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 2))); - dki.issue.properties.expire_legal = GNUNET_TIME_absolute_hton - (GNUNET_TIME_absolute_add - (GNUNET_TIME_absolute_get (), - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 3))); - TALER_amount_hton (&dki.issue.properties.value, value); - TALER_amount_hton (&dki.issue.properties.fee_withdraw, fee_withdraw); - TALER_amount_hton (&dki.issue.properties.fee_deposit, fee_deposit); - TALER_amount_hton (&dki.issue.properties.fee_refresh, fee_refresh); - GNUNET_CRYPTO_rsa_public_key_hash (dkp->pub.rsa_public_key, - &dki.issue.properties.denom_hash); - if (GNUNET_OK != - plugin->insert_denomination_info (plugin->cls, - session, - &dki.denom_pub, - &dki.issue)) - { - GNUNET_break(0); - destroy_denom_key_pair (dkp); - return NULL; - } - return dkp; -} - -static struct TALER_Amount value; -static struct TALER_Amount fee_withdraw; -static struct TALER_Amount fee_deposit; -static struct TALER_Amount fee_refresh; -static struct TALER_Amount amount_with_fee; - -static void -free_refresh_commit_coins_array(struct TALER_MINTDB_RefreshCommitCoin - *commit_coins, - unsigned int size) -{ - unsigned int cnt; - struct TALER_MINTDB_RefreshCommitCoin *ccoin; - struct TALER_RefreshLinkEncrypted *rlink; - - for (cnt = 0; cnt < size; cnt++) - { - ccoin = &commit_coins[cnt]; - GNUNET_free_non_null (ccoin->coin_ev); - rlink = (struct TALER_RefreshLinkEncrypted *) ccoin->refresh_link; - GNUNET_free_non_null (rlink); - } - GNUNET_free (commit_coins); -} - -#define MELT_NEW_COINS 5 - -static int -test_refresh_commit_coins (struct TALER_MINTDB_Session *session, - struct TALER_MINTDB_RefreshSession *refresh_session, - const struct GNUNET_HashCode *session_hash) -{ - struct TALER_MINTDB_RefreshCommitCoin *commit_coins; - struct TALER_MINTDB_RefreshCommitCoin *ret_commit_coins; - struct TALER_MINTDB_RefreshCommitCoin *a_ccoin; - struct TALER_RefreshLinkEncrypted *a_rlink; - struct TALER_MINTDB_RefreshCommitCoin *b_ccoin; - struct TALER_RefreshLinkEncrypted *b_rlink; - size_t size; - unsigned int cnt; - uint16_t cnc_index; - int ret; - - #define COIN_ENC_MAX_SIZE 512 - ret = GNUNET_SYSERR; - ret_commit_coins = NULL; - commit_coins = GNUNET_new_array (MELT_NEW_COINS, - struct TALER_MINTDB_RefreshCommitCoin); - cnc_index = (uint16_t) GNUNET_CRYPTO_random_u32 - (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_MIN (MELT_NEW_COINS, UINT16_MAX)); - for (cnt=0; cnt < MELT_NEW_COINS; cnt++) - { - struct TALER_MINTDB_RefreshCommitCoin *ccoin; - struct TALER_RefreshLinkEncrypted *rlink; - ccoin = &commit_coins[cnt]; - size = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - COIN_ENC_MAX_SIZE); - rlink = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) + size); - ccoin->refresh_link = rlink; - ccoin->coin_ev_size = GNUNET_CRYPTO_random_u64 - (GNUNET_CRYPTO_QUALITY_WEAK, COIN_ENC_MAX_SIZE); - ccoin->coin_ev = GNUNET_malloc (ccoin->coin_ev_size); - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - ccoin->coin_ev, - ccoin->coin_ev_size); - rlink->blinding_key_enc_size = size; - RND_BLK (&rlink->coin_priv_enc); - rlink->blinding_key_enc = (const char *) &rlink[1]; - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - (void *)rlink->blinding_key_enc, - rlink->blinding_key_enc_size); - } - FAILIF (GNUNET_OK != - plugin->insert_refresh_commit_coins (plugin->cls, - session, - session_hash, - cnc_index, - MELT_NEW_COINS, - commit_coins)); - ret_commit_coins = GNUNET_new_array (MELT_NEW_COINS, - struct TALER_MINTDB_RefreshCommitCoin); - FAILIF (GNUNET_OK != - plugin->get_refresh_commit_coins (plugin->cls, - session, - session_hash, - cnc_index, - MELT_NEW_COINS, - ret_commit_coins)); - /* compare the refresh commit coin arrays */ - for (cnt = 0; cnt < MELT_NEW_COINS; cnt++) - { - a_ccoin = &commit_coins[cnt]; - b_ccoin = &ret_commit_coins[cnt]; - FAILIF (a_ccoin->coin_ev_size != b_ccoin->coin_ev_size); - FAILIF (0 != memcmp (a_ccoin->coin_ev, - a_ccoin->coin_ev, - a_ccoin->coin_ev_size)); - a_rlink = a_ccoin->refresh_link; - b_rlink = b_ccoin->refresh_link; - FAILIF (a_rlink->blinding_key_enc_size != b_rlink->blinding_key_enc_size); - FAILIF (0 != memcmp (a_rlink->blinding_key_enc, - b_rlink->blinding_key_enc, - a_rlink->blinding_key_enc_size)); - FAILIF (0 != memcmp (a_rlink->coin_priv_enc, - b_rlink->coin_priv_enc, - sizeof (a_rlink->coin_priv_enc))); - } - ret = GNUNET_OK; - - drop: - if (NULL != ret_commit_coins) - free_refresh_commit_coins_array (ret_commit_coins, MELT_NEW_COINS); - if (NULL != commit_coins) - free_refresh_commit_coins_array (commit_coins, MELT_NEW_COINS); - return ret; -} - -/** - * Function to test melting of coins as part of a refresh session - * - * @param session the database session - * @param refresh_session the refresh session - * @return #GNUNET_OK if everything went well; #GNUNET_SYSERR if not - */ -static int -test_melting (struct TALER_MINTDB_Session *session) -{ -#define MELT_OLD_COINS 10 - struct TALER_MINTDB_RefreshSession refresh_session; - struct TALER_MINTDB_RefreshSession ret_refresh_session; - struct GNUNET_HashCode session_hash; - struct DenomKeyPair *dkp; - struct DenomKeyPair **new_dkp; - /* struct TALER_CoinPublicInfo *coins; */ - struct TALER_MINTDB_RefreshMelt *melts; - struct TALER_DenominationPublicKey *new_denom_pubs; - struct TALER_DenominationPublicKey *ret_denom_pubs; - unsigned int cnt; - int ret; - - ret = GNUNET_SYSERR; - RND_BLK (&refresh_session); - RND_BLK (&session_hash); - melts = NULL; - dkp = NULL; - new_dkp = NULL; - new_denom_pubs = NULL; - ret_denom_pubs = NULL; - /* create and test a refresh session */ - refresh_session.num_oldcoins = MELT_OLD_COINS; - refresh_session.num_newcoins = 1; - refresh_session.noreveal_index = 1; - FAILIF (GNUNET_OK != plugin->create_refresh_session (plugin->cls, - session, - &session_hash, - &refresh_session)); - FAILIF (GNUNET_OK != plugin->get_refresh_session (plugin->cls, - session, - &session_hash, - &ret_refresh_session)); - FAILIF (0 != memcmp (&ret_refresh_session, - &refresh_session, - sizeof (refresh_session))); - - /* create a denomination (value: 1; fraction: 100) */ - dkp = create_denom_key_pair (512, session, - &value, - &fee_withdraw, - &fee_deposit, - &fee_refresh); - /* create MELT_OLD_COINS number of refresh melts */ - melts = GNUNET_new_array (MELT_OLD_COINS, struct TALER_MINTDB_RefreshMelt); - for (cnt=0; cnt < MELT_OLD_COINS; cnt++) - { - RND_BLK (&melts[cnt].coin.coin_pub); - melts[cnt].coin.denom_sig.rsa_signature = - GNUNET_CRYPTO_rsa_sign (dkp->priv.rsa_private_key, - &melts[cnt].coin.coin_pub, - sizeof (melts[cnt].coin.coin_pub)); - melts[cnt].coin.denom_pub = dkp->pub; - RND_BLK (&melts[cnt].coin_sig); - melts[cnt].session_hash = session_hash; - melts[cnt].amount_with_fee = amount_with_fee; - melts[cnt].melt_fee = fee_refresh; - FAILIF (GNUNET_OK != plugin->insert_refresh_melt (plugin->cls, - session, - cnt, - &melts[cnt])); - } - for (cnt = 0; cnt < MELT_OLD_COINS; cnt++) - { - struct TALER_MINTDB_RefreshMelt ret_melt; - FAILIF (GNUNET_OK != plugin->get_refresh_melt (plugin->cls, - session, - &session_hash, - cnt, - &ret_melt)); - FAILIF (0 != GNUNET_CRYPTO_rsa_signature_cmp - (ret_melt.coin.denom_sig.rsa_signature, - melts[cnt].coin.denom_sig.rsa_signature)); - FAILIF (0 != memcmp (&ret_melt.coin.coin_pub, - &melts[cnt].coin.coin_pub, - sizeof (ret_melt.coin.coin_pub))); - FAILIF (0 != GNUNET_CRYPTO_rsa_public_key_cmp - (ret_melt.coin.denom_pub.rsa_public_key, - melts[cnt].coin.denom_pub.rsa_public_key)); - FAILIF (0 != memcmp (&ret_melt.coin_sig, - &melts[cnt].coin_sig, - sizeof (ret_melt.coin_sig))); - FAILIF (0 != memcmp (&ret_melt.session_hash, - &melts[cnt].session_hash, - sizeof (ret_melt.session_hash))); - FAILIF (0 != TALER_amount_cmp (&ret_melt.amount_with_fee, - &melts[cnt].amount_with_fee)); - FAILIF (0 != TALER_amount_cmp (&ret_melt.melt_fee, - &melts[cnt].melt_fee)); - GNUNET_CRYPTO_rsa_signature_free (ret_melt.coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (ret_melt.coin.denom_pub.rsa_public_key); - } - new_dkp = GNUNET_new_array (MELT_NEW_COINS, struct DenomKeyPair *); - new_denom_pubs = GNUNET_new_array (MELT_NEW_COINS, - struct TALER_DenominationPublicKey); - for (cnt=0; cnt < MELT_NEW_COINS; cnt++) - { - new_dkp[cnt] = create_denom_key_pair (128, session, - &value, - &fee_withdraw, - &fee_deposit, - &fee_refresh); - new_denom_pubs[cnt]=new_dkp[cnt]->pub; - } - FAILIF (GNUNET_OK != plugin->insert_refresh_order (plugin->cls, - session, - &session_hash, - MELT_NEW_COINS, - new_denom_pubs)); - ret_denom_pubs = GNUNET_new_array (MELT_NEW_COINS, - struct TALER_DenominationPublicKey); - FAILIF (GNUNET_OK != plugin->get_refresh_order (plugin->cls, - session, - &session_hash, - MELT_NEW_COINS, - ret_denom_pubs)); - for (cnt=0; cnt < MELT_NEW_COINS; cnt++) - { - FAILIF (0 != GNUNET_CRYPTO_rsa_public_key_cmp - (ret_denom_pubs[cnt].rsa_public_key, - new_denom_pubs[cnt].rsa_public_key)); - } - FAILIF (GNUNET_OK != - test_refresh_commit_coins (session, - &refresh_session, - &session_hash)); - - ret = GNUNET_OK; - - drop: - if (NULL != dkp) - destroy_denom_key_pair (dkp); - if (NULL != melts) - { - for (cnt = 0; cnt < MELT_OLD_COINS; cnt++) - GNUNET_CRYPTO_rsa_signature_free (melts[cnt].coin.denom_sig.rsa_signature); - GNUNET_free (melts); - } - for (cnt = 0; - (NULL != ret_denom_pubs) && (cnt < MELT_NEW_COINS) - && (NULL != ret_denom_pubs[cnt].rsa_public_key); - cnt++) - GNUNET_CRYPTO_rsa_public_key_free (ret_denom_pubs[cnt].rsa_public_key); - GNUNET_free_non_null (ret_denom_pubs); - GNUNET_free_non_null (new_denom_pubs); - for (cnt = 0; - (NULL != new_dkp) && (cnt < MELT_NEW_COINS) && (NULL != new_dkp[cnt]); - cnt++) - destroy_denom_key_pair (new_dkp[cnt]); - GNUNET_free_non_null (new_dkp); - return ret; -} - - -/** - * Callback that should never be called. - */ -static void -cb_wt_never (void *cls, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct GNUNET_HashCode *h_wire, - const struct GNUNET_HashCode *h_contract, - uint64_t transaction_id, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *coin_value, - const struct TALER_Amount *coin_fee) -{ - GNUNET_assert (0); /* this statement should be unreachable */ -} - - -/** - * Callback that should never be called. - */ -static void -cb_wtid_never (void *cls, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *coin_fee, - struct GNUNET_TIME_Absolute execution_time) -{ - GNUNET_assert (0); -} - - -static struct TALER_MerchantPublicKeyP merchant_pub_wt; -static struct GNUNET_HashCode h_wire_wt; -static struct GNUNET_HashCode h_contract_wt; -static uint64_t transaction_id_wt; -static struct TALER_CoinSpendPublicKeyP coin_pub_wt; -static struct TALER_Amount coin_value_wt; -static struct TALER_Amount coin_fee_wt; -static struct TALER_Amount transfer_value_wt; -static struct GNUNET_TIME_Absolute execution_time_wt; -static struct TALER_WireTransferIdentifierRawP wtid_wt; - - -/** - * Callback that should be called with the WT data. - */ -static void -cb_wt_check (void *cls, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct GNUNET_HashCode *h_wire, - const struct GNUNET_HashCode *h_contract, - uint64_t transaction_id, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *coin_value, - const struct TALER_Amount *coin_fee) -{ - GNUNET_assert (cls == &cb_wt_never); - GNUNET_assert (0 == memcmp (merchant_pub, - &merchant_pub_wt, - sizeof (struct TALER_MerchantPublicKeyP))); - GNUNET_assert (0 == memcmp (h_wire, - &h_wire_wt, - sizeof (struct GNUNET_HashCode))); - GNUNET_assert (0 == memcmp (h_contract, - &h_contract_wt, - sizeof (struct GNUNET_HashCode))); - GNUNET_assert (transaction_id == transaction_id_wt); - GNUNET_assert (0 == memcmp (coin_pub, - &coin_pub_wt, - sizeof (struct TALER_CoinSpendPublicKeyP))); - GNUNET_assert (0 == TALER_amount_cmp (coin_value, - &coin_value_wt)); - GNUNET_assert (0 == TALER_amount_cmp (coin_fee, - &coin_fee_wt)); -} - - -/** - * Callback that should be called with the WT data. - */ -static void -cb_wtid_check (void *cls, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *coin_fee, - struct GNUNET_TIME_Absolute execution_time) -{ - GNUNET_assert (cls == &cb_wtid_never); - GNUNET_assert (0 == memcmp (wtid, - &wtid_wt, - sizeof (struct TALER_WireTransferIdentifierRawP))); - GNUNET_assert (execution_time.abs_value_us == - execution_time_wt.abs_value_us); - GNUNET_assert (0 == TALER_amount_cmp (coin_contribution, - &coin_value_wt)); - GNUNET_assert (0 == TALER_amount_cmp (coin_fee, - &coin_fee_wt)); -} - - -/** - * Main function that will be run by the scheduler. - * - * @param cls closure - * @param args remaining command-line arguments - * @param cfgfile name of the configuration file used (for saving, can be NULL!) - * @param cfg configuration - */ -static void -run (void *cls, - char *const *args, - const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct TALER_MINTDB_Session *session; - struct TALER_ReservePublicKeyP reserve_pub; - struct DenomKeyPair *dkp; - struct TALER_MINTDB_CollectableBlindcoin cbc; - struct TALER_MINTDB_CollectableBlindcoin cbc2; - struct TALER_MINTDB_ReserveHistory *rh; - struct TALER_MINTDB_ReserveHistory *rh_head; - struct TALER_MINTDB_BankTransfer *bt; - struct TALER_MINTDB_CollectableBlindcoin *withdraw; - struct TALER_MINTDB_Deposit deposit; - struct TALER_MINTDB_Deposit deposit2; - struct TALER_WireTransferIdentifierRawP wtid; - json_t *wire; - json_t *just; - const char * const json_wire_str = - "{ \"type\":\"SEPA\", \ -\"IBAN\":\"DE67830654080004822650\", \ -\"name\":\"GNUnet e.V.\", \ -\"bic\":\"GENODEF1SLR\", \ -\"edate\":\"1449930207000\", \ -\"r\":123456789, \ -\"address\": \"foobar\"}"; - unsigned int cnt; - - dkp = NULL; - rh = NULL; - wire = NULL; - session = NULL; - ZR_BLK (&cbc); - ZR_BLK (&cbc2); - if (NULL == - (plugin = TALER_MINTDB_plugin_load (cfg))) - { - result = 1; - return; - } - if (GNUNET_OK != - plugin->create_tables (plugin->cls, - GNUNET_YES)) - { - result = 2; - goto drop; - } - if (NULL == - (session = plugin->get_session (plugin->cls, - GNUNET_YES))) - { - result = 3; - goto drop; - } - RND_BLK (&reserve_pub); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":1.000010", - &value)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":0.000010", - &fee_withdraw)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":0.000010", - &fee_deposit)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":0.000010", - &fee_refresh)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY ":1.000010", - &amount_with_fee)); - - result = 4; - just = json_loads ("{ \"justification\":\"1\" }", 0, NULL); - FAILIF (GNUNET_OK != - plugin->reserves_in_insert (plugin->cls, - session, - &reserve_pub, - &value, - GNUNET_TIME_absolute_get (), - just)); - json_decref (just); - FAILIF (GNUNET_OK != - check_reserve (session, - &reserve_pub, - value.value, - value.fraction, - value.currency)); - just = json_loads ("{ \"justification\":\"2\" }", 0, NULL); - FAILIF (GNUNET_OK != - plugin->reserves_in_insert (plugin->cls, - session, - &reserve_pub, - &value, - GNUNET_TIME_absolute_get (), - just)); - json_decref (just); - FAILIF (GNUNET_OK != - check_reserve (session, - &reserve_pub, - value.value * 2, - value.fraction * 2, - value.currency)); - dkp = create_denom_key_pair (1024, session, - &value, - &fee_withdraw, - &fee_deposit, - &fee_refresh); - RND_BLK(&cbc.h_coin_envelope); - RND_BLK(&cbc.reserve_sig); - cbc.denom_pub = dkp->pub; - cbc.sig.rsa_signature - = GNUNET_CRYPTO_rsa_sign (dkp->priv.rsa_private_key, - &cbc.h_coin_envelope, - sizeof (cbc.h_coin_envelope)); - cbc.reserve_pub = reserve_pub; - cbc.amount_with_fee = value; - GNUNET_assert (GNUNET_OK == - TALER_amount_get_zero (CURRENCY, &cbc.withdraw_fee)); - FAILIF (GNUNET_OK != - plugin->insert_withdraw_info (plugin->cls, - session, - &cbc)); - FAILIF (GNUNET_OK != - check_reserve (session, - &reserve_pub, - value.value, - value.fraction, - value.currency)); - FAILIF (GNUNET_YES != - plugin->get_withdraw_info (plugin->cls, - session, - &cbc.h_coin_envelope, - &cbc2)); - FAILIF (NULL == cbc2.denom_pub.rsa_public_key); - FAILIF (0 != memcmp (&cbc2.reserve_sig, - &cbc.reserve_sig, - sizeof (cbc2.reserve_sig))); - FAILIF (0 != memcmp (&cbc2.reserve_pub, - &cbc.reserve_pub, - sizeof (cbc2.reserve_pub))); - FAILIF (GNUNET_OK != - GNUNET_CRYPTO_rsa_verify (&cbc.h_coin_envelope, - cbc2.sig.rsa_signature, - dkp->pub.rsa_public_key)); - rh = plugin->get_reserve_history (plugin->cls, - session, - &reserve_pub); - FAILIF (NULL == rh); - rh_head = rh; - for (cnt=0; NULL != rh_head; rh_head=rh_head->next, cnt++) - { - switch (rh_head->type) - { - case TALER_MINTDB_RO_BANK_TO_MINT: - bt = rh_head->details.bank; - FAILIF (0 != memcmp (&bt->reserve_pub, - &reserve_pub, - sizeof (reserve_pub))); - /* this is the amount we trasferred twice*/ - FAILIF (1 != bt->amount.value); - FAILIF (10 != bt->amount.fraction); - FAILIF (0 != strcmp (CURRENCY, bt->amount.currency)); - FAILIF (NULL == bt->wire); - break; - case TALER_MINTDB_RO_WITHDRAW_COIN: - withdraw = rh_head->details.withdraw; - FAILIF (0 != memcmp (&withdraw->reserve_pub, - &reserve_pub, - sizeof (reserve_pub))); - FAILIF (0 != memcmp (&withdraw->h_coin_envelope, - &cbc.h_coin_envelope, - sizeof (cbc.h_coin_envelope))); - break; - } - } - FAILIF (3 != cnt); - /* Tests for deposits */ - memset (&deposit, 0, sizeof (deposit)); - RND_BLK (&deposit.coin.coin_pub); - deposit.coin.denom_pub = dkp->pub; - deposit.coin.denom_sig = cbc.sig; - RND_BLK (&deposit.csig); - RND_BLK (&deposit.merchant_pub); - RND_BLK (&deposit.h_contract); - RND_BLK (&deposit.h_wire); - wire = json_loads (json_wire_str, 0, NULL); - deposit.wire = wire; - deposit.transaction_id = - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); - deposit.amount_with_fee = value; - GNUNET_assert (GNUNET_OK == - TALER_amount_get_zero (CURRENCY, &deposit.deposit_fee)); - FAILIF (GNUNET_OK != - plugin->insert_deposit (plugin->cls, - session, &deposit)); - FAILIF (GNUNET_YES != - plugin->have_deposit (plugin->cls, - session, - &deposit)); - deposit2 = deposit; - deposit2.transaction_id++; /* should fail if transaction id is different */ - FAILIF (GNUNET_NO != - plugin->have_deposit (plugin->cls, - session, - &deposit2)); - deposit2.transaction_id = deposit.transaction_id; - RND_BLK (&deposit2.merchant_pub); /* should fail if merchant is different */ - FAILIF (GNUNET_NO != - plugin->have_deposit (plugin->cls, - session, - &deposit2)); - deposit2.merchant_pub = deposit.merchant_pub; - RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ - FAILIF (GNUNET_NO != - plugin->have_deposit (plugin->cls, - session, - &deposit2)); - FAILIF (GNUNET_OK != test_melting (session)); - - /* setup values for wire transfer aggregation data */ - memset (&wtid, 42, sizeof (wtid)); - memset (&merchant_pub_wt, 43, sizeof (merchant_pub_wt)); - memset (&h_wire_wt, 44, sizeof (h_wire_wt)); - memset (&h_contract_wt, 45, sizeof (h_contract_wt)); - memset (&coin_pub_wt, 46, sizeof (coin_pub_wt)); - transaction_id_wt = 47; - execution_time_wt = GNUNET_TIME_absolute_get (); - memset (&merchant_pub_wt, 48, sizeof (merchant_pub_wt)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY "KUDOS:1.000010", - &coin_value_wt)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY "KUDOS:0.000010", - &coin_fee_wt)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (CURRENCY "KUDOS:1.000000", - &transfer_value_wt)); - - FAILIF (GNUNET_NO != - plugin->lookup_wire_transfer (plugin->cls, - session, - &wtid_wt, - &cb_wt_never, - NULL)); - FAILIF (GNUNET_NO != - plugin->wire_lookup_deposit_wtid (plugin->cls, - session, - &h_contract_wt, - &h_wire_wt, - &coin_pub_wt, - &merchant_pub_wt, - transaction_id_wt, - &cb_wtid_never, - NULL)); - /* insert WT data */ - FAILIF (GNUNET_OK != - plugin->insert_aggregation_tracking (plugin->cls, - session, - &wtid_wt, - &merchant_pub_wt, - &h_wire_wt, - &h_contract_wt, - transaction_id_wt, - execution_time_wt, - &coin_pub_wt, - &coin_value_wt, - &coin_fee_wt)); - FAILIF (GNUNET_OK != - plugin->lookup_wire_transfer (plugin->cls, - session, - &wtid_wt, - &cb_wt_check, - &cb_wt_never)); - FAILIF (GNUNET_OK != - plugin->wire_lookup_deposit_wtid (plugin->cls, - session, - &h_contract_wt, - &h_wire_wt, - &coin_pub_wt, - &merchant_pub_wt, - transaction_id_wt, - &cb_wtid_check, - &cb_wtid_never)); - result = 0; - - drop: - if (NULL != wire) - json_decref (wire); - if (NULL != rh) - plugin->free_reserve_history (plugin->cls, - rh); - rh = NULL; - if (NULL != session) - GNUNET_break (GNUNET_OK == - plugin->drop_temporary (plugin->cls, - session)); - if (NULL != dkp) - destroy_denom_key_pair (dkp); - if (NULL != cbc.sig.rsa_signature) - GNUNET_CRYPTO_rsa_signature_free (cbc.sig.rsa_signature); - if (NULL != cbc2.denom_pub.rsa_public_key) - GNUNET_CRYPTO_rsa_public_key_free (cbc2.denom_pub.rsa_public_key); - if (NULL != cbc2.sig.rsa_signature) - GNUNET_CRYPTO_rsa_signature_free (cbc2.sig.rsa_signature); - dkp = NULL; - TALER_MINTDB_plugin_unload (plugin); - plugin = NULL; -} - - -int -main (int argc, - char *const argv[]) -{ - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - char *argv2[] = { - "test-mint-db-<plugin_name>", /* will be replaced later */ - "-c", "test-mint-db-<plugin_name>.conf", /* will be replaced later */ - NULL, - }; - const char *plugin_name; - char *config_filename; - char *testname; - - result = -1; - if (NULL == (plugin_name = strrchr (argv[0], (int) '-'))) - { - GNUNET_break (0); - return -1; - } - plugin_name++; - (void) GNUNET_asprintf (&testname, - "test-mint-db-%s", plugin_name); - (void) GNUNET_asprintf (&config_filename, - "%s.conf", testname); - argv2[0] = argv[0]; - argv2[2] = config_filename; - if (GNUNET_OK != - GNUNET_PROGRAM_run ((sizeof (argv2)/sizeof (char *)) - 1, argv2, - testname, - "Test cases for mint database helper functions.", - options, &run, NULL)) - { - GNUNET_free (config_filename); - GNUNET_free (testname); - return 3; - } - GNUNET_free (config_filename); - GNUNET_free (testname); - return result; -} diff --git a/src/mintdb/test_mintdb_deposits.c b/src/mintdb/test_mintdb_deposits.c deleted file mode 100644 index 3ce0a35a5..000000000 --- a/src/mintdb/test_mintdb_deposits.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file mint/test_mint_deposits.c - * @brief testcase for mint deposits - * @author Sree Harsha Totakura <sreeharsha@totakura.in> - */ -#include "platform.h" -#include <libpq-fe.h> -#include <gnunet/gnunet_util_lib.h> -#include "taler_pq_lib.h" -#include "taler_mintdb_lib.h" -#include "taler_mintdb_plugin.h" - -#define MINT_CURRENCY "EUR" - -#define DB_URI "postgres:///taler" - -#define break_db_err(result) do { \ - GNUNET_break(0); \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Database failure: %s\n", PQresultErrorMessage (result)); \ - } while (0) - -/** - * Shorthand for exit jumps. - */ -#define EXITIF(cond) \ - do { \ - if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ - } while (0) - - -/** - * Should we not interact with a temporary table? - */ -static int persistent; - -/** - * Testcase result - */ -static int result; - -/** - * The plugin. - */ -static struct TALER_MINTDB_Plugin *plugin; - -/** - * Main function that will be run by the scheduler. - * - * @param cls closure - * @param args remaining command-line arguments - * @param cfgfile name of the configuration file used (for saving, can be NULL!) - * @param cfg configuration - */ -static void -run (void *cls, - char *const *args, - const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - static const char wire[] = "{" - "\"type\":\"SEPA\"," - "\"IBAN\":\"DE67830654080004822650\"," - "\"NAME\":\"GNUNET E.V\"," - "\"BIC\":\"GENODEF1SRL\"" - "}"; - struct TALER_MINTDB_Deposit *deposit; - uint64_t transaction_id; - struct TALER_MINTDB_Session *session; - - deposit = NULL; - EXITIF (NULL == (plugin = TALER_MINTDB_plugin_load (cfg))); - EXITIF (GNUNET_OK != - plugin->create_tables (plugin->cls, - ! persistent)); - session = plugin->get_session (plugin->cls, - ! persistent); - EXITIF (NULL == session); - deposit = GNUNET_malloc (sizeof (struct TALER_MINTDB_Deposit) + sizeof (wire)); - /* Makeup a random coin public key */ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - deposit, - sizeof (struct TALER_MINTDB_Deposit)); - /* Makeup a random 64bit transaction ID */ - transaction_id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT64_MAX); - deposit->transaction_id = GNUNET_htonll (transaction_id); - /* Random amount */ - deposit->amount_with_fee.value = - htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX)); - deposit->amount_with_fee.fraction = - htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX)); - GNUNET_assert (strlen (MINT_CURRENCY) < sizeof (deposit->amount_with_fee.currency)); - strcpy (deposit->amount_with_fee.currency, MINT_CURRENCY); - /* Copy wireformat */ - deposit->wire = json_loads (wire, 0, NULL); - EXITIF (GNUNET_OK != - plugin->insert_deposit (plugin->cls, - session, - deposit)); - EXITIF (GNUNET_OK != - plugin->have_deposit (plugin->cls, - session, - deposit)); - result = GNUNET_OK; - - EXITIF_exit: - GNUNET_free_non_null (deposit); - if (NULL != plugin) - { - TALER_MINTDB_plugin_unload (plugin); - plugin = NULL; - } -} - - -int -main (int argc, - char *const argv[]) -{ - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'T', "persist", NULL, - gettext_noop ("Use a persistent database table instead of a temporary one"), - GNUNET_NO, &GNUNET_GETOPT_set_one, &persistent}, - GNUNET_GETOPT_OPTION_END - }; - - - persistent = GNUNET_NO; - result = GNUNET_SYSERR; - if (GNUNET_OK != - GNUNET_PROGRAM_run (argc, argv, - "test-mint-deposits", - "testcase for mint deposits", - options, &run, NULL)) - return 3; - return (GNUNET_OK == result) ? 0 : 1; -} diff --git a/src/mintdb/test_mintdb_keyio.c b/src/mintdb/test_mintdb_keyio.c deleted file mode 100644 index aa1ba2f20..000000000 --- a/src/mintdb/test_mintdb_keyio.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014 GNUnet e. V. (and other contributing authors) - - 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, If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file mint/test_mint_common.c - * @brief test cases for some functions in mint/mint_common.c - * @author Sree Harsha Totakura <sreeharsha@totakura.in> - */ -#include "platform.h" -#include "gnunet/gnunet_util_lib.h" -#include "taler_signatures.h" -#include "taler_mintdb_lib.h" - -#define RSA_KEY_SIZE 1024 - - -#define EXITIF(cond) \ - do { \ - if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ - } while (0) - - -int -main (int argc, - const char *const argv[]) -{ - struct TALER_MINTDB_DenominationKeyIssueInformation dki; - char *enc; - size_t enc_size; - struct TALER_MINTDB_DenominationKeyIssueInformation dki_read; - char *enc_read; - size_t enc_read_size; - char *tmpfile; - int ret; - - ret = 1; - enc = NULL; - enc_read = NULL; - tmpfile = NULL; - dki.denom_priv.rsa_private_key = NULL; - dki_read.denom_priv.rsa_private_key = NULL; - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - &dki.issue.signature, - sizeof (struct TALER_MasterSignatureP)); - dki.denom_priv.rsa_private_key - = GNUNET_CRYPTO_rsa_private_key_create (RSA_KEY_SIZE); - enc_size = GNUNET_CRYPTO_rsa_private_key_encode (dki.denom_priv.rsa_private_key, - &enc); - EXITIF (NULL == (tmpfile = GNUNET_DISK_mktemp ("test_mint_common"))); - EXITIF (GNUNET_OK != TALER_MINTDB_denomination_key_write (tmpfile, &dki)); - EXITIF (GNUNET_OK != TALER_MINTDB_denomination_key_read (tmpfile, &dki_read)); - enc_read_size = GNUNET_CRYPTO_rsa_private_key_encode (dki_read.denom_priv.rsa_private_key, - &enc_read); - EXITIF (enc_size != enc_read_size); - EXITIF (0 != memcmp (enc, - enc_read, - enc_size)); - ret = 0; - - EXITIF_exit: - GNUNET_free_non_null (enc); - if (NULL != tmpfile) - { - (void) unlink (tmpfile); - GNUNET_free (tmpfile); - } - GNUNET_free_non_null (enc_read); - if (NULL != dki.denom_priv.rsa_private_key) - GNUNET_CRYPTO_rsa_private_key_free (dki.denom_priv.rsa_private_key); - if (NULL != dki_read.denom_priv.rsa_private_key) - GNUNET_CRYPTO_rsa_private_key_free (dki_read.denom_priv.rsa_private_key); - return ret; -} diff --git a/src/mintdb/test_perf_taler_mintdb.c b/src/mintdb/test_perf_taler_mintdb.c deleted file mode 100644 index 789a0dd4f..000000000 --- a/src/mintdb/test_perf_taler_mintdb.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see <http://www.gnu.org/licenses/> - */ -/** - * @file mintdb/test_perf_taler_mintdb.c - * @brief Mint database performance analysis - * @author Nicolas Fournier - */ -#include "platform.h" -#include "perf_taler_mintdb_interpreter.h" -#include "perf_taler_mintdb_init.h" - - -#define NB_DENOMINATION_INIT 2 -#define NB_DENOMINATION_SAVE 2 - -#define NB_RESERVE_INIT 4 -#define NB_RESERVE_SAVE 1 - -#define NB_DEPOSIT_INIT 1 -#define NB_DEPOSIT_SAVE 1 - -#define NB_WITHDRAW_INIT 1 -#define NB_WITHDRAW_SAVE 1 - -/** - * Allocate, copies and free all the data used in the interpreter - * Used to check for memory leaks - */ -static void -test_allocate () -{ - struct TALER_MINTDB_DenominationKeyIssueInformation *dki, *dki_copy; - struct PERF_TALER_MINTDB_Reserve *reserve, *reserve_copy; - struct PERF_TALER_MINTDB_Coin *coin, *coin_copy; - struct TALER_MINTDB_Deposit *deposit, *deposit_copy; - - dki = PERF_TALER_MINTDB_denomination_init (); - reserve = PERF_TALER_MINTDB_reserve_init (); - coin = PERF_TALER_MINTDB_coin_init (dki, - reserve); - deposit = PERF_TALER_MINTDB_deposit_init (coin); - - dki_copy = PERF_TALER_MINTDB_denomination_copy (dki); - reserve_copy = PERF_TALER_MINTDB_reserve_copy (reserve); - coin_copy = PERF_TALER_MINTDB_coin_copy (coin); - deposit_copy = PERF_TALER_MINTDB_deposit_copy (deposit); - - PERF_TALER_MINTDB_denomination_free (dki); - PERF_TALER_MINTDB_denomination_free (dki_copy); - PERF_TALER_MINTDB_reserve_free (reserve); - PERF_TALER_MINTDB_reserve_free (reserve_copy); - PERF_TALER_MINTDB_coin_free (coin); - PERF_TALER_MINTDB_coin_free (coin_copy); - PERF_TALER_MINTDB_deposit_free (deposit); - PERF_TALER_MINTDB_deposit_free (deposit_copy); -} - -/** - * Runs the performances tests for the mint database - * and logs the results using Gauger - */ -int -main (int argc, char ** argv) -{ - int ret = 0; - struct PERF_TALER_MINTDB_Cmd init[] = - { - PERF_TALER_MINTDB_INIT_CMD_END ("init") - }; - struct PERF_TALER_MINTDB_Cmd benchmark[] = - { - // Denomination used to create coins - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("00 - Start of interpreter"), - - PERF_TALER_MINTDB_INIT_CMD_LOOP ("01 - denomination loop", - NB_DENOMINATION_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION ("01 - start transaction"), - PERF_TALER_MINTDB_INIT_CMD_CREATE_DENOMINATION ("01 - denomination"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_DENOMINATION ("01 - insert", - "01 - denomination"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION ("01 - commit transaction"), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("01 - save denomination", - "01 - denomination loop", - "01 - denomination", - NB_DENOMINATION_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("01 - denomination loop end", - "01 - denomination loop"), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("01 - init denomination complete"), - // End of initialization - // Reserve initialization - PERF_TALER_MINTDB_INIT_CMD_LOOP ("02 - init reserve loop", - NB_RESERVE_INIT), - - PERF_TALER_MINTDB_INIT_CMD_CREATE_RESERVE ("02 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_RESERVE ("02 - insert", - "02 - reserve"), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("02 - save reserve", - "02 - init reserve loop", - "02 - reserve", - NB_RESERVE_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("02 - init reserve end loop", - "02 - init reserve loop"), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("02 - reserve init complete"), - // End reserve init - // Withdrawal initialization - PERF_TALER_MINTDB_INIT_CMD_LOOP ("03 - init withdraw loop", - NB_WITHDRAW_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION ("03 - start transaction"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("03 - denomination load", - "03 - init withdraw loop", - "01 - save denomination"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("03 - reserve load", - "03 - init withdraw loop", - "02 - save reserve"), - PERF_TALER_MINTDB_INIT_CMD_CREATE_WITHDRAW ("03 - withdraw", - "03 - denomination load", - "03 - reserve load"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_WITHDRAW ("03 - insert withdraw", - "03 - withdraw"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION ("03 - commit transaction"), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("03 - coin array", - "03 - init withdraw loop", - "03 - withdraw", - NB_WITHDRAW_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("03 - withdraw init end loop", - "03 - init withdraw loop"), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("03 - withdraw init complete"), - //End of withdrawal initialization - //Deposit initialization - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("04 - time start"), - PERF_TALER_MINTDB_INIT_CMD_LOOP ("04 - deposit init loop", - NB_DEPOSIT_INIT), - PERF_TALER_MINTDB_INIT_CMD_START_TRANSACTION ("04 - start transaction"), - PERF_TALER_MINTDB_INIT_CMD_LOAD_ARRAY ("04 - coin load", - "04 - deposit init loop", - "03 - coin array"), - PERF_TALER_MINTDB_INIT_CMD_CREATE_DEPOSIT ("04 - deposit", - "04 - coin load"), - PERF_TALER_MINTDB_INIT_CMD_INSERT_DEPOSIT ("04 - insert deposit", - "04 - deposit"), - PERF_TALER_MINTDB_INIT_CMD_COMMIT_TRANSACTION ("04 - commit transaction"), - PERF_TALER_MINTDB_INIT_CMD_SAVE_ARRAY ("04 - deposit array", - "04 - deposit init loop", - "04 - deposit", - NB_DEPOSIT_SAVE), - PERF_TALER_MINTDB_INIT_CMD_END_LOOP ("04 - deposit init loop end", - "04 - deposit init loop"), - PERF_TALER_MINTDB_INIT_CMD_GET_TIME ("04 - time stop"), - PERF_TALER_MINTDB_INIT_CMD_GAUGER ("04 - gauger", - "04 - time start", - "04 - time stop", - "TEST", - "time to insert a deposit", - "deposit/sec", - NB_DEPOSIT_SAVE), - PERF_TALER_MINTDB_INIT_CMD_DEBUG ("04 - deposit init complete"), - // End of deposit initialization - PERF_TALER_MINTDB_INIT_CMD_END ("end"), - }; - - test_allocate (); - ret = PERF_TALER_MINTDB_run_benchmark ("test-perf-taler-mintdb", - "./test-mint-db-postgres.conf", - init, - benchmark); - if (GNUNET_SYSERR == ret) - return 1; - return 0; -} |