From f8a730a0ab6db9ca37c652493b844a7a5ff503e0 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 19 Sep 2015 20:02:21 +0200 Subject: [PATCH] fixing #3816: adding 'id' field to uniquely identify each deposit --- src/include/taler_mintdb_plugin.h | 52 +++++++++++++++++++++++++++-- src/mintdb/plugin_mintdb_postgres.c | 29 +++++++++++----- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index 14518d284..4e06fc86f 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -516,6 +516,31 @@ struct TALER_MINTDB_MeltCommitment struct TALER_MINTDB_Session; +/** + * Function called with details about deposits that + * have been made, with the goal of executing the + * corresponding wire transaction. + * + * @param cls closure + * @param id transaction ID (used as future `min_id` to avoid + * iterating over transactions more than once) + * @param amount_with_fee amount that was deposited including fee + * @param deposit_fee amount the mint gets to keep as transaction fees + * @param transaction_id unique transaction ID chosen by the merchant + * @param h_contract hash of the contract between merchant and customer + * @param wire wire details for the merchant + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef int +(*TALER_MINTDB_DepositIterator)(void *cls, + uint64_t id, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *deposit_fee, + uint64_t transaction_id, + const struct GNUNET_HashCode *h_contract, + const char *wire); + + /** * Function called with the session hashes and transfer secret * information for a given coin. @@ -780,8 +805,7 @@ struct TALER_MINTDB_Plugin /** - * Insert information about deposited coin into the - * database. + * 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 @@ -794,6 +818,30 @@ struct TALER_MINTDB_Plugin const struct TALER_MINTDB_Deposit *deposit); + /** + * 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. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param sesssion 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 + */ + int + (*iterate_deposits) (void *cls, + struct TALER_MINTDB_Session *sesssion, + uint64_t min_id, + unsigned int limit, + TALER_MINTDB_DepositIterator deposit_cb, + void *deposit_cb_cls); + + /** * Lookup refresh session data under the given @a session_hash. * diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index f47e31b43..efb73a321 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -424,15 +424,10 @@ postgres_create_tables (void *cls, ",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). - TODO: we might want to generate some other primary key - to internally identify outgoing transactions, as "coin_pub" - may not be unique if a wallet chooses not to refresh. The - resulting transaction ID should then be returned to the merchant - and could be used by the mearchant for further inquriries about - the deposit's execution. (#3816); */ + execute to transmit funds to the merchants (and manage refunds). */ SQLEXEC("CREATE TABLE IF NOT EXISTS deposits " - "(coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)" + "(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" ",transaction_id INT8 NOT NULL" @@ -853,6 +848,24 @@ postgres_prepare (PGconn *db_conn) " (merchant_pub=$3)" " )", 3, NULL); + + /* Used in #postgres_iterate_deposits() */ + PREPARE ("deposits_iterate", + "SELECT" + " id" + " amount_with_fee_val" + ",amount_with_fee_frac" + ",amount_with_fee_curr" + ",deposit_fee_val" + ",deposit_fee_frac" + ",deposit_fee_curr" + ",transaction_id" + ",h_contract" + ",wire" + " FROM deposits" + " WHERE id>=$1" + " LIMIT $2;", + 2, 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",