diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-06-11 13:02:57 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-06-11 13:02:57 +0200 |
commit | babeff1968b4076fa2f570af8c994727dd8fa09f (patch) | |
tree | a929ac352a8e71bd60cbf87ab4c2993707322812 | |
parent | 95f4cdc6df73955675ab07a98455bf9bf8c3e8e8 (diff) | |
download | exchange-babeff1968b4076fa2f570af8c994727dd8fa09f.tar.xz |
fix #3825
-rw-r--r-- | src/include/taler_mintdb_plugin.h | 17 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_db.c | 20 | ||||
-rw-r--r-- | src/mintdb/plugin_mintdb_postgres.c | 165 | ||||
-rw-r--r-- | src/mintdb/test_mintdb.c | 29 |
4 files changed, 123 insertions, 108 deletions
diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index 27bd46a52..d8644df8d 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -744,9 +744,9 @@ struct TALER_MINTDB_Plugin */ int (*get_withdraw_info) (void *cls, - struct TALER_MINTDB_Session *sesssion, - const struct GNUNET_HashCode *h_blind, - struct TALER_MINTDB_CollectableBlindcoin *collectable); + struct TALER_MINTDB_Session *sesssion, + const struct GNUNET_HashCode *h_blind, + struct TALER_MINTDB_CollectableBlindcoin *collectable); /** @@ -755,11 +755,6 @@ struct TALER_MINTDB_Plugin * * @param cls the @e cls of this struct with the plugin-specific state * @param sesssion database connection to use - * @param h_blind hash of the blinded message which is (blindly) signed by the - * signature in @a collectable - * @param withdraw amount by which the reserve will be withdrawn with this - * transaction (based on the value of the denomination key - * used for the signature); coin value plus fee. * @param collectable corresponding collectable coin (blind signature) * if a coin is found * @return #GNUNET_SYSERR on internal error @@ -768,10 +763,8 @@ struct TALER_MINTDB_Plugin */ int (*insert_withdraw_info) (void *cls, - struct TALER_MINTDB_Session *sesssion, - const struct GNUNET_HashCode *h_blind, - struct TALER_Amount withdraw, - const struct TALER_MINTDB_CollectableBlindcoin *collectable); + struct TALER_MINTDB_Session *sesssion, + const struct TALER_MINTDB_CollectableBlindcoin *collectable); /** diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index b97b30d35..26122d1e1 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -294,9 +294,9 @@ TMH_DB_execute_withdraw_sign (struct MHD_Connection *connection, return TMH_RESPONSE_reply_internal_db_error (connection); } res = TMH_plugin->get_withdraw_info (TMH_plugin->cls, - session, - &h_blind, - &collectable); + session, + &h_blind, + &collectable); if (GNUNET_SYSERR == res) { GNUNET_break (0); @@ -446,17 +446,15 @@ TMH_DB_execute_withdraw_sign (struct MHD_Connection *connection, } collectable.sig.rsa_signature = sig; collectable.denom_pub = *denomination_pub; + collectable.amount_with_fee = amount_required; + collectable.withdraw_fee = fee_withdraw; collectable.reserve_pub = *reserve; - GNUNET_CRYPTO_hash (blinded_msg, - blinded_msg_len, - &collectable.h_coin_envelope); + collectable.h_coin_envelope = h_blind; collectable.reserve_sig = *signature; if (GNUNET_OK != TMH_plugin->insert_withdraw_info (TMH_plugin->cls, - session, - &h_blind, - amount_required, - &collectable)) + session, + &collectable)) { GNUNET_break (0); GNUNET_CRYPTO_rsa_signature_free (sig); @@ -871,7 +869,7 @@ check_commitment (struct MHD_Connection *connection, &transfer_privs[j], &melts[j].coin.coin_pub, &shared_secret)) - { + { GNUNET_free (commit_links); return (MHD_YES == TMH_RESPONSE_reply_internal_error (connection, diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index 850a26be3..706b92dcf 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -266,19 +266,21 @@ postgres_create_tables (void *cls, 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). */ - /* TODO: maybe add withdraw fee and amount_with_fee explicitly to table, - so we can init those fields on select? #3825 - TODO: maybe add timestamp of when the operation was performed, so we - can influence the reserves' expiration_date not just based on - incoming but also based on outgoing transactions? */ - SQLEXEC ("CREATE TABLE IF NOT EXISTS reserves_out" + 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_blindcoins statement */ + /* Index blindcoins(reserve_pub) for get_reserves_out statement */ SQLEXEC_INDEX ("CREATE INDEX reserves_out_reserve_pub_index ON" " reserves_out (reserve_pub)"); /* Table with coins that have been (partially) spent, used to track @@ -529,9 +531,16 @@ postgres_prepare (PGconn *db_conn) ",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);", - 5, NULL); + "($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 /withdraw/sign request using the hash of the blinded message. Used to @@ -542,6 +551,13 @@ postgres_prepare (PGconn *db_conn) ",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); @@ -549,12 +565,19 @@ postgres_prepare (PGconn *db_conn) obtain all of the /withdraw/sign operations that have been performed on a given reserve. (i.e. to demonstrate double-spending) */ - PREPARE ("get_reserves_blindcoins", + 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); @@ -1273,17 +1296,15 @@ postgres_reserves_in_insert (void *cls, */ static int postgres_get_withdraw_info (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *h_blind, - struct TALER_MINTDB_CollectableBlindcoin *collectable) + struct TALER_MINTDB_Session *session, + const struct GNUNET_HashCode *h_blind, + struct TALER_MINTDB_CollectableBlindcoin *collectable) { PGresult *result; struct TALER_PQ_QueryParam params[] = { TALER_PQ_query_param_auto_from_type (h_blind), TALER_PQ_query_param_end }; - struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub; - struct GNUNET_CRYPTO_rsa_Signature *denom_sig; int ret; ret = GNUNET_SYSERR; @@ -1301,31 +1322,35 @@ postgres_get_withdraw_info (void *cls, ret = GNUNET_NO; goto cleanup; } - struct TALER_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_rsa_public_key("denom_pub", &denom_pub), - TALER_PQ_result_spec_rsa_signature("denom_sig", &denom_sig), - TALER_PQ_result_spec_auto_from_type("reserve_sig", &collectable->reserve_sig), - TALER_PQ_result_spec_auto_from_type("reserve_pub", &collectable->reserve_pub), - /* FIXME: collectable->amount_with_fee and - collectable->withdraw_fee not initialized! (#3825) */ - TALER_PQ_result_spec_end - }; - - if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) { - GNUNET_break (0); - goto cleanup; + struct TALER_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_rsa_public_key ("denom_pub", + &collectable->denom_pub.rsa_public_key), + TALER_PQ_result_spec_rsa_signature ("denom_sig", + &collectable->sig.rsa_signature), + TALER_PQ_result_spec_auto_from_type ("reserve_sig", + &collectable->reserve_sig), + TALER_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), + TALER_PQ_result_spec_end + }; + + if (GNUNET_OK != + TALER_PQ_extract_result (result, rs, 0)) + { + GNUNET_break (0); + goto cleanup; + } } - /* FIXME: why do we bother with the temporary variables? */ - collectable->denom_pub.rsa_public_key = denom_pub; - collectable->sig.rsa_signature = denom_sig; collectable->h_coin_envelope = *h_blind; ret = GNUNET_YES; cleanup: PQclear (result); - if (GNUNET_YES != ret) - TALER_PQ_cleanup_result (rs); return ret; } @@ -1336,11 +1361,6 @@ postgres_get_withdraw_info (void *cls, * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param session database connection to use - * @param h_blind hash of the blinded message. FIXME: - * redundant information given @a collectable's h_coin_envelope, right? #3825 - * @param withdraw amount by which the reserve will be reduced with this - * transaction (coin value plus fee). FIXME: - * redundant information given @a collectable's amount_with_fee! #3825 * @param collectable corresponding collectable coin (blind signature) * if a coin is found * @return #GNUNET_SYSERR on internal error @@ -1349,21 +1369,22 @@ postgres_get_withdraw_info (void *cls, */ static int postgres_insert_withdraw_info (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *h_blind, - struct TALER_Amount withdraw, - const struct TALER_MINTDB_CollectableBlindcoin *collectable) + 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 = GNUNET_TIME_absolute_get (); struct TALER_PQ_QueryParam params[] = { - TALER_PQ_query_param_auto_from_type (h_blind), + TALER_PQ_query_param_auto_from_type (&collectable->h_coin_envelope), TALER_PQ_query_param_rsa_public_key (collectable->denom_pub.rsa_public_key), TALER_PQ_query_param_rsa_signature (collectable->sig.rsa_signature), TALER_PQ_query_param_auto_from_type (&collectable->reserve_pub), TALER_PQ_query_param_auto_from_type (&collectable->reserve_sig), - /* FIXME: store fees? #3825 */ + TALER_PQ_query_param_absolute_time (&now), + TALER_PQ_query_param_amount (&collectable->amount_with_fee), + TALER_PQ_query_param_amount (&collectable->withdraw_fee), TALER_PQ_query_param_end }; @@ -1392,7 +1413,7 @@ postgres_insert_withdraw_info (void *cls, if (GNUNET_SYSERR == TALER_amount_subtract (&reserve.balance, &reserve.balance, - &withdraw)) + &collectable->amount_with_fee)) { /* Should have been checked before we got here... */ GNUNET_break (0); @@ -1501,11 +1522,6 @@ postgres_get_reserve_history (void *cls, PQclear (result); } { - struct GNUNET_HashCode h_blind_ev; - struct TALER_ReserveSignatureP reserve_sig; - struct TALER_MINTDB_CollectableBlindcoin *cbc; - struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub; - struct GNUNET_CRYPTO_rsa_Signature *denom_sig; struct TALER_PQ_QueryParam params[] = { TALER_PQ_query_param_auto_from_type (reserve_pub), TALER_PQ_query_param_end @@ -1515,7 +1531,7 @@ postgres_get_reserve_history (void *cls, GNUNET_assert (NULL != rh_tail); GNUNET_assert (NULL == rh_tail->next); result = TALER_PQ_exec_prepared (session->conn, - "get_reserves_blindcoins", + "get_reserves_out", params); if (PGRES_TUPLES_OK != PQresultStatus (result)) { @@ -1526,28 +1542,35 @@ postgres_get_reserve_history (void *cls, rows = PQntuples (result); while (0 < rows) { - struct TALER_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_auto_from_type ("h_blind_ev", &h_blind_ev), - TALER_PQ_result_spec_rsa_public_key ("denom_pub", &denom_pub), - TALER_PQ_result_spec_rsa_signature ("denom_sig", &denom_sig), - TALER_PQ_result_spec_auto_from_type ("reserve_sig", &reserve_sig), - TALER_PQ_result_spec_end - }; - - if (GNUNET_YES != - TALER_PQ_extract_result (result, rs, --rows)) + struct TALER_MINTDB_CollectableBlindcoin *cbc; + + cbc = GNUNET_new (struct TALER_MINTDB_CollectableBlindcoin); { - GNUNET_break (0); - PQclear (result); - goto cleanup; + struct TALER_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_auto_from_type ("h_blind_ev", + &cbc->h_coin_envelope), + TALER_PQ_result_spec_rsa_public_key ("denom_pub", + &cbc->denom_pub.rsa_public_key), + TALER_PQ_result_spec_rsa_signature ("denom_sig", + &cbc->sig.rsa_signature), + TALER_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), + TALER_PQ_result_spec_end + }; + if (GNUNET_YES != + TALER_PQ_extract_result (result, rs, --rows)) + { + GNUNET_break (0); + GNUNET_free (cbc); + PQclear (result); + goto cleanup; + } + cbc->reserve_pub = *reserve_pub; } - cbc = GNUNET_new (struct TALER_MINTDB_CollectableBlindcoin); - cbc->sig.rsa_signature = denom_sig; - cbc->denom_pub.rsa_public_key = denom_pub; - /* FIXME: amount_with_fee and withdraw_fee not initialized! #3825 */ - cbc->h_coin_envelope = h_blind_ev; - cbc->reserve_pub = *reserve_pub; - cbc->reserve_sig = reserve_sig; rh_tail->next = GNUNET_new (struct TALER_MINTDB_ReserveHistory); rh_tail = rh_tail->next; rh_tail->type = TALER_MINTDB_RO_WITHDRAW_COIN; diff --git a/src/mintdb/test_mintdb.c b/src/mintdb/test_mintdb.c index d1f554a1d..0bdcec365 100644 --- a/src/mintdb/test_mintdb.c +++ b/src/mintdb/test_mintdb.c @@ -14,7 +14,7 @@ TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> */ /** - * @file mint/test_mint_db.c + * @file mint/test_mintdb.c * @brief test cases for DB interaction functions * @author Sree Harsha Totakura <sreeharsha@totakura.in> */ @@ -239,7 +239,6 @@ run (void *cls, struct GNUNET_TIME_Absolute expiry; struct TALER_Amount amount; struct DenomKeyPair *dkp; - struct GNUNET_HashCode h_blind; struct TALER_MINTDB_CollectableBlindcoin cbc; struct TALER_MINTDB_CollectableBlindcoin cbc2; struct TALER_MINTDB_ReserveHistory *rh; @@ -321,24 +320,25 @@ run (void *cls, amount.currency, expiry.abs_value_us)); dkp = create_denom_key_pair (1024, session); - RND_BLK(&h_blind); + 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, - &h_blind, - sizeof (h_blind)); + &cbc.h_coin_envelope, + sizeof (cbc.h_coin_envelope)); (void) memcpy (&cbc.reserve_pub, &reserve_pub, sizeof (reserve_pub)); amount.value--; amount.fraction--; + cbc.amount_with_fee = amount; + GNUNET_assert (GNUNET_OK == + TALER_amount_get_zero (CURRENCY, &cbc.withdraw_fee)); FAILIF (GNUNET_OK != plugin->insert_withdraw_info (plugin->cls, - session, - &h_blind, - amount, - &cbc)); + session, + &cbc)); FAILIF (GNUNET_OK != check_reserve (session, &reserve_pub, @@ -348,9 +348,9 @@ run (void *cls, expiry.abs_value_us)); FAILIF (GNUNET_YES != plugin->get_withdraw_info (plugin->cls, - session, - &h_blind, - &cbc2)); + session, + &cbc.h_coin_envelope, + &cbc2)); FAILIF (NULL == cbc2.denom_pub.rsa_public_key); FAILIF (0 != memcmp (&cbc2.reserve_sig, &cbc.reserve_sig, @@ -359,7 +359,7 @@ run (void *cls, &cbc.reserve_pub, sizeof (cbc2.reserve_pub))); FAILIF (GNUNET_OK != - GNUNET_CRYPTO_rsa_verify (&h_blind, + GNUNET_CRYPTO_rsa_verify (&cbc.h_coin_envelope, cbc2.sig.rsa_signature, dkp->pub.rsa_public_key)); rh = plugin->get_reserve_history (plugin->cls, @@ -387,7 +387,8 @@ run (void *cls, &reserve_pub, sizeof (reserve_pub))); FAILIF (0 != memcmp (&withdraw->h_coin_envelope, - &h_blind, sizeof (h_blind))); + &cbc.h_coin_envelope, + sizeof (cbc.h_coin_envelope))); break; } } |