summaryrefslogtreecommitdiff
path: root/src/mint/mint_db.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-03-20 23:51:28 +0100
committerChristian Grothoff <christian@grothoff.org>2015-03-20 23:51:28 +0100
commit7d9a40327587ed99fb20f4c4a5669069c7a51e48 (patch)
tree40ed8371340ef3d36269e0c9d23c4daae23fb039 /src/mint/mint_db.c
parent0414fb51a9f219c37afc06ad2b309711e360c485 (diff)
downloadexchange-7d9a40327587ed99fb20f4c4a5669069c7a51e48.tar.gz
exchange-7d9a40327587ed99fb20f4c4a5669069c7a51e48.tar.bz2
exchange-7d9a40327587ed99fb20f4c4a5669069c7a51e48.zip
first stab at establishing proper plugin API, main HTTP code compiles, other binaries FTBFS right now
Diffstat (limited to 'src/mint/mint_db.c')
-rw-r--r--src/mint/mint_db.c2241
1 files changed, 0 insertions, 2241 deletions
diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c
deleted file mode 100644
index 6832cdac9..000000000
--- a/src/mint/mint_db.c
+++ /dev/null
@@ -1,2241 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 Christian Grothoff (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_db.c
- * @brief Low-level (statement-level) database access for the mint
- * @author Florian Dold
- * @author Christian Grothoff
- * @author Sree Harsha Totakura
- *
- * TODO:
- * - The mint_db.h-API should ideally be what we need to port
- * when using other databases; so here we should enable
- * alternative implementations by returning
- * a more opaque DB handle.
- */
-#include "platform.h"
-#include "db_pq.h"
-#include "taler_signatures.h"
-#include "taler-mint-httpd_responses.h"
-#include "mint_db.h"
-#include <pthread.h>
-
-
-/**
- * Thread-local database connection.
- * Contains a pointer to PGconn or NULL.
- */
-static pthread_key_t db_conn_threadlocal;
-
-
-#define QUERY_ERR(result) \
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Query failed at %s:%u: %s\n", __FILE__, __LINE__, PQresultErrorMessage (result))
-
-/**
- * Database connection string, as read from
- * the configuration.
- */
-static char *TALER_MINT_db_connection_cfg_str;
-
-#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)
-
-
-#define SQLEXEC_(conn, sql, result) \
- do { \
- result = PQexec (conn, sql); \
- if (PGRES_COMMAND_OK != PQresultStatus (result)) \
- { \
- BREAK_DB_ERR (result); \
- PQclear (result); result = NULL; \
- goto SQLEXEC_fail; \
- } \
- PQclear (result); result = NULL; \
- } while (0)
-
-/**
- * This the length of the currency strings (without 0-termination) we use. Note
- * that we need to use this at the DB layer instead of TALER_CURRENCY_LEN as the
- * DB only needs to store 3 bytes instead of 8 bytes.
- */
-#define TALER_DB_CURRENCY_LEN 3
-
-/**
- * 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)
-{
- PGresult *result;
-
- SQLEXEC_(db,
- "CREATE SCHEMA IF NOT EXISTS " TALER_TEMP_SCHEMA_NAME ";"
- "SET search_path to " TALER_TEMP_SCHEMA_NAME ";",
- result);
- return GNUNET_OK;
- SQLEXEC_fail:
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Drop the temporary taler schema. This is only useful for testcases
- *
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-int
-TALER_MINT_DB_drop_temporary (PGconn *db)
-{
- PGresult *result;
-
- SQLEXEC_ (db,
- "DROP SCHEMA " TALER_TEMP_SCHEMA_NAME " CASCADE;",
- result);
- return GNUNET_OK;
- SQLEXEC_fail:
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Create the necessary tables if they are not present
- *
- * @param temporary should we use a temporary schema
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-int
-TALER_MINT_DB_create_tables (int temporary)
-{
- PGresult *result;
- PGconn *conn;
-
- result = NULL;
- conn = PQconnectdb (TALER_MINT_db_connection_cfg_str);
- if (CONNECTION_OK != PQstatus (conn))
- {
- LOG_ERROR ("Database connection failed: %s\n",
- PQerrorMessage (conn));
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if ((GNUNET_YES == temporary)
- && (GNUNET_SYSERR == set_temporary_schema (conn)))
- {
- PQfinish (conn);
- return GNUNET_SYSERR;
- }
-#define SQLEXEC(sql) SQLEXEC_(conn, sql, result);
- /* reserves table is for summarization of a reserve. It is updated when new
- funds are added and existing funds are withdrawn */
- SQLEXEC ("CREATE TABLE IF NOT EXISTS reserves"
- "("
- " reserve_pub BYTEA PRIMARY KEY"
- ",current_balance_value INT4 NOT NULL"
- ",current_balance_fraction INT4 NOT NULL"
- ",balance_currency VARCHAR(4) NOT NULL"
- ",expiration_date INT8 NOT NULL"
- ")");
- /* reserves_in table collects the transactions which transfer funds into the
- reserve. The amount and expiration date for the corresponding reserve are
- updated when new transfer funds are added. 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_value INT4 NOT NULL"
- ",balance_fraction INT4 NOT NULL"
- ",balance_currency VARCHAR(4) NOT NULL"
- ",expiration_date INT8 NOT NULL"
- ");");
- /* Create an index on the foreign key as it is not created automatically by PSQL */
- SQLEXEC ("CREATE INDEX reserves_in_reserve_pub_index"
- " ON reserves_in (reserve_pub);");
- SQLEXEC ("CREATE TABLE IF NOT EXISTS collectable_blindcoins"
- "("
- "blind_ev BYTEA PRIMARY KEY"
- ",denom_pub BYTEA NOT NULL" /* FIXME: Make this a foreign key? */
- ",denom_sig BYTEA NOT NULL"
- ",reserve_pub BYTEA REFERENCES reserves (reserve_pub) ON DELETE CASCADE"
- ",reserve_sig BYTEA NOT NULL"
- ");");
- SQLEXEC ("CREATE INDEX collectable_blindcoins_reserve_pub_index ON"
- " collectable_blindcoins (reserve_pub)");
- SQLEXEC("CREATE TABLE IF NOT EXISTS known_coins "
- "("
- " coin_pub BYTEA NOT NULL PRIMARY KEY"
- ",denom_pub BYTEA NOT NULL"
- ",denom_sig BYTEA NOT NULL"
- ",expended_value INT4 NOT NULL"
- ",expended_fraction INT4 NOT NULL"
- ",expended_currency VARCHAR(4) NOT NULL"
- ",refresh_session_pub BYTEA"
- ")");
- SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_sessions "
- "("
- " session_pub BYTEA PRIMARY KEY CHECK (length(session_pub) = 32)"
- ",session_melt_sig BYTEA"
- ",session_commit_sig BYTEA"
- ",noreveal_index INT2 NOT NULL"
- // non-zero if all reveals were ok
- // and the new coin signatures are ready
- ",reveal_ok BOOLEAN NOT NULL DEFAULT false"
- ") ");
- SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_order "
- "( "
- " session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub)"
- ",newcoin_index INT2 NOT NULL "
- ",denom_pub BYTEA NOT NULL "
- ",PRIMARY KEY (session_pub, newcoin_index)"
- ") ");
- SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_link"
- "("
- " session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub)"
- ",transfer_pub BYTEA NOT NULL"
- ",link_secret_enc BYTEA NOT NULL"
- // index of the old coin in the customer's request
- ",oldcoin_index INT2 NOT NULL"
- // index for cut and choose,
- // ranges from 0 to kappa-1
- ",cnc_index INT2 NOT NULL"
- ")");
- SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_coin"
- "("
- " session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub) "
- ",link_vector_enc BYTEA NOT NULL"
- // index of the new coin in the customer's request
- ",newcoin_index INT2 NOT NULL"
- // index for cut and choose,
- ",cnc_index INT2 NOT NULL"
- ",coin_ev BYTEA NOT NULL"
- ")");
- SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_melt"
- "("
- " session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub) "
- ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) "
- ",denom_pub BYTEA NOT NULL "
- ",oldcoin_index INT2 NOT NULL"
- ")");
- SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_collectable"
- "("
- " session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub) "
- ",ev_sig BYTEA NOT NULL"
- ",newcoin_index INT2 NOT NULL"
- ")");
- SQLEXEC("CREATE TABLE IF NOT EXISTS deposits "
- "( "
- " coin_pub BYTEA NOT NULL PRIMARY KEY CHECK (length(coin_pub)=32)"
- ",denom_pub BYTEA NOT NULL" /* FIXME: Link this as a foreign key? */
- ",denom_sig BYTEA NOT NULL"
- ",transaction_id INT8 NOT NULL"
- ",amount_currency VARCHAR(4) NOT NULL"
- ",amount_value INT4 NOT NULL"
- ",amount_fraction INT4 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"
- ")");
-#undef SQLEXEC
- 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
- */
-int
-TALER_MINT_DB_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);
-
- PREPARE ("get_reserve",
- "SELECT "
- "current_balance_value"
- ",current_balance_fraction"
- ",balance_currency "
- ",expiration_date "
- "FROM reserves "
- "WHERE reserve_pub=$1 "
- "LIMIT 1; ",
- 1, NULL);
- PREPARE ("create_reserve",
- "INSERT INTO reserves ("
- " reserve_pub,"
- " current_balance_value,"
- " current_balance_fraction,"
- " balance_currency,"
- " expiration_date) VALUES ("
- "$1, $2, $3, $4, $5);",
- 5, NULL);
- PREPARE ("update_reserve",
- "UPDATE reserves "
- "SET"
- " current_balance_value=$2 "
- ",current_balance_fraction=$3 "
- ",expiration_date=$4 "
- "WHERE reserve_pub=$1 ",
- 4, NULL);
- PREPARE ("create_reserves_in_transaction",
- "INSERT INTO reserves_in ("
- " reserve_pub,"
- " balance_value,"
- " balance_fraction,"
- " balance_currency,"
- " expiration_date) VALUES ("
- " $1, $2, $3, $4, $5);",
- 5, NULL);
- PREPARE ("get_reserves_in_transactions",
- "SELECT"
- " balance_value"
- ",balance_fraction"
- ",balance_currency"
- ",expiration_date"
- " FROM reserves_in WHERE reserve_pub=$1",
- 1, NULL);
- PREPARE ("insert_collectable_blindcoin",
- "INSERT INTO collectable_blindcoins ( "
- " blind_ev"
- ",denom_pub, denom_sig"
- ",reserve_pub, reserve_sig) "
- "VALUES ($1, $2, $3, $4, $5)",
- 5, NULL);
- PREPARE ("get_collectable_blindcoin",
- "SELECT "
- " denom_pub, denom_sig"
- ",reserve_sig, reserve_pub "
- "FROM collectable_blindcoins "
- "WHERE blind_ev = $1",
- 1, NULL);
- PREPARE ("get_reserves_blindcoins",
- "select"
- " blind_ev"
- ",denom_pub, denom_sig"
- ",reserve_sig"
- " FROM collectable_blindcoins"
- " WHERE reserve_pub=$1;",
- 1, NULL);
-
- /* FIXME: does it make sense to store these computed values in the DB? */
-#if 0
- PREPARE ("get_refresh_session",
- "SELECT "
- " (SELECT count(*) FROM refresh_melt WHERE session_pub = $1)::INT2 as num_oldcoins "
- ",(SELECT count(*) FROM refresh_blind_session_keys "
- " WHERE session_pub = $1 and cnc_index = 0)::INT2 as num_newcoins "
- ",(SELECT count(*) FROM refresh_blind_session_keys "
- " WHERE session_pub = $1 and newcoin_index = 0)::INT2 as kappa "
- ",noreveal_index"
- ",session_commit_sig "
- ",reveal_ok "
- "FROM refresh_sessions "
- "WHERE session_pub = $1",
- 1, NULL);
-#endif
-
- PREPARE ("get_known_coin",
- "SELECT "
- " coin_pub, denom_pub, denom_sig "
- ",expended_value, expended_fraction, expended_currency "
- ",refresh_session_pub "
- "FROM known_coins "
- "WHERE coin_pub = $1",
- 1, NULL);
- PREPARE ("update_known_coin",
- "UPDATE known_coins "
- "SET "
- " denom_pub = $2 "
- ",denom_sig = $3 "
- ",expended_value = $4 "
- ",expended_fraction = $5 "
- ",expended_currency = $6 "
- ",refresh_session_pub = $7 "
- "WHERE "
- " coin_pub = $1 ",
- 7, NULL);
- PREPARE ("insert_known_coin",
- "INSERT INTO known_coins ("
- " coin_pub"
- ",denom_pub"
- ",denom_sig"
- ",expended_value"
- ",expended_fraction"
- ",expended_currency"
- ",refresh_session_pub"
- ")"
- "VALUES ($1,$2,$3,$4,$5,$6,$7)",
- 7, NULL);
- PREPARE ("get_refresh_commit_link",
- "SELECT "
- " transfer_pub "
- ",link_secret_enc "
- "FROM refresh_commit_link "
- "WHERE session_pub = $1 AND cnc_index = $2 AND oldcoin_index = $3",
- 3, NULL);
- PREPARE ("get_refresh_commit_coin",
- "SELECT "
- " link_vector_enc "
- ",coin_ev "
- "FROM refresh_commit_coin "
- "WHERE session_pub = $1 AND cnc_index = $2 AND newcoin_index = $3",
- 3, NULL);
- PREPARE ("insert_refresh_order",
- "INSERT INTO refresh_order ( "
- " newcoin_index "
- ",session_pub "
- ",denom_pub "
- ") "
- "VALUES ($1, $2, $3) ",
- 3, NULL);
- PREPARE ("insert_refresh_melt",
- "INSERT INTO refresh_melt ( "
- " session_pub "
- ",oldcoin_index "
- ",coin_pub "
- ",denom_pub "
- ") "
- "VALUES ($1, $2, $3, $4) ",
- 3, NULL);
- PREPARE ("get_refresh_order",
- "SELECT denom_pub "
- "FROM refresh_order "
- "WHERE session_pub = $1 AND newcoin_index = $2",
- 2, NULL);
- PREPARE ("get_refresh_collectable",
- "SELECT ev_sig "
- "FROM refresh_collectable "
- "WHERE session_pub = $1 AND newcoin_index = $2",
- 2, NULL);
- PREPARE ("get_refresh_melt",
- "SELECT coin_pub "
- "FROM refresh_melt "
- "WHERE session_pub = $1 AND oldcoin_index = $2",
- 2, NULL);
- PREPARE ("insert_refresh_session",
- "INSERT INTO refresh_sessions ( "
- " session_pub "
- ",noreveal_index "
- ") "
- "VALUES ($1, $2) ",
- 2, NULL);
- PREPARE ("insert_refresh_commit_link",
- "INSERT INTO refresh_commit_link ( "
- " session_pub "
- ",transfer_pub "
- ",cnc_index "
- ",oldcoin_index "
- ",link_secret_enc "
- ") "
- "VALUES ($1, $2, $3, $4, $5) ",
- 5, NULL);
- PREPARE ("insert_refresh_commit_coin",
- "INSERT INTO refresh_commit_coin ( "
- " session_pub "
- ",coin_ev "
- ",cnc_index "
- ",newcoin_index "
- ",link_vector_enc "
- ") "
- "VALUES ($1, $2, $3, $4, $5) ",
- 5, NULL);
- PREPARE ("insert_refresh_collectable",
- "INSERT INTO refresh_collectable ( "
- " session_pub "
- ",newcoin_index "
- ",ev_sig "
- ") "
- "VALUES ($1, $2, $3) ",
- 3, NULL);
- PREPARE ("set_reveal_ok",
- "UPDATE refresh_sessions "
- "SET reveal_ok = TRUE "
- "WHERE session_pub = $1 ",
- 1, NULL);
- PREPARE ("get_link",
- "SELECT link_vector_enc, ro.denom_pub, ev_sig "
- "FROM refresh_melt rm "
- " JOIN refresh_order ro USING (session_pub) "
- " JOIN refresh_commit_coin rcc USING (session_pub) "
- " JOIN refresh_sessions rs USING (session_pub) "
- " JOIN refresh_collectable rc USING (session_pub) "
- "WHERE rm.coin_pub = $1 "
- "AND ro.newcoin_index = rcc.newcoin_index "
- "AND ro.newcoin_index = rc.newcoin_index "
- "AND rcc.cnc_index = rs.noreveal_index % ( "
- " SELECT count(*) FROM refresh_commit_coin rcc2 "
- " WHERE rcc2.newcoin_index = 0 AND rcc2.session_pub = rs.session_pub "
- " ) ",
- 1, NULL);
- PREPARE ("get_transfer",
- "SELECT transfer_pub, link_secret_enc "
- "FROM refresh_melt rm "
- " JOIN refresh_commit_link rcl USING (session_pub) "
- " JOIN refresh_sessions rs USING (session_pub) "
- "WHERE rm.coin_pub = $1 "
- "AND rm.oldcoin_index = rcl.oldcoin_index "
- "AND rcl.cnc_index = rs.noreveal_index % ( "
- " SELECT count(*) FROM refresh_commit_coin rcc2 "
- " WHERE newcoin_index = 0 AND rcc2.session_pub = rm.session_pub "
- " ) ",
- 1, NULL);
- PREPARE ("insert_deposit",
- "INSERT INTO deposits ("
- "coin_pub,"
- "denom_pub,"
- "denom_sig,"
- "transaction_id,"
- "amount_value,"
- "amount_fraction,"
- "amount_currency,"
- "merchant_pub,"
- "h_contract,"
- "h_wire,"
- "coin_sig,"
- "wire"
- ") VALUES ("
- "$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12"
- ")",
- 12, NULL);
- PREPARE ("get_deposit",
- "SELECT "
- "coin_pub,"
- "denom_pub,"
- "transaction_id,"
- "amount_value,"
- "amount_fraction,"
- "amount_currency,"
- "merchant_pub,"
- "h_contract,"
- "h_wire,"
- "coin_sig"
- " FROM deposits WHERE ("
- "(coin_pub = $1) AND"
- "(transaction_id = $2) AND"
- "(merchant_pub = $3)"
- ")",
- 3, NULL);
- return GNUNET_OK;
-#undef PREPARE
-}
-
-
-/**
- * Close thread-local database connection when a thread is destroyed.
- *
- * @param closure we get from pthreads (the db handle)
- */
-static void
-db_conn_destroy (void *cls)
-{
- PGconn *db_conn = cls;
-
- if (NULL != db_conn)
- PQfinish (db_conn);
-}
-
-
-/**
- * Initialize database subsystem.
- *
- * @param connection_cfg configuration to use to talk to DB
- * @return #GNUNET_OK on success
- */
-int
-TALER_MINT_DB_init (const char *connection_cfg)
-{
- if (0 != pthread_key_create (&db_conn_threadlocal,
- &db_conn_destroy))
- {
- LOG_ERROR ("Cannnot create pthread key.\n");
- return GNUNET_SYSERR;
- }
- TALER_MINT_db_connection_cfg_str = GNUNET_strdup (connection_cfg);
- return GNUNET_OK;
-}
-
-
-/**
- * Get the thread-local database-handle.
- * Connect to the db if the connection does not exist yet.
- *
- * @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
- */
-PGconn *
-TALER_MINT_DB_get_connection (int temporary)
-{
- PGconn *db_conn;
-
- if (NULL != (db_conn = pthread_getspecific (db_conn_threadlocal)))
- return db_conn;
- db_conn = PQconnectdb (TALER_MINT_db_connection_cfg_str);
- if (CONNECTION_OK !=
- PQstatus (db_conn))
- {
- LOG_ERROR ("Database connection failed: %s\n",
- PQerrorMessage (db_conn));
- GNUNET_break (0);
- return NULL;
- }
- if ((GNUNET_YES == temporary)
- && (GNUNET_SYSERR == set_temporary_schema(db_conn)))
- {
- GNUNET_break (0);
- return NULL;
- }
- if (GNUNET_OK !=
- TALER_MINT_DB_prepare (db_conn))
- {
- GNUNET_break (0);
- return NULL;
- }
- if (0 != pthread_setspecific (db_conn_threadlocal,
- db_conn))
- {
- GNUNET_break (0);
- return NULL;
- }
- return db_conn;
-}
-
-
-/**
- * Start a transaction.
- *
- * @param db_conn the database connection
- * @return #GNUNET_OK on success
- */
-int
-TALER_MINT_DB_transaction (PGconn *db_conn)
-{
- PGresult *result;
-
- result = PQexec (db_conn,
- "BEGIN");
- if (PGRES_COMMAND_OK !=
- PQresultStatus (result))
- {
- 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 db_conn the database connection
- * @return #GNUNET_OK on success
- */
-void
-TALER_MINT_DB_rollback (PGconn *db_conn)
-{
- PGresult *result;
-
- result = PQexec (db_conn,
- "ROLLBACK");
- GNUNET_break (PGRES_COMMAND_OK ==
- PQresultStatus (result));
- PQclear (result);
-}
-
-
-/**
- * Commit the current transaction of a database connection.
- *
- * @param db_conn the database connection
- * @return #GNUNET_OK on success
- */
-int
-TALER_MINT_DB_commit (PGconn *db_conn)
-{
- PGresult *result;
-
- result = PQexec (db_conn,
- "COMMIT");
- if (PGRES_COMMAND_OK !=
- PQresultStatus (result))
- {
- GNUNET_break (0);
- PQclear (result);
- return GNUNET_SYSERR;
- }
-
- PQclear (result);
- return GNUNET_OK;
-}
-
-
-/**
- * Get the summary of a reserve.
- *
- * @param db the database connection handle
- * @param 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
- */
-int
-TALER_MINT_DB_reserve_get (PGconn *db,
- struct Reserve *reserve)
-{
- PGresult *result;
- uint64_t expiration_date_nbo;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(reserve->pub),
- TALER_DB_QUERY_PARAM_END
- };
-
- if (NULL == reserve->pub)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- result = TALER_DB_exec_prepared (db,
- "get_reserve",
- 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 TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC("expiration_date", &expiration_date_nbo),
- TALER_DB_RESULT_SPEC_END
- };
- EXITIF (GNUNET_OK != TALER_DB_extract_result (result, rs, 0));
- EXITIF (GNUNET_OK !=
- TALER_DB_extract_amount (result, 0,
- "current_balance_value",
- "current_balance_fraction",
- "balance_currency",
- &reserve->balance));
- reserve->expiry.abs_value_us = GNUNET_ntohll (expiration_date_nbo);
- PQclear (result);
- return GNUNET_OK;
-
- EXITIF_exit:
- PQclear (result);
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Updates a reserve with the data from the given reserve structure.
- *
- * @param db 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
- */
-int
-reserves_update (PGconn *db,
- struct Reserve *reserve)
-{
- PGresult *result;
- struct TALER_AmountNBO balance_nbo;
- struct GNUNET_TIME_AbsoluteNBO expiry_nbo;
- int ret;
-
- if ((NULL == reserve) || (NULL == reserve->pub))
- return GNUNET_SYSERR;
- ret = GNUNET_OK;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (reserve->pub),
- TALER_DB_QUERY_PARAM_PTR (&balance_nbo.value),
- TALER_DB_QUERY_PARAM_PTR (&balance_nbo.fraction),
- TALER_DB_QUERY_PARAM_PTR (&expiry_nbo),
- TALER_DB_QUERY_PARAM_END
- };
- TALER_amount_hton (&balance_nbo,
- &reserve->balance);
- expiry_nbo = GNUNET_TIME_absolute_hton (reserve->expiry);
- result = TALER_DB_exec_prepared (db,
- "update_reserve",
- params);
- if (PGRES_COMMAND_OK != PQresultStatus(result))
- {
- QUERY_ERR (result);
- ret = GNUNET_SYSERR;
- }
- PQclear (result);
- return ret;
-}
-
-
-/**
- * Insert a incoming transaction into reserves. New reserves are also created
- * through this function.
- *
- * @param db the database connection handle
- * @param reserve the reserve structure. The public key of the reserve should
- * be set here. Upon successful execution of this function, the
- * balance and expiration of the reserve will be updated.
- * @param balance the amount that has to be added to the reserve
- * @param expiry the new expiration time for the reserve
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failures
- */
-int
-TALER_MINT_DB_reserves_in_insert (PGconn *db,
- struct Reserve *reserve,
- const struct TALER_Amount *balance,
- const struct GNUNET_TIME_Absolute expiry)
-{
- struct TALER_AmountNBO balance_nbo;
- struct GNUNET_TIME_AbsoluteNBO expiry_nbo;
- PGresult *result;
- int reserve_exists;
-
- result = NULL;
- if (NULL == reserve)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK != TALER_MINT_DB_transaction (db))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- reserve_exists = TALER_MINT_DB_reserve_get (db, reserve);
- if (GNUNET_SYSERR == reserve_exists)
- {
- TALER_MINT_DB_rollback (db);
- return GNUNET_SYSERR;
- }
- TALER_amount_hton (&balance_nbo,
- balance);
- expiry_nbo = GNUNET_TIME_absolute_hton (expiry);
- if (GNUNET_NO == reserve_exists)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Reserve does not exist; creating a new one\n");
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (reserve->pub),
- TALER_DB_QUERY_PARAM_PTR (&balance_nbo.value),
- TALER_DB_QUERY_PARAM_PTR (&balance_nbo.fraction),
- TALER_DB_QUERY_PARAM_PTR_SIZED (balance_nbo.currency,
- TALER_DB_CURRENCY_LEN),
- TALER_DB_QUERY_PARAM_PTR (&expiry_nbo),
- TALER_DB_QUERY_PARAM_END
- };
- result = TALER_DB_exec_prepared (db,
- "create_reserve",
- params);
- if (PGRES_COMMAND_OK != PQresultStatus(result))
- {
- QUERY_ERR (result);
- goto rollback;
- }
- }
- if (NULL != result)
- PQclear (result);
- result = NULL;
- /* create new incoming transaction */
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (reserve->pub),
- TALER_DB_QUERY_PARAM_PTR (&balance_nbo.value),
- TALER_DB_QUERY_PARAM_PTR (&balance_nbo.fraction),
- TALER_DB_QUERY_PARAM_PTR_SIZED (&balance_nbo.currency,
- TALER_DB_CURRENCY_LEN),
- TALER_DB_QUERY_PARAM_PTR (&expiry_nbo),
- TALER_DB_QUERY_PARAM_END
- };
- result = TALER_DB_exec_prepared (db,
- "create_reserves_in_transaction",
- params);
- if (PGRES_COMMAND_OK != PQresultStatus(result))
- {
- QUERY_ERR (result);
- goto rollback;
- }
- PQclear (result);
- result = NULL;
- if (GNUNET_NO == reserve_exists)
- {
- if (GNUNET_OK != TALER_MINT_DB_commit (db))
- return GNUNET_SYSERR;
- reserve->balance = *balance;
- reserve->expiry = expiry;
- return GNUNET_OK;
- }
- /* Update reserve */
- struct Reserve updated_reserve;
- updated_reserve.pub = reserve->pub;
-
- if (GNUNET_OK !=
- TALER_amount_add (&updated_reserve.balance,
- &reserve->balance,
- balance))
- {
- return GNUNET_SYSERR;
- }
- updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry, reserve->expiry);
- if (GNUNET_OK != reserves_update (db, &updated_reserve))
- goto rollback;
- if (GNUNET_OK != TALER_MINT_DB_commit (db))
- return GNUNET_SYSERR;
- reserve->balance = updated_reserve.balance;
- reserve->expiry = updated_reserve.expiry;
- return GNUNET_OK;
-
- rollback:
- PQclear (result);
- TALER_MINT_DB_rollback (db);
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Locate the response for a /withdraw request under the
- * key of the hash of the blinded message.
- *
- * @param db_conn database connection to use
- * @param h_blind hash of the blinded message
- * @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
- */
-int
-TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
- const struct GNUNET_HashCode *h_blind,
- struct CollectableBlindcoin *collectable)
-{
- PGresult *result;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (h_blind),
- TALER_DB_QUERY_PARAM_END
- };
- struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
- struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
- char *denom_pub_enc;
- char *denom_sig_enc;
- size_t denom_pub_enc_size;
- size_t denom_sig_enc_size;
- int ret;
-
- ret = GNUNET_SYSERR;
- denom_pub = NULL;
- denom_pub_enc = NULL;
- denom_sig_enc = NULL;
- result = TALER_DB_exec_prepared (db_conn,
- "get_collectable_blindcoin",
- params);
-
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- QUERY_ERR (result);
- goto cleanup;
- }
- if (0 == PQntuples (result))
- {
- ret = GNUNET_NO;
- goto cleanup;
- }
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC_VAR("denom_pub", &denom_pub_enc, &denom_pub_enc_size),
- TALER_DB_RESULT_SPEC_VAR("denom_sig", &denom_sig_enc, &denom_sig_enc_size),
- TALER_DB_RESULT_SPEC("reserve_sig", &collectable->reserve_sig),
- TALER_DB_RESULT_SPEC("reserve_pub", &collectable->reserve_pub),
- TALER_DB_RESULT_SPEC_END
- };
-
- if (GNUNET_OK != TALER_DB_extract_result (result, rs, 0))
- {
- GNUNET_break (0);
- goto cleanup;
- }
- denom_pub = GNUNET_CRYPTO_rsa_public_key_decode (denom_pub_enc,
- denom_pub_enc_size);
- denom_sig = GNUNET_CRYPTO_rsa_signature_decode (denom_sig_enc,
- denom_sig_enc_size);
- if ((NULL == denom_pub) || (NULL == denom_sig))
- {
- GNUNET_break (0);
- goto cleanup;
- }
- collectable->denom_pub = denom_pub;
- collectable->sig = denom_sig;
- ret = GNUNET_YES;
-
- cleanup:
- PQclear (result);
- GNUNET_free_non_null (denom_pub_enc);
- GNUNET_free_non_null (denom_sig_enc);
- if (GNUNET_YES != ret)
- { if (NULL != denom_pub)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pub);
- if (NULL != denom_sig)
- GNUNET_CRYPTO_rsa_signature_free (denom_sig);
- }
- return ret;
-}
-
-
-/**
- * Store collectable bit coin under the corresponding
- * hash of the blinded message.
- *
- * @param db_conn database connection to use
- * @param h_blind hash of the blinded message
- * @param withdraw amount by which the reserve will be withdrawn with this
- * transaction
- * @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
- */
-int
-TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn,
- const struct GNUNET_HashCode *h_blind,
- struct TALER_Amount withdraw,
- const struct CollectableBlindcoin *collectable)
-{
- PGresult *result;
- struct Reserve reserve;
- char *denom_pub_enc = NULL;
- char *denom_sig_enc = NULL;
- size_t denom_pub_enc_size;
- size_t denom_sig_enc_size;
- int ret;
-
- ret = GNUNET_SYSERR;
- denom_pub_enc_size =
- GNUNET_CRYPTO_rsa_public_key_encode (collectable->denom_pub,
- &denom_pub_enc);
- denom_sig_enc_size =
- GNUNET_CRYPTO_rsa_signature_encode (collectable->sig,
- &denom_sig_enc);
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (h_blind),
- TALER_DB_QUERY_PARAM_PTR_SIZED (denom_pub_enc, denom_pub_enc_size - 1),
- TALER_DB_QUERY_PARAM_PTR_SIZED (denom_sig_enc, denom_sig_enc_size - 1), /* DB doesn't like the trailing \0 */
- TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_pub),
- TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_sig),
- TALER_DB_QUERY_PARAM_END
- };
- if (GNUNET_OK != TALER_MINT_DB_transaction (db_conn))
- goto cleanup;
- result = TALER_DB_exec_prepared (db_conn,
- "insert_collectable_blindcoin",
- params);
- if (PGRES_COMMAND_OK != PQresultStatus (result))
- {
- QUERY_ERR (result);
- goto rollback;
- }
- reserve.pub = (struct GNUNET_CRYPTO_EddsaPublicKey *)
- &collectable->reserve_pub;
- if (GNUNET_OK != TALER_MINT_DB_reserve_get (db_conn,
- &reserve))
- goto rollback;
- if (GNUNET_SYSERR ==
- TALER_amount_subtract (&reserve.balance,
- &reserve.balance,
- &withdraw))
- goto rollback;
- if (GNUNET_OK != reserves_update (db_conn, &reserve))
- goto rollback;
- if (GNUNET_OK == TALER_MINT_DB_commit (db_conn))
- {
- ret = GNUNET_OK;
- goto cleanup;
- }
-
- rollback:
- TALER_MINT_DB_rollback(db_conn);
- cleanup:
- PQclear (result);
- GNUNET_free_non_null (denom_pub_enc);
- GNUNET_free_non_null (denom_sig_enc);
- return ret;
-}
-
-
-/**
- * Get all of the transaction history associated with the specified
- * reserve.
- *
- * @param db_conn connection to use
- * @param reserve_pub public key of the reserve
- * @return known transaction history (NULL if reserve is unknown)
- */
-struct ReserveHistory *
-TALER_MINT_DB_get_reserve_history (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub)
-{
- PGresult *result;
- struct ReserveHistory *rh;
- struct ReserveHistory *rh_head;
- int rows;
- int ret;
-
- result = NULL;
- rh = NULL;
- rh_head = NULL;
- ret = GNUNET_SYSERR;
- {
- struct BankTransfer *bt;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (reserve_pub),
- TALER_DB_QUERY_PARAM_END
- };
-
- result = TALER_DB_exec_prepared (db_conn,
- "get_reserves_in_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 BankTransfer);
- if (GNUNET_OK != TALER_DB_extract_amount (result,
- --rows,
- "balance_value",
- "balance_fraction",
- "balance_currency",
- &bt->amount))
- {
- GNUNET_free (bt);
- GNUNET_break (0);
- goto cleanup;
- }
- (void) memcpy (&bt->reserve_pub, reserve_pub, sizeof (bt->reserve_pub));
- if (NULL != rh_head)
- {
- rh_head->next = GNUNET_new (struct ReserveHistory);
- rh_head = rh_head->next;
- }
- else
- {
- rh_head = GNUNET_new (struct ReserveHistory);
- rh = rh_head;
- }
- rh_head->type = TALER_MINT_DB_RO_BANK_TO_MINT;
- rh_head->details.bank = bt;
- }
- }
- PQclear (result);
- result = NULL;
- {
- struct GNUNET_HashCode blind_ev;
- struct GNUNET_CRYPTO_EddsaSignature reserve_sig;
- struct CollectableBlindcoin *cbc;
- char *denom_pub_enc;
- char *denom_sig_enc;
- size_t denom_pub_enc_size;
- size_t denom_sig_enc_size;
-
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (reserve_pub),
- TALER_DB_QUERY_PARAM_END
- };
- result = TALER_DB_exec_prepared (db_conn,
- "get_reserves_blindcoins",
- params);
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- QUERY_ERR (result);
- goto cleanup;
- }
- if (0 == (rows = PQntuples (result)))
- {
- ret = GNUNET_OK; /* Its OK if there are no withdrawls yet */
- goto cleanup;
- }
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC ("blind_ev", &blind_ev),
- TALER_DB_RESULT_SPEC_VAR ("denom_pub", &denom_pub_enc, &denom_pub_enc_size),
- TALER_DB_RESULT_SPEC_VAR ("denom_sig", &denom_sig_enc, &denom_sig_enc_size),
- TALER_DB_RESULT_SPEC ("reserve_sig", &reserve_sig),
- TALER_DB_RESULT_SPEC_END
- };
- GNUNET_assert (NULL != rh);
- GNUNET_assert (NULL != rh_head);
- GNUNET_assert (NULL == rh_head->next);
- while (0 < rows)
- {
- if (GNUNET_YES != TALER_DB_extract_result (result, rs, --rows))
- {
- GNUNET_break (0);
- goto cleanup;
- }
- cbc = GNUNET_new (struct CollectableBlindcoin);
- cbc->sig = GNUNET_CRYPTO_rsa_signature_decode (denom_sig_enc,
- denom_sig_enc_size);
- GNUNET_free (denom_sig_enc);
- denom_sig_enc = NULL;
- cbc->denom_pub = GNUNET_CRYPTO_rsa_public_key_decode (denom_pub_enc,
- denom_pub_enc_size);
- GNUNET_free (denom_pub_enc);
- denom_pub_enc = NULL;
- if ((NULL == cbc->sig) || (NULL == cbc->denom_pub))
- {
- if (NULL != cbc->sig)
- GNUNET_CRYPTO_rsa_signature_free (cbc->sig);
- if (NULL != cbc->denom_pub)
- GNUNET_CRYPTO_rsa_public_key_free (cbc->denom_pub);
- GNUNET_free (cbc);
- GNUNET_break (0);
- goto cleanup;
- }
- (void) memcpy (&cbc->h_coin_envelope, &blind_ev, sizeof (blind_ev));
- (void) memcpy (&cbc->reserve_pub, reserve_pub, sizeof (cbc->reserve_pub));
- (void) memcpy (&cbc->reserve_sig, &reserve_sig, sizeof (cbc->reserve_sig));
- rh_head->next = GNUNET_new (struct ReserveHistory);
- rh_head = rh_head->next;
- rh_head->type = TALER_MINT_DB_RO_WITHDRAW_COIN;
- rh_head->details.withdraw = cbc;
- }
- }
- ret = GNUNET_OK;
-
- cleanup:
- if (NULL != result)
- PQclear (result);
- if (GNUNET_SYSERR == ret)
- {
- TALER_MINT_DB_free_reserve_history (rh);
- rh = NULL;
- }
- return rh;
-}
-
-
-/**
- * Free memory associated with the given reserve history.
- *
- * @param rh history to free.
- */
-void
-TALER_MINT_DB_free_reserve_history (struct ReserveHistory *rh)
-{
- struct BankTransfer *bt;
- struct CollectableBlindcoin *cbc;
- struct ReserveHistory *backref;
-
- while (NULL != rh)
- {
- switch(rh->type)
- {
- case TALER_MINT_DB_RO_BANK_TO_MINT:
- bt = rh->details.bank;
- if (NULL != bt->wire)
- json_decref ((json_t *) bt->wire); /* FIXME: avoid cast? */
- GNUNET_free (bt);
- break;
- case TALER_MINT_DB_RO_WITHDRAW_COIN:
- cbc = rh->details.withdraw;
- GNUNET_CRYPTO_rsa_signature_free (cbc->sig);
- GNUNET_CRYPTO_rsa_public_key_free (cbc->denom_pub);
- GNUNET_free (cbc);
- break;
- }
- backref = rh;
- rh = rh->next;
- GNUNET_free (backref);
- }
-}
-
-
-/**
- * Check if we have the specified deposit already in the database.
- *
- * @param db_conn database connection
- * @param deposit deposit to search for
- * @return #GNUNET_YES if we know this operation,
- * #GNUNET_NO if this deposit is unknown to us
- */
-int
-TALER_MINT_DB_have_deposit (PGconn *db_conn,
- const struct Deposit *deposit)
-{
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (&deposit->coin.coin_pub),
- TALER_DB_QUERY_PARAM_PTR (&deposit->transaction_id),
- TALER_DB_QUERY_PARAM_PTR (&deposit->merchant_pub),
- TALER_DB_QUERY_PARAM_END
- };
- PGresult *result;
- int ret;
-
- ret = GNUNET_SYSERR;
- result = TALER_DB_exec_prepared (db_conn,
- "get_deposit",
- params);
- if (PGRES_TUPLES_OK !=
- PQresultStatus (result))
- {
- BREAK_DB_ERR (result);
- goto cleanup;
- }
-
- if (0 == PQntuples (result))
- {
- ret = GNUNET_NO;
- goto cleanup;
- }
- ret = GNUNET_YES;
-
- cleanup:
- PQclear (result);
- return ret;
-}
-
-
-/**
- * Insert information about deposited coin into the
- * database.
- *
- * @param db_conn connection to the database
- * @param deposit deposit information to store
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-int
-TALER_MINT_DB_insert_deposit (PGconn *db_conn,
- const struct Deposit *deposit)
-{
- char *denom_pub_enc;
- char *denom_sig_enc;
- char *json_wire_enc;
- PGresult *result;
- struct TALER_AmountNBO amount_nbo;
- size_t denom_pub_enc_size;
- size_t denom_sig_enc_size;
- int ret;
-
- ret = GNUNET_SYSERR;
- denom_pub_enc_size =
- GNUNET_CRYPTO_rsa_public_key_encode (deposit->coin.denom_pub,
- &denom_pub_enc);
- denom_sig_enc_size =
- GNUNET_CRYPTO_rsa_signature_encode (deposit->coin.denom_sig,
- &denom_sig_enc);
- json_wire_enc = json_dumps (deposit->wire, JSON_COMPACT);
- TALER_amount_hton (&amount_nbo,
- &deposit->amount);
- struct TALER_DB_QueryParam params[]= {
- TALER_DB_QUERY_PARAM_PTR (&deposit->coin.coin_pub),
- TALER_DB_QUERY_PARAM_PTR_SIZED (denom_pub_enc, denom_pub_enc_size),
- TALER_DB_QUERY_PARAM_PTR_SIZED (denom_sig_enc, denom_sig_enc_size),
- TALER_DB_QUERY_PARAM_PTR (&deposit->transaction_id),
- TALER_DB_QUERY_PARAM_PTR (&amount_nbo.value),
- TALER_DB_QUERY_PARAM_PTR (&amount_nbo.fraction),
- TALER_DB_QUERY_PARAM_PTR_SIZED (amount_nbo.currency,
- TALER_CURRENCY_LEN - 1),
- TALER_DB_QUERY_PARAM_PTR (&deposit->merchant_pub),
- TALER_DB_QUERY_PARAM_PTR (&deposit->h_contract),
- TALER_DB_QUERY_PARAM_PTR (&deposit->h_wire),
- TALER_DB_QUERY_PARAM_PTR (&deposit->csig),
- TALER_DB_QUERY_PARAM_PTR_SIZED (json_wire_enc,
- strlen (json_wire_enc)),
- TALER_DB_QUERY_PARAM_END
- };
- result = TALER_DB_exec_prepared (db_conn, "insert_deposit", params);
- if (PGRES_COMMAND_OK != PQresultStatus (result))
- {
- BREAK_DB_ERR (result);
- goto cleanup;
- }
- ret = GNUNET_OK;
-
- cleanup:
- PQclear (result);
- GNUNET_free_non_null (denom_pub_enc);
- GNUNET_free_non_null (denom_sig_enc);
- GNUNET_free_non_null (json_wire_enc);
- return ret;
-}
-
-
-/**
- * Lookup refresh session data under the given public key.
- *
- * @param db_conn database handle to use
- * @param refresh_session_pub public key to use for the lookup
- * @param session[OUT] where to store the result
- * @return #GNUNET_YES on success,
- * #GNUNET_NO if not found,
- * #GNUNET_SYSERR on DB failure
- */
-int
-TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- struct RefreshSession *session)
-{
- // FIXME: check logic!
- int res;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(refresh_session_pub),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "get_refresh_session", params);
-
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Query failed: %s\n",
- PQresultErrorMessage (result));
- PQclear (result);
- return GNUNET_SYSERR;
- }
-
- if (0 == PQntuples (result))
- return GNUNET_NO;
-
- GNUNET_assert (1 == PQntuples (result));
-
- /* We're done if the caller is only interested in
- * whether the session exists or not */
-
- if (NULL == session)
- return GNUNET_YES;
-
- memset (session, 0, sizeof (struct RefreshSession));
-
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC("num_oldcoins", &session->num_oldcoins),
- TALER_DB_RESULT_SPEC("num_newcoins", &session->num_newcoins),
- TALER_DB_RESULT_SPEC("kappa", &session->kappa),
- TALER_DB_RESULT_SPEC("noreveal_index", &session->noreveal_index),
- TALER_DB_RESULT_SPEC_END
- };
-
- res = TALER_DB_extract_result (result, rs, 0);
-
- if (GNUNET_OK != res)
- {
- GNUNET_break (0);
- PQclear (result);
- return GNUNET_SYSERR;
- }
-
- session->num_oldcoins = ntohs (session->num_oldcoins);
- session->num_newcoins = ntohs (session->num_newcoins);
- session->kappa = ntohs (session->kappa);
- session->noreveal_index = ntohs (session->noreveal_index);
-
- PQclear (result);
- return GNUNET_YES;
-}
-
-
-/**
- * Store new refresh session data under the given public key.
- *
- * @param db_conn database handle to use
- * @param refresh_session_pub public key to use to locate the session
- * @param session session data to store
- * @return #GNUNET_YES on success,
- * #GNUNET_SYSERR on DB failure
- */
-int
-TALER_MINT_DB_create_refresh_session (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- const struct RefreshSession *session)
-{
- // FIXME: actually store session data!
- uint16_t noreveal_index;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(session_pub),
- TALER_DB_QUERY_PARAM_PTR(&noreveal_index),
- TALER_DB_QUERY_PARAM_END
- };
-
- noreveal_index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1<<15);
- noreveal_index = htonl (noreveal_index);
-
- PGresult *result = TALER_DB_exec_prepared (db_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;
-}
-
-
-/**
- * Store the given /refresh/melt request in the database.
- *
- * @param db_conn database connection
- * @param session session key of the melt operation
- * @param oldcoin_index index of the coin to store
- * @param melt melt operation
- * @return #GNUNET_OK on success
- * #GNUNET_SYSERR on internal error
- */
-int
-TALER_MINT_DB_insert_refresh_melt (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session,
- uint16_t oldcoin_index,
- const struct RefreshMelt *melt)
-{
- // FIXME: check logic!
- uint16_t oldcoin_index_nbo = htons (oldcoin_index);
- char *buf;
- size_t buf_size;
- PGresult *result;
-
- buf_size = GNUNET_CRYPTO_rsa_public_key_encode (melt->coin.denom_pub,
- &buf);
- {
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(session),
- TALER_DB_QUERY_PARAM_PTR(&oldcoin_index_nbo),
- TALER_DB_QUERY_PARAM_PTR(&melt->coin.coin_pub),
- TALER_DB_QUERY_PARAM_PTR_SIZED(buf, buf_size),
- TALER_DB_QUERY_PARAM_END
- };
- result = TALER_DB_exec_prepared (db_conn, "insert_refresh_melt", params);
- }
- GNUNET_free (buf);
- 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 db_conn database connection
- * @param session session key of the melt operation
- * @param oldcoin_index index of the coin to retrieve
- * @param melt melt data to fill in
- * @return #GNUNET_OK on success
- * #GNUNET_SYSERR on internal error
- */
-int
-TALER_MINT_DB_get_refresh_melt (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session,
- uint16_t oldcoin_index,
- struct RefreshMelt *melt)
-{
- // FIXME: check logic!
- GNUNET_break (0);
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Store in the database which coin(s) we want to create
- * in a given refresh operation.
- *
- * @param db_conn database connection
- * @param session_pub refresh session key
- * @param newcoin_index index of the coin to generate
- * @param denom_pub denomination of the coin to create
- * @return #GNUNET_OK on success
- * #GNUNET_SYSERR on internal error
- */
-int
-TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- uint16_t newcoin_index,
- const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
-{
- // FIXME: check logic
- uint16_t newcoin_index_nbo = htons (newcoin_index);
- char *buf;
- size_t buf_size;
- PGresult *result;
-
- buf_size = GNUNET_CRYPTO_rsa_public_key_encode (denom_pub,
- &buf);
-
- {
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (&newcoin_index_nbo),
- TALER_DB_QUERY_PARAM_PTR (session_pub),
- TALER_DB_QUERY_PARAM_PTR_SIZED (buf, buf_size),
- TALER_DB_QUERY_PARAM_END
- };
- result = TALER_DB_exec_prepared (db_conn,
- "insert_refresh_order",
- params);
- }
- GNUNET_free (buf);
- 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;
-}
-
-
-/**
- * Lookup in the database the @a newcoin_index coin that we want to
- * create in the given refresh operation.
- *
- * @param db_conn database connection
- * @param session_pub refresh session key
- * @param newcoin_index index of the coin to generate
- * @param denom_pub denomination of the coin to create
- * @return NULL on error (not found or internal error)
- */
-struct GNUNET_CRYPTO_rsa_PublicKey *
-TALER_MINT_DB_get_refresh_order (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- uint16_t newcoin_index)
-{
- // FIXME: check logic
- char *buf;
- size_t buf_size;
- struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
- uint16_t newcoin_index_nbo = htons (newcoin_index);
-
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(session_pub),
- TALER_DB_QUERY_PARAM_PTR(&newcoin_index_nbo),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "get_refresh_order", params);
-
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- BREAK_DB_ERR (result);
- PQclear (result);
- return NULL;
- }
-
- if (0 == PQntuples (result))
- {
- PQclear (result);
- /* FIXME: may want to distinguish between different error cases! */
- return NULL;
- }
- GNUNET_assert (1 == PQntuples (result));
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC_VAR ("denom_pub", &buf, &buf_size),
- TALER_DB_RESULT_SPEC_END
- };
- if (GNUNET_OK != TALER_DB_extract_result (result, rs, 0))
- {
- PQclear (result);
- GNUNET_break (0);
- return NULL;
- }
- PQclear (result);
- denom_pub = GNUNET_CRYPTO_rsa_public_key_decode (buf, buf_size);
- GNUNET_free (buf);
- return denom_pub;
-}
-
-
-
-/**
- * Store information about the commitment of the
- * given coin for the given refresh session in the database.
- *
- * @param db_conn database connection to use
- * @param refresh_session_pub refresh session this commitment belongs to
- * @param i set index (1st dimension)
- * @param j coin index (2nd dimension), corresponds to refreshed (new) coins
- * @param commit_coin coin commitment to store
- * @return #GNUNET_OK on success
- * #GNUNET_SYSERR on error
- */
-int
-TALER_MINT_DB_insert_refresh_commit_coin (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- unsigned int i,
- unsigned int j,
- const struct RefreshCommitCoin *commit_coin)
-{
- // FIXME: check logic!
- uint16_t cnc_index_nbo = htons (i);
- uint16_t newcoin_index_nbo = htons (j);
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(refresh_session_pub),
- TALER_DB_QUERY_PARAM_PTR_SIZED(commit_coin->coin_ev, commit_coin->coin_ev_size),
- TALER_DB_QUERY_PARAM_PTR(&cnc_index_nbo),
- TALER_DB_QUERY_PARAM_PTR(&newcoin_index_nbo),
- TALER_DB_QUERY_PARAM_PTR_SIZED(commit_coin->refresh_link->coin_priv_enc,
- commit_coin->refresh_link->blinding_key_enc_size +
- sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "insert_refresh_commit_coin", 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 information about the commitment of the
- * given coin of the given refresh session from the database.
- *
- * @param db_conn database connection to use
- * @param refresh_session_pub refresh session the commitment belongs to
- * @param i set index (1st dimension)
- * @param j coin index (2nd dimension), corresponds to refreshed (new) coins
- * @param commit_coin[OUT] coin commitment to return
- * @return #GNUNET_OK on success
- * #GNUNET_NO if not found
- * #GNUNET_SYSERR on error
- */
-int
-TALER_MINT_DB_get_refresh_commit_coin (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- unsigned int cnc_index,
- unsigned int newcoin_index,
- struct RefreshCommitCoin *cc)
-{
- // FIXME: check logic!
- uint16_t cnc_index_nbo = htons (cnc_index);
- uint16_t newcoin_index_nbo = htons (newcoin_index);
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(refresh_session_pub),
- TALER_DB_QUERY_PARAM_PTR(&cnc_index_nbo),
- TALER_DB_QUERY_PARAM_PTR(&newcoin_index_nbo),
- TALER_DB_QUERY_PARAM_END
- };
- char *c_buf;
- size_t c_buf_size;
- char *rl_buf;
- size_t rl_buf_size;
- struct TALER_RefreshLinkEncrypted *rl;
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "get_refresh_commit_coin", 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 TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC_VAR("coin_ev", &c_buf, &c_buf_size),
- TALER_DB_RESULT_SPEC_VAR("link_vector_enc", &rl_buf, &rl_buf_size),
- TALER_DB_RESULT_SPEC_END
- };
- if (GNUNET_YES != TALER_DB_extract_result (result, rs, 0))
- {
- PQclear (result);
- return GNUNET_SYSERR;
- }
- PQclear (result);
- if (rl_buf_size < sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))
- {
- GNUNET_free (c_buf);
- GNUNET_free (rl_buf);
- return GNUNET_SYSERR;
- }
- rl = TALER_refresh_link_encrypted_decode (rl_buf,
- rl_buf_size);
- GNUNET_free (rl_buf);
- cc->refresh_link = rl;
- cc->coin_ev = c_buf;
- cc->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 db_conn database connection to use
- * @param refresh_session_pub public key of the refresh session this
- * commitment belongs with
- * @param i set index (1st dimension)
- * @param j coin index (2nd dimension), corresponds to melted (old) coins
- * @param commit_link link information to store
- * @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success
- */
-int
-TALER_MINT_DB_insert_refresh_commit_link (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- unsigned int i,
- unsigned int j,
- const struct RefreshCommitLink *commit_link)
-{
- // FIXME: check logic!
- uint16_t cnc_index_nbo = htons (i);
- uint16_t oldcoin_index_nbo = htons (j);
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(refresh_session_pub),
- TALER_DB_QUERY_PARAM_PTR(&commit_link->transfer_pub),
- TALER_DB_QUERY_PARAM_PTR(&cnc_index_nbo),
- TALER_DB_QUERY_PARAM_PTR(&oldcoin_index_nbo),
- TALER_DB_QUERY_PARAM_PTR(&commit_link->shared_secret_enc),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_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 db_conn database connection to use
- * @param refresh_session_pub public key of the refresh session this
- * commitment belongs with
- * @param i set index (1st dimension)
- * @param j coin index (2nd dimension), corresponds to melted (old) coins
- * @param cc[OUT] link information to return
- * @return #GNUNET_SYSERR on internal error,
- * #GNUNET_NO if commitment was not found
- * #GNUNET_OK on success
- */
-int
-TALER_MINT_DB_get_refresh_commit_link (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- unsigned int cnc_index,
- unsigned int oldcoin_index,
- struct RefreshCommitLink *cc)
-{
- // FIXME: check logic!
- uint16_t cnc_index_nbo = htons (cnc_index);
- uint16_t oldcoin_index_nbo = htons (oldcoin_index);
-
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(refresh_session_pub),
- TALER_DB_QUERY_PARAM_PTR(&cnc_index_nbo),
- TALER_DB_QUERY_PARAM_PTR(&oldcoin_index_nbo),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_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 TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC("transfer_pub", &cc->transfer_pub),
- TALER_DB_RESULT_SPEC("link_secret_enc", &cc->shared_secret_enc),
- TALER_DB_RESULT_SPEC_END
- };
-
- if (GNUNET_YES != TALER_DB_extract_result (result, rs, 0))
- {
- PQclear (result);
- GNUNET_free (cc);
- return GNUNET_SYSERR;
- }
-
- PQclear (result);
- return GNUNET_OK;
-}
-
-
-/**
- * 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 db_conn database connection
- * @param session_pub refresh session
- * @param newcoin_index coin index
- * @param ev_sig coin signature
- * @return #GNUNET_OK on success
- */
-int
-TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- uint16_t newcoin_index,
- const struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
-{
- // FIXME: check logic!
- uint16_t newcoin_index_nbo = htons (newcoin_index);
- char *buf;
- size_t buf_size;
- PGresult *result;
-
- buf_size = GNUNET_CRYPTO_rsa_signature_encode (ev_sig,
- &buf);
- {
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(session_pub),
- TALER_DB_QUERY_PARAM_PTR(&newcoin_index_nbo),
- TALER_DB_QUERY_PARAM_PTR_SIZED(buf, buf_size),
- TALER_DB_QUERY_PARAM_END
- };
- result = TALER_DB_exec_prepared (db_conn,
- "insert_refresh_collectable",
- params);
- }
- GNUNET_free (buf);
- 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 db_conn database connection
- * @param coin_pub public key to use to retrieve linkage data
- * @return all known link data for the coin
- */
-struct LinkDataList *
-TALER_db_get_link (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub)
-{
- // FIXME: check logic!
- struct LinkDataList *ldl;
- struct LinkDataList *pos;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(coin_pub),
- TALER_DB_QUERY_PARAM_END
- };
- PGresult *result = TALER_DB_exec_prepared (db_conn, "get_link", params);
-
- ldl = NULL;
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- BREAK_DB_ERR (result);
- PQclear (result);
- return NULL;
- }
-
- if (0 == PQntuples (result))
- {
- PQclear (result);
- return NULL;
- }
-
-
- int i = 0;
-
- for (i = 0; i < PQntuples (result); i++)
- {
- struct TALER_RefreshLinkEncrypted *link_enc;
- struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
- struct GNUNET_CRYPTO_rsa_Signature *sig;
- char *ld_buf;
- size_t ld_buf_size;
- char *pk_buf;
- size_t pk_buf_size;
- char *sig_buf;
- size_t sig_buf_size;
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC_VAR("link_vector_enc", &ld_buf, &ld_buf_size),
- TALER_DB_RESULT_SPEC_VAR("denom_pub", &pk_buf, &pk_buf_size),
- TALER_DB_RESULT_SPEC_VAR("ev_sig", &sig_buf, &sig_buf_size),
- TALER_DB_RESULT_SPEC_END
- };
-
- if (GNUNET_OK != TALER_DB_extract_result (result, rs, i))
- {
- PQclear (result);
- GNUNET_break (0);
- TALER_db_link_data_list_free (ldl);
- return NULL;
- }
- if (ld_buf_size < sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))
- {
- PQclear (result);
- GNUNET_free (pk_buf);
- GNUNET_free (sig_buf);
- GNUNET_free (ld_buf);
- TALER_db_link_data_list_free (ldl);
- return NULL;
- }
- // FIXME: use util API for this!
- link_enc = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) +
- ld_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
- link_enc->blinding_key_enc = (const char *) &link_enc[1];
- link_enc->blinding_key_enc_size = ld_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey);
- memcpy (link_enc->coin_priv_enc,
- ld_buf,
- ld_buf_size);
-
- sig = GNUNET_CRYPTO_rsa_signature_decode (sig_buf,
- sig_buf_size);
- denom_pub = GNUNET_CRYPTO_rsa_public_key_decode (pk_buf,
- pk_buf_size);
- GNUNET_free (pk_buf);
- GNUNET_free (sig_buf);
- GNUNET_free (ld_buf);
- if ( (NULL == sig) ||
- (NULL == denom_pub) )
- {
- if (NULL != denom_pub)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pub);
- if (NULL != sig)
- GNUNET_CRYPTO_rsa_signature_free (sig);
- GNUNET_free (link_enc);
- GNUNET_break (0);
- PQclear (result);
- TALER_db_link_data_list_free (ldl);
- return NULL;
- }
- pos = GNUNET_new (struct LinkDataList);
- pos->next = ldl;
- pos->link_data_enc = link_enc;
- pos->denom_pub = denom_pub;
- pos->ev_sig = sig;
- ldl = pos;
- }
- return ldl;
-}
-
-
-/**
- * Free memory of the link data list.
- *
- * @param ldl link data list to release
- */
-void
-TALER_db_link_data_list_free (struct LinkDataList *ldl)
-{
- GNUNET_break (0); // FIXME
-}
-
-
-/**
- * Obtain shared secret and transfer public key from the public key of
- * the coin. This information and the link information returned by
- * #TALER_db_get_link() enable the owner of an old coin to determine
- * the private keys of the new coins after the melt.
- *
- *
- * @param db_conn database connection
- * @param coin_pub public key of the coin
- * @param transfer_pub[OUT] public transfer key
- * @param shared_secret_enc[OUT] set to shared secret
- * @return #GNUNET_OK on success,
- * #GNUNET_NO on failure (not found)
- * #GNUNET_SYSERR on internal failure (database issue)
- */
-int
-TALER_db_get_transfer (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
- struct GNUNET_CRYPTO_EcdsaPublicKey *transfer_pub,
- struct TALER_EncryptedLinkSecret *shared_secret_enc)
-{
- // FIXME: check logic!
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(coin_pub),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "get_transfer", 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;
- }
-
- if (1 != PQntuples (result))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "got %d tuples for get_transfer\n",
- PQntuples (result));
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
-
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC("transfer_pub", transfer_pub),
- TALER_DB_RESULT_SPEC("link_secret_enc", shared_secret_enc),
- TALER_DB_RESULT_SPEC_END
- };
-
- if (GNUNET_OK != TALER_DB_extract_result (result, rs, 0))
- {
- PQclear (result);
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
-
- PQclear (result);
- return GNUNET_OK;
-}
-
-
-
-
-/**
- * Compile a list of all (historic) transactions performed
- * with the given coin (/refresh/melt and /deposit operations).
- *
- * @param db_conn database connection
- * @param coin_pub coin to investigate
- * @return list of transactions, NULL if coin is fresh
- */
-struct TALER_MINT_DB_TransactionList *
-TALER_MINT_DB_get_coin_transactions (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub)
-{
- // FIXME: check logic!
- GNUNET_break (0); // FIXME: implement!
- return NULL;
-}
-
-
-/**
- * Free linked list of transactions.
- *
- * @param list list to free
- */
-void
-TALER_MINT_DB_free_coin_transaction_list (struct TALER_MINT_DB_TransactionList *list)
-{
- // FIXME: check logic!
- GNUNET_break (0);
-}
-
-
-/* end of mint_db.c */