From 737301c8d07bf3112b515fa035611af32ab129ce Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 20 Jan 2015 17:50:32 +0100 Subject: [PATCH] towards separating out DB operations during refresh --- src/mint/mint_db.c | 3 +- src/mint/mint_db.h | 3 +- src/mint/taler-mint-httpd_keys.c | 6 +- src/mint/taler-mint-httpd_refresh.c | 240 +++++++++++++++----------- src/mint/taler-mint-httpd_responses.c | 27 ++- 5 files changed, 159 insertions(+), 120 deletions(-) diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c index 372fc937d..af900b5d7 100644 --- a/src/mint/mint_db.c +++ b/src/mint/mint_db.c @@ -829,7 +829,8 @@ TALER_MINT_DB_get_refresh_session (PGconn *db_conn, int -TALER_MINT_DB_get_known_coin (PGconn *db_conn, struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub, +TALER_MINT_DB_get_known_coin (PGconn *db_conn, + const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub, struct KnownCoin *known_coin) { int res; diff --git a/src/mint/mint_db.h b/src/mint/mint_db.h index d5a74a45d..5eaa367d7 100644 --- a/src/mint/mint_db.h +++ b/src/mint/mint_db.h @@ -81,7 +81,8 @@ TALER_MINT_DB_get_refresh_session (PGconn *db_conn, int -TALER_MINT_DB_get_known_coin (PGconn *db_conn, struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub, +TALER_MINT_DB_get_known_coin (PGconn *db_conn, + const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub, struct KnownCoin *known_coin); diff --git a/src/mint/taler-mint-httpd_keys.c b/src/mint/taler-mint-httpd_keys.c index 01679718e..ac792f7fe 100644 --- a/src/mint/taler-mint-httpd_keys.c +++ b/src/mint/taler-mint-httpd_keys.c @@ -356,9 +356,9 @@ TALER_MINT_get_denom_key (const struct MintKeyState *key_state, * * @param key_state the key state to use for checking the coin's validity * @param coin_public_info the coin public info to check for validity - * @return GNUNET_YES if the coin is valid, - * GNUNET_NO if it is invalid - * GNUNET_SYSERROR if an internal error occured + * @return #GNUNET_YES if the coin is valid, + * #GNUNET_NO if it is invalid + * #GNUNET_SYSERROR if an internal error occured */ int TALER_MINT_test_coin_valid (const struct MintKeyState *key_state, diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 8b18e9a66..b209f4fde 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -79,7 +79,8 @@ link_iter (void *cls, * @param db_conn the database connection * @param key_state the mint's key state to use * @param session_pub the refresh session public key - * @param root the request JSON object + * @param denom_pubs_count number of entries in @a denom_pubs + * @param denom_pubs array of public keys for the refresh * @param hash_context the hash context where accepted * denominations will be hased into * @param r_amount the sum of the cost (value+fee) for @@ -91,60 +92,36 @@ refresh_accept_denoms (struct MHD_Connection *connection, PGconn *db_conn, const struct MintKeyState *key_state, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, - const json_t *root, + unsigned int denom_pubs_count, + const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs, struct GNUNET_HashContext *hash_context, struct TALER_Amount *r_amount) { - unsigned i; + unsigned int i; int res; - json_t *new_denoms; - - res = GNUNET_MINT_parse_navigate_json (connection, root, - JNAV_FIELD, "new_denoms", - JNAV_RET_TYPED_JSON, - JSON_ARRAY, - &new_denoms); - if (GNUNET_OK != res) - return res; + struct TALER_MINT_DenomKeyIssue *dki; + struct TALER_Amount cost; memset (r_amount, 0, sizeof (struct TALER_Amount)); - - for (i = 0; i < json_array_size (new_denoms); i++) + for (i = 0; i < denom_pubs_count; i++) { - struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; - int res; - struct TALER_MINT_DenomKeyIssue *dki; - struct TALER_Amount cost; - - res = GNUNET_MINT_parse_navigate_json (connection, root, - JNAV_FIELD, "new_denoms", - JNAV_INDEX, (int) i, - JNAV_RET_DATA, - &denom_pub, - sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); - - if (GNUNET_OK != res) - return res; - - dki = &(TALER_MINT_get_denom_key (key_state, &denom_pub)->issue); - + dki = &(TALER_MINT_get_denom_key (key_state, &denom_pubs[i])->issue); GNUNET_CRYPTO_hash_context_read (hash_context, - &denom_pub, + &denom_pubs[i], sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); - cost = TALER_amount_add (TALER_amount_ntoh (dki->value), TALER_amount_ntoh (dki->fee_withdraw)); - *r_amount = TALER_amount_add (cost, *r_amount); + /* Insert the requested coin into the DB, so we'll know later * what denomination the request had */ if (GNUNET_OK != - TALER_MINT_DB_insert_refresh_order (db_conn, - i, - session_pub, - &denom_pub)) + (res = TALER_MINT_DB_insert_refresh_order (db_conn, + i, + session_pub, + &denom_pubs[i]))) return res; // ??? } return GNUNET_OK; @@ -268,7 +245,8 @@ request_json_require_coin_public_info (struct MHD_Connection *connection, * @param db_conn the database connection * @param key_state the mint's key state * @param session_pub the refresh session's public key - * @param root the JSON object + * @param coin_count number of coins in @a coin_public_infos to melt + * @param coin_public_infos the coins to melt * @param hash_context the hash context that will receive * the coin public keys of the melted coin * @return #GNUNET_OK on success, @@ -280,54 +258,27 @@ refresh_accept_melts (struct MHD_Connection *connection, PGconn *db_conn, const struct MintKeyState *key_state, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, - json_t *root, + unsigned int coin_count, + const struct TALER_CoinPublicInfo *coin_public_infos, struct GNUNET_HashContext *hash_context, struct TALER_Amount *r_melt_balance) { size_t i; int res; - json_t *melt_coins; - - res = GNUNET_MINT_parse_navigate_json (connection, root, - JNAV_FIELD, "melt_coins", - JNAV_RET_TYPED_JSON, - JSON_ARRAY, - &melt_coins); - if (GNUNET_OK != res) - return res; memset (r_melt_balance, 0, sizeof (struct TALER_Amount)); - for (i = 0; i < json_array_size (melt_coins); i++) + for (i = 0; i < coin_count; i++) { - struct TALER_CoinPublicInfo coin_public_info; struct TALER_MINT_DenomKeyIssue *dki; struct KnownCoin known_coin; // money the customer gets by melting the current coin struct TALER_Amount coin_gain; - res = request_json_require_coin_public_info (connection, - json_array_get (melt_coins, i), - &coin_public_info); - if (GNUNET_OK != res) - { - GNUNET_break (GNUNET_SYSERR != res); - return res; - } - - if (GNUNET_OK != (res = check_confirm_signature (connection, - json_array_get (melt_coins, i), - &coin_public_info.coin_pub, - session_pub))) - { - GNUNET_break (GNUNET_SYSERR != res); - return res; - } - GNUNET_CRYPTO_hash_context_read (hash_context, - &coin_public_info.coin_pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); - - dki = &(TALER_MINT_get_denom_key (key_state, &coin_public_info.denom_pub)->issue); + &coin_public_infos[i].coin_pub, + sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); + dki = &(TALER_MINT_get_denom_key (key_state, &coin_public_infos[i].denom_pub)->issue); if (NULL == dki) return (MHD_YES == @@ -337,15 +288,9 @@ refresh_accept_melts (struct MHD_Connection *connection, "error", "denom not found")) ? GNUNET_NO : GNUNET_SYSERR; - if (GNUNET_OK != TALER_MINT_test_coin_valid (key_state, &coin_public_info)) - return (MHD_YES == - TALER_MINT_reply_json_pack (connection, - MHD_HTTP_NOT_FOUND, - "{s:s}", - "error", "coin invalid")) - ? GNUNET_NO : GNUNET_SYSERR; - res = TALER_MINT_DB_get_known_coin (db_conn, &coin_public_info.coin_pub, + res = TALER_MINT_DB_get_known_coin (db_conn, + &coin_public_infos[i].coin_pub, &known_coin); if (GNUNET_SYSERR == res) @@ -368,7 +313,7 @@ refresh_accept_melts (struct MHD_Connection *connection, else { known_coin.expended_balance = mint_amount_native_zero (); - known_coin.public_info = coin_public_info; + known_coin.public_info = coin_public_infos[i]; } known_coin.is_refreshed = GNUNET_YES; @@ -381,8 +326,8 @@ refresh_accept_melts (struct MHD_Connection *connection, } if (GNUNET_OK != TALER_MINT_DB_insert_refresh_melt (db_conn, session_pub, i, - &coin_public_info.coin_pub, - &coin_public_info.denom_pub)) + &coin_public_infos[i].coin_pub, + &coin_public_infos[i].denom_pub)) { GNUNET_break (0); return GNUNET_SYSERR; @@ -527,6 +472,13 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh, struct GNUNET_HashContext *hash_context; struct GNUNET_HashCode melt_hash; struct RefreshSession session; + json_t *new_denoms; + unsigned int num_new_denoms; + unsigned int i; + struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs; + json_t *melt_coins; + struct TALER_CoinPublicInfo *coin_public_infos; + unsigned int coin_count; res = TALER_MINT_parse_post_json (connection, connection_cls, @@ -538,12 +490,6 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh, if ( (GNUNET_NO == res) || (NULL == root) ) return MHD_YES; - if (NULL == (db_conn = TALER_MINT_DB_get_connection ())) - { - /* FIXME: return error code to MHD! */ - return MHD_NO; - } - /* session_pub field must always be present */ res = GNUNET_MINT_parse_navigate_json (connection, root, JNAV_FIELD, "session_pub", @@ -559,9 +505,99 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh, if (GNUNET_NO == res) return MHD_YES; + res = GNUNET_MINT_parse_navigate_json (connection, root, + JNAV_FIELD, "new_denoms", + JNAV_RET_TYPED_JSON, + JSON_ARRAY, + &new_denoms); + if (GNUNET_OK != res) + return res; + num_new_denoms = json_array_size (new_denoms); + denom_pubs = GNUNET_malloc (num_new_denoms * + sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); + + for (i=0;i