summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-09-19 20:28:37 +0200
committerChristian Grothoff <christian@grothoff.org>2015-09-19 20:28:37 +0200
commitcc47c5c701340c9be0acc6b7394aa2afad0cd0d3 (patch)
treeb64bbcdc7b2dcabdbfe9a0c501e7964e63be55be /src
parentf8a730a0ab6db9ca37c652493b844a7a5ff503e0 (diff)
downloadexchange-cc47c5c701340c9be0acc6b7394aa2afad0cd0d3.tar.gz
exchange-cc47c5c701340c9be0acc6b7394aa2afad0cd0d3.tar.bz2
exchange-cc47c5c701340c9be0acc6b7394aa2afad0cd0d3.zip
implement #3838 (as required for wire transfers)
Diffstat (limited to 'src')
-rw-r--r--src/include/taler_mintdb_plugin.h102
-rw-r--r--src/mintdb/plugin_mintdb_postgres.c123
2 files changed, 170 insertions, 55 deletions
diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h
index 4e06fc86f..851ed5265 100644
--- a/src/include/taler_mintdb_plugin.h
+++ b/src/include/taler_mintdb_plugin.h
@@ -538,7 +538,7 @@ typedef int
const struct TALER_Amount *deposit_fee,
uint64_t transaction_id,
const struct GNUNET_HashCode *h_contract,
- const char *wire);
+ const json_t *wire);
/**
@@ -628,23 +628,23 @@ struct TALER_MINTDB_Plugin
* Commit a transaction.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion connection to use
+ * @param session connection to use
* @return #GNUNET_OK on success
*/
int
(*commit) (void *cls,
- struct TALER_MINTDB_Session *sesssion);
+ struct TALER_MINTDB_Session *session);
/**
* Abort/rollback a transaction.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion connection to use
+ * @param session connection to use
*/
void
(*rollback) (void *cls,
- struct TALER_MINTDB_Session *sesssion);
+ struct TALER_MINTDB_Session *session);
/**
@@ -653,7 +653,7 @@ struct TALER_MINTDB_Plugin
* with this key have.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion connection to use
+ * @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
@@ -669,7 +669,7 @@ struct TALER_MINTDB_Plugin
* Fetch information about a denomination key.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion connection to use
+ * @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
@@ -728,7 +728,7 @@ struct TALER_MINTDB_Plugin
* key of the hash of the blinded message.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection to use
+ * @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)
@@ -739,7 +739,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*get_withdraw_info) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *h_blind,
struct TALER_MINTDB_CollectableBlindcoin *collectable);
@@ -749,7 +749,7 @@ struct TALER_MINTDB_Plugin
* hash of the blinded message.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection to use
+ * @param session database connection to use
* @param collectable corresponding collectable coin (blind signature)
* if a coin is found
* @return #GNUNET_SYSERR on internal error
@@ -758,7 +758,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*insert_withdraw_info) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct TALER_MINTDB_CollectableBlindcoin *collectable);
@@ -767,13 +767,13 @@ struct TALER_MINTDB_Plugin
* reserve.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion connection to use
+ * @param session connection to use
* @param reserve_pub public key of the reserve
* @return known transaction history (NULL if reserve is unknown)
*/
struct TALER_MINTDB_ReserveHistory *
(*get_reserve_history) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct TALER_ReservePublicKeyP *reserve_pub);
@@ -792,7 +792,7 @@ struct TALER_MINTDB_Plugin
* Check if we have the specified deposit already in the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @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,
@@ -800,7 +800,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*have_deposit) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct TALER_MINTDB_Deposit *deposit);
@@ -808,13 +808,13 @@ struct TALER_MINTDB_Plugin
* Insert information about deposited coin into the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion connection to the database
+ * @param session connection to the database
* @param deposit deposit information to store
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
(*insert_deposit) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct TALER_MINTDB_Deposit *deposit);
@@ -822,10 +822,10 @@ struct TALER_MINTDB_Plugin
* Obtain information about deposits. Iterates over all deposits
* above a certain ID. Use a @a min_id of 0 to start at the beginning.
* This operation is executed in its own transaction in transaction
- * mode "READ COMMITTED", i.e. we should only see valid deposits.
+ * mode "REPEATABLE READ", i.e. we should only see valid deposits.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion connection to the database
+ * @param session connection to the database
* @param min_id deposit to start at
* @param limit maximum number of transactions to fetch
* @param deposit_cb function to call for each deposit
@@ -835,9 +835,9 @@ struct TALER_MINTDB_Plugin
*/
int
(*iterate_deposits) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
uint64_t min_id,
- unsigned int limit,
+ uint32_t limit,
TALER_MINTDB_DepositIterator deposit_cb,
void *deposit_cb_cls);
@@ -846,7 +846,7 @@ struct TALER_MINTDB_Plugin
* Lookup refresh session data under the given @a session_hash.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database handle to use
+ * @param session database handle to use
* @param session_hash hash over the melt to use for the lookup
* @param[out] refresh_session where to store the result
* @return #GNUNET_YES on success,
@@ -855,7 +855,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*get_refresh_session) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
struct TALER_MINTDB_RefreshSession *refresh_session);
@@ -864,7 +864,7 @@ struct TALER_MINTDB_Plugin
* Store new refresh session data under the given @a session_hash.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database handle to use
+ * @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,
@@ -872,7 +872,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*create_refresh_session) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
const struct TALER_MINTDB_RefreshSession *refresh_session);
@@ -881,7 +881,7 @@ struct TALER_MINTDB_Plugin
* Store the given /refresh/melt request in the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @param session database connection
* @param oldcoin_index index of the coin to store
* @param melt coin melt operation details to store; includes
* the session hash of the melt
@@ -890,7 +890,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*insert_refresh_melt) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
uint16_t oldcoin_index,
const struct TALER_MINTDB_RefreshMelt *melt);
@@ -899,7 +899,7 @@ struct TALER_MINTDB_Plugin
* Get information about melted coin details from the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @param session database connection
* @param session_hash hash to identify refresh session
* @param oldcoin_index index of the coin to retrieve
* @param melt melt data to fill in, can be NULL
@@ -908,7 +908,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*get_refresh_melt) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t oldcoin_index,
struct TALER_MINTDB_RefreshMelt *melt);
@@ -919,7 +919,7 @@ struct TALER_MINTDB_Plugin
* in a given refresh operation.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @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
@@ -928,7 +928,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*insert_refresh_order) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t num_newcoins,
const struct TALER_DenominationPublicKey *denom_pubs);
@@ -939,7 +939,7 @@ struct TALER_MINTDB_Plugin
* create in the given refresh operation.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @param session database connection
* @param session_hash hash to identify refresh session
* @param num_newcoins size of the @a denom_pubs array
* @param[out] denom_pubs where to write @a num_newcoins denomination keys
@@ -948,7 +948,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*get_refresh_order) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t num_newcoins,
struct TALER_DenominationPublicKey *denom_pubs);
@@ -959,7 +959,7 @@ struct TALER_MINTDB_Plugin
* for the given refresh session in the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection to use
+ * @param session database connection to use
* @param session_hash hash to identify refresh session
* @param cnc_index cut and choose index (1st dimension), relating to #TALER_CNC_KAPPA
* @param num_newcoins coin index size of the @a commit_coins array
@@ -969,7 +969,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*insert_refresh_commit_coins) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t cnc_index,
uint16_t num_newcoins,
@@ -981,7 +981,7 @@ struct TALER_MINTDB_Plugin
* given coin of the given refresh session from the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection to use
+ * @param session database connection to use
* @param session_hash hash to identify refresh session
* @param cnc_index cut and choose set index (1st dimension)
* @param num_coins size of the @a commit_coins array
@@ -992,7 +992,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*get_refresh_commit_coins) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t cnc_index,
uint16_t num_coins,
@@ -1004,7 +1004,7 @@ struct TALER_MINTDB_Plugin
* for the given refresh session.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection to use
+ * @param session database connection to use
* @param session_hash hash to identify refresh session
* @param cnc_index cut and choose index (1st dimension), relating to #TALER_CNC_KAPPA
* @param num_links size of the @a commit_link array
@@ -1013,7 +1013,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*insert_refresh_commit_links) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t cnc_index,
uint16_t num_links,
@@ -1024,7 +1024,7 @@ struct TALER_MINTDB_Plugin
* for the given refresh session.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection to use
+ * @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
@@ -1035,7 +1035,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*get_refresh_commit_links) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t cnc_index,
uint16_t num_links,
@@ -1046,14 +1046,14 @@ struct TALER_MINTDB_Plugin
* 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 sesssion database connection to use
+ * @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
*/
struct TALER_MINTDB_MeltCommitment *
(*get_melt_commitment) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash);
@@ -1075,7 +1075,7 @@ struct TALER_MINTDB_Plugin
* be used to try to obtain the private keys during "/refresh/link".
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @param session database connection
* @param session_hash hash to identify refresh session
* @param newcoin_index coin index
* @param ev_sig coin signature
@@ -1083,7 +1083,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*insert_refresh_out) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t newcoin_index,
const struct TALER_DenominationSignature *ev_sig);
@@ -1094,13 +1094,13 @@ struct TALER_MINTDB_Plugin
* information, the denomination keys and the signatures.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @param session database connection
* @param session_hash session to get linkage data for
* @return all known link data for the session
*/
struct TALER_MINTDB_LinkDataList *
(*get_link_data_list) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash);
@@ -1123,7 +1123,7 @@ struct TALER_MINTDB_Plugin
*
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @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
@@ -1133,7 +1133,7 @@ struct TALER_MINTDB_Plugin
*/
int
(*get_transfer) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
TALER_MINTDB_TransferDataCallback tdc,
void *tdc_cls);
@@ -1144,13 +1144,13 @@ struct TALER_MINTDB_Plugin
* with the given coin (/refresh/melt and /deposit operations).
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param sesssion database connection
+ * @param session database connection
* @param coin_pub coin to investigate
* @return list of transactions, NULL if coin is fresh
*/
struct TALER_MINTDB_TransactionList *
(*get_coin_transactions) (void *cls,
- struct TALER_MINTDB_Session *sesssion,
+ struct TALER_MINTDB_Session *session,
const struct TALER_CoinSpendPublicKeyP *coin_pub);
diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c
index efb73a321..86db0a11e 100644
--- a/src/mintdb/plugin_mintdb_postgres.c
+++ b/src/mintdb/plugin_mintdb_postgres.c
@@ -426,7 +426,7 @@ postgres_create_tables (void *cls,
/* 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 "
- "(id BIGSERIAL"
+ "(serial_id BIGSERIAL"
",coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)"
",denom_pub BYTEA NOT NULL REFERENCES denominations (pub)"
",denom_sig BYTEA NOT NULL"
@@ -852,8 +852,8 @@ postgres_prepare (PGconn *db_conn)
/* Used in #postgres_iterate_deposits() */
PREPARE ("deposits_iterate",
"SELECT"
- " id"
- " amount_with_fee_val"
+ " serial_id"
+ ",amount_with_fee_val"
",amount_with_fee_frac"
",amount_with_fee_curr"
",deposit_fee_val"
@@ -863,7 +863,8 @@ postgres_prepare (PGconn *db_conn)
",h_contract"
",wire"
" FROM deposits"
- " WHERE id>=$1"
+ " WHERE serial_id>=$1"
+ " ORDER BY serial_id ASC"
" LIMIT $2;",
2, NULL);
/* Used in #postgres_get_coin_transactions() to obtain information
@@ -1895,6 +1896,119 @@ postgres_have_deposit (void *cls,
/**
+ * Obtain information about deposits. Iterates over all deposits
+ * above a certain ID. Use a @a min_id of 0 to start at the beginning.
+ * This operation is executed in its own transaction in transaction
+ * mode "REPEATABLE READ", i.e. we should only see valid deposits.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param session connection to the database
+ * @param min_id deposit to start at
+ * @param limit maximum number of transactions to fetch
+ * @param deposit_cb function to call for each 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_iterate_deposits (void *cls,
+ struct TALER_MINTDB_Session *session,
+ uint64_t min_id,
+ uint32_t limit,
+ TALER_MINTDB_DepositIterator deposit_cb,
+ void *deposit_cb_cls)
+{
+ struct TALER_PQ_QueryParam params[] = {
+ TALER_PQ_query_param_uint64 (&min_id),
+ TALER_PQ_query_param_uint32 (&limit),
+ TALER_PQ_query_param_end
+ };
+ PGresult *result;
+ unsigned int i;
+ unsigned int n;
+
+ if (GNUNET_OK !=
+ postgres_start (cls, session))
+ return GNUNET_SYSERR;
+ result = PQexec (session->conn,
+ "SET TRANSACTION REPEATABLE READ");
+ if (PGRES_COMMAND_OK !=
+ PQresultStatus (result))
+ {
+ TALER_LOG_ERROR ("Failed to set transaction to REPEATABL EREAD: %s\n",
+ PQresultErrorMessage (result));
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ result = TALER_PQ_exec_prepared (session->conn,
+ "deposits_iterate",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ postgres_rollback (cls, session);
+ return GNUNET_SYSERR;
+ }
+ if (0 == (n = PQntuples (result)))
+ {
+ PQclear (result);
+ postgres_rollback (cls, session);
+ return 0;
+ }
+ for (i=0;i<n;i++)
+ {
+ struct TALER_Amount amount_with_fee;
+ struct TALER_Amount deposit_fee;
+ struct GNUNET_HashCode h_contract;
+ json_t *wire;
+ uint64_t transaction_id;
+ uint64_t id;
+ int ret;
+ struct TALER_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_uint64 ("id",
+ &id),
+ TALER_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),
+ TALER_PQ_result_spec_auto_from_type ("h_contract",
+ &h_contract),
+ TALER_PQ_result_spec_json ("wire",
+ &wire),
+ TALER_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ TALER_PQ_extract_result (result, rs, i))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ postgres_rollback (cls, session);
+ return GNUNET_SYSERR;
+ }
+ ret = deposit_cb (deposit_cb_cls,
+ id,
+ &amount_with_fee,
+ &deposit_fee,
+ transaction_id,
+ &h_contract,
+ wire);
+ TALER_PQ_cleanup_result (rs);
+ PQclear (result);
+ if (GNUNET_OK != ret)
+ break;
+ }
+ postgres_rollback (cls, session);
+ return i;
+}
+
+
+/**
* Insert information about deposited coin into the database.
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
@@ -3280,6 +3394,7 @@ libtaler_plugin_mintdb_postgres_init (void *cls)
plugin->get_reserve_history = &postgres_get_reserve_history;
plugin->free_reserve_history = &common_free_reserve_history;
plugin->have_deposit = &postgres_have_deposit;
+ plugin->iterate_deposits = &postgres_iterate_deposits;
plugin->insert_deposit = &postgres_insert_deposit;
plugin->get_refresh_session = &postgres_get_refresh_session;