diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/exchange-lib/exchange_api_refresh.c | 259 | ||||
-rw-r--r-- | src/exchange-lib/test_exchange_api.c | 94 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_db.c | 295 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_db.h | 14 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_refresh.c | 330 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_responses.c | 80 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_responses.h | 2 | ||||
-rw-r--r-- | src/exchangedb/perf_taler_exchangedb.c | 5 | ||||
-rw-r--r-- | src/exchangedb/perf_taler_exchangedb_init.c | 3 | ||||
-rw-r--r-- | src/exchangedb/perf_taler_exchangedb_interpreter.c | 121 | ||||
-rw-r--r-- | src/exchangedb/perf_taler_exchangedb_interpreter.h | 77 | ||||
-rw-r--r-- | src/exchangedb/plugin_exchangedb_common.c | 10 | ||||
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 483 | ||||
-rw-r--r-- | src/exchangedb/test_exchangedb.c | 120 | ||||
-rw-r--r-- | src/include/taler_exchange_service.h | 44 | ||||
-rw-r--r-- | src/include/taler_exchangedb_plugin.h | 135 |
16 files changed, 634 insertions, 1438 deletions
diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c index 91bcca180..ad2195689 100644 --- a/src/exchange-lib/exchange_api_refresh.c +++ b/src/exchange-lib/exchange_api_refresh.c @@ -241,20 +241,14 @@ struct MeltData struct TALER_LinkSecretP link_secrets[TALER_CNC_KAPPA]; /** - * Number of coins we are melting - */ - uint16_t num_melted_coins; - - /** * Number of coins we are creating */ uint16_t num_fresh_coins; /** - * Information about the melted coins in an array of length @e - * num_melted_coins. + * Information about the melted coin. */ - struct MeltedCoin *melted_coins; + struct MeltedCoin melted_coin; /** * Array of @e num_fresh_coins denomination keys for the coins to be @@ -279,8 +273,6 @@ struct MeltData static void free_melted_coin (struct MeltedCoin *mc) { - if (NULL == mc) - return; if (NULL != mc->pub_key.rsa_public_key) GNUNET_CRYPTO_rsa_public_key_free (mc->pub_key.rsa_public_key); if (NULL != mc->sig.rsa_signature) @@ -319,12 +311,7 @@ free_melt_data (struct MeltData *md) unsigned int i; unsigned int j; - if (NULL != md->melted_coins) - { - for (i=0;i<md->num_melted_coins;i++) - free_melted_coin (&md->melted_coins[i]); - GNUNET_free (md->melted_coins); - } + free_melted_coin (&md->melted_coin); if (NULL != md->fresh_pks) { for (i=0;i<md->num_fresh_coins;i++) @@ -694,13 +681,11 @@ serialize_melt_data (const struct MeltData *md, mdp->melt_session_hash = md->melt_session_hash; for (i=0;i<TALER_CNC_KAPPA;i++) mdp->link_secrets[i] = md->link_secrets[i]; - mdp->num_melted_coins = htons (md->num_melted_coins); mdp->num_fresh_coins = htons (md->num_fresh_coins); } - for (i=0;i<md->num_melted_coins;i++) - size += serialize_melted_coin (&md->melted_coins[i], - buf, - size); + size += serialize_melted_coin (&md->melted_coin, + buf, + size); for (i=0;i<md->num_fresh_coins;i++) size += serialize_denomination_key (&md->fresh_pks[i], buf, @@ -744,10 +729,7 @@ deserialize_melt_data (const char *buf, md->melt_session_hash = mdp.melt_session_hash; for (i=0;i<TALER_CNC_KAPPA;i++) md->link_secrets[i] = mdp.link_secrets[i]; - md->num_melted_coins = ntohs (mdp.num_melted_coins); md->num_fresh_coins = ntohs (mdp.num_fresh_coins); - md->melted_coins = GNUNET_new_array (md->num_melted_coins, - struct MeltedCoin); md->fresh_pks = GNUNET_new_array (md->num_fresh_coins, struct TALER_DenominationPublicKey); for (i=0;i<TALER_CNC_KAPPA;i++) @@ -755,11 +737,10 @@ deserialize_melt_data (const char *buf, struct FreshCoin); off = sizeof (struct MeltDataP); ok = GNUNET_YES; - for (i=0;(i<md->num_melted_coins)&&(GNUNET_YES == ok);i++) - off += deserialize_melted_coin (&md->melted_coins[i], - &buf[off], - buf_size - off, - &ok); + off += deserialize_melted_coin (&md->melted_coin, + &buf[off], + buf_size - off, + &ok); for (i=0;(i<md->num_fresh_coins)&&(GNUNET_YES == ok);i++) off += deserialize_denomination_key (&md->fresh_pks[i], &buf[off], @@ -831,17 +812,16 @@ setup_fresh_coin (struct FreshCoin *fc, * its result immediately and does not start any asynchronous * processing. This function is also thread-safe. * - * @param num_melts number of coins that are being melted (typically 1) - * @param melt_privs array of @a num_melts private keys of the coins to melt - * @param melt_amounts array of @a num_melts amounts specifying how much - * each coin will contribute to the melt (including fee) - * @param melt_sigs array of @a num_melts signatures affirming the + * @param melt_priv private key of the coin to melt + * @param melt_amount amount specifying how much + * the coin will contribute to the melt (including fee) + * @param melt_sig signature affirming the * validity of the public keys corresponding to the - * @a melt_privs private keys - * @param melt_pks array of @a num_melts denomination key information - * records corresponding to the @a melt_sigs + * @a melt_priv private key + * @param melt_pk denomination key information + * record corresponding to the @a melt_sig * validity of the keys - * @param check_sigs verify the validity of the signatures of @a melt_sigs + * @param check_sig verify the validity of the @a melt_sig signature * @param fresh_pks_len length of the @a pks array * @param fresh_pks array of @a pks_len denominations of fresh coins to create * @param[out] res_size set to the size of the return value, or 0 on error @@ -852,15 +832,14 @@ setup_fresh_coin (struct FreshCoin *fc, * Non-null results should be freed using #GNUNET_free(). */ char * -TALER_EXCHANGE_refresh_prepare (unsigned int num_melts, - const struct TALER_CoinSpendPrivateKeyP *melt_privs, - const struct TALER_Amount *melt_amounts, - const struct TALER_DenominationSignature *melt_sigs, - const struct TALER_EXCHANGE_DenomPublicKey *melt_pks, - int check_sigs, - unsigned int fresh_pks_len, - const struct TALER_EXCHANGE_DenomPublicKey *fresh_pks, - size_t *res_size) +TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_priv, + const struct TALER_Amount *melt_amount, + const struct TALER_DenominationSignature *melt_sig, + const struct TALER_EXCHANGE_DenomPublicKey *melt_pk, + int check_sig, + unsigned int fresh_pks_len, + const struct TALER_EXCHANGE_DenomPublicKey *fresh_pks, + size_t *res_size) { struct MeltData md; char *buf; @@ -873,31 +852,25 @@ TALER_EXCHANGE_refresh_prepare (unsigned int num_melts, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, &md.link_secrets[i], sizeof (struct TALER_LinkSecretP)); - md.num_melted_coins = num_melts; md.num_fresh_coins = fresh_pks_len; - md.melted_coins = GNUNET_new_array (num_melts, - struct MeltedCoin); - for (i=0;i<num_melts;i++) + md.melted_coin.coin_priv = *melt_priv; + md.melted_coin.melt_amount_with_fee = *melt_amount; + md.melted_coin.fee_melt = melt_pk->fee_refresh; + md.melted_coin.original_value = melt_pk->value; + for (j=0;j<TALER_CNC_KAPPA;j++) { - md.melted_coins[i].coin_priv = melt_privs[i]; - md.melted_coins[i].melt_amount_with_fee = melt_amounts[i]; - md.melted_coins[i].fee_melt = melt_pks[i].fee_refresh; - md.melted_coins[i].original_value = melt_pks[i].value; - for (j=0;j<TALER_CNC_KAPPA;j++) - { - struct GNUNET_CRYPTO_EcdhePrivateKey *tpk; + struct GNUNET_CRYPTO_EcdhePrivateKey *tpk; - tpk = GNUNET_CRYPTO_ecdhe_key_create (); - md.melted_coins[i].transfer_priv[j].ecdhe_priv = *tpk; - GNUNET_free (tpk); - } - md.melted_coins[i].expire_deposit - = melt_pks[i].expire_deposit; - md.melted_coins[i].pub_key.rsa_public_key - = GNUNET_CRYPTO_rsa_public_key_dup (melt_pks[i].key.rsa_public_key); - md.melted_coins[i].sig.rsa_signature - = GNUNET_CRYPTO_rsa_signature_dup (melt_sigs[i].rsa_signature); + tpk = GNUNET_CRYPTO_ecdhe_key_create (); + md.melted_coin.transfer_priv[j].ecdhe_priv = *tpk; + GNUNET_free (tpk); } + md.melted_coin.expire_deposit + = melt_pk->expire_deposit; + md.melted_coin.pub_key.rsa_public_key + = GNUNET_CRYPTO_rsa_public_key_dup (melt_pk->key.rsa_public_key); + md.melted_coin.sig.rsa_signature + = GNUNET_CRYPTO_rsa_signature_dup (melt_sig->rsa_signature); md.fresh_pks = GNUNET_new_array (fresh_pks_len, struct TALER_DenominationPublicKey); for (i=0;i<fresh_pks_len;i++) @@ -926,20 +899,19 @@ TALER_EXCHANGE_refresh_prepare (unsigned int num_melts, buf_size); GNUNET_free (buf); } - for (i=0;i<num_melts;i++) { struct TALER_CoinSpendPublicKeyP coin_pub; - struct TALER_AmountNBO melt_amount; + struct TALER_AmountNBO melt_amountn; - GNUNET_CRYPTO_eddsa_key_get_public (&melt_privs[i].eddsa_priv, + GNUNET_CRYPTO_eddsa_key_get_public (&melt_priv->eddsa_priv, &coin_pub.eddsa_pub); GNUNET_CRYPTO_hash_context_read (hash_context, &coin_pub, sizeof (struct TALER_CoinSpendPublicKeyP)); - TALER_amount_hton (&melt_amount, - &melt_amounts[i]); + TALER_amount_hton (&melt_amountn, + melt_amount); GNUNET_CRYPTO_hash_context_read (hash_context, - &melt_amount, + &melt_amountn, sizeof (struct TALER_AmountNBO)); } @@ -987,23 +959,20 @@ TALER_EXCHANGE_refresh_prepare (unsigned int num_melts, } for (i = 0; i < TALER_CNC_KAPPA; i++) { - for (j = 0; j < num_melts; j++) - { - struct TALER_RefreshCommitLinkP rcl; - struct TALER_TransferSecretP trans_sec; - - GNUNET_CRYPTO_ecdhe_key_get_public (&md.melted_coins[j].transfer_priv[i].ecdhe_priv, - &rcl.transfer_pub.ecdhe_pub); - TALER_link_derive_transfer_secret (&melt_privs[j], - &md.melted_coins[j].transfer_priv[i], - &trans_sec); - TALER_transfer_encrypt (&md.link_secrets[i], - &trans_sec, - &rcl.shared_secret_enc); - GNUNET_CRYPTO_hash_context_read (hash_context, - &rcl, - sizeof (struct TALER_RefreshCommitLinkP)); - } + struct TALER_RefreshCommitLinkP rcl; + struct TALER_TransferSecretP trans_sec; + + GNUNET_CRYPTO_ecdhe_key_get_public (&md.melted_coin.transfer_priv[i].ecdhe_priv, + &rcl.transfer_pub.ecdhe_pub); + TALER_link_derive_transfer_secret (melt_priv, + &md.melted_coin.transfer_priv[i], + &trans_sec); + TALER_transfer_encrypt (&md.link_secrets[i], + &trans_sec, + &rcl.shared_secret_enc); + GNUNET_CRYPTO_hash_context_read (hash_context, + &rcl, + sizeof (struct TALER_RefreshCommitLinkP)); } GNUNET_CRYPTO_hash_context_finish (hash_context, @@ -1150,7 +1119,6 @@ verify_refresh_melt_signature_forbidden (struct TALER_EXCHANGE_RefreshMeltHandle struct TALER_Amount melt_value_with_fee; struct TALER_Amount total; struct TALER_CoinSpendPublicKeyP coin_pub; - unsigned int i; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_json ("history", &history), GNUNET_JSON_spec_fixed_auto ("coin_pub", &coin_pub), @@ -1171,32 +1139,7 @@ verify_refresh_melt_signature_forbidden (struct TALER_EXCHANGE_RefreshMeltHandle } /* Find out which coin was deemed problematic by the exchange */ - mc = NULL; - for (i=0;i<rmh->md->num_melted_coins;i++) - { - if (0 == TALER_amount_cmp (&melt_value_with_fee, - &rmh->md->melted_coins[i].melt_amount_with_fee)) - { - struct TALER_CoinSpendPublicKeyP mc_pub; - - GNUNET_CRYPTO_eddsa_key_get_public (&rmh->md->melted_coins[i].coin_priv.eddsa_priv, - &mc_pub.eddsa_pub); - if (0 == memcmp (&mc_pub, - &coin_pub, - sizeof (struct TALER_CoinSpendPublicKeyP))) - { - mc = &rmh->md->melted_coins[i]; - break; - } - } - } - if (NULL == mc) - { - /* coin not found in our original request */ - GNUNET_break_op (0); - json_decref (history); - return GNUNET_SYSERR; - } + mc = &rmh->md->melted_coin; /* check basic coin properties */ if (0 != TALER_amount_cmp (&original_value, @@ -1410,7 +1353,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, { json_t *melt_obj; json_t *new_denoms; - json_t *melt_coins; + json_t *melt_coin; json_t *coin_evs; json_t *transfer_pubs; json_t *secret_encs; @@ -1439,63 +1382,43 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, /* build JSON request, each of the 6 arrays first */ new_denoms = json_array (); - melt_coins = json_array (); + melt_coin = melted_coin_to_json (&md->melt_session_hash, + &md->melted_coin); coin_evs = json_array (); transfer_pubs = json_array (); secret_encs = json_array (); link_encs = json_array (); - for (i=0;i<md->num_melted_coins;i++) - { - const struct MeltedCoin *mc = &md->melted_coins[i]; - - /* now melt_coins */ - json_array_append (melt_coins, - melted_coin_to_json (&md->melt_session_hash, - mc)); - } /* now transfer_pubs */ for (j=0;j<TALER_CNC_KAPPA;j++) { - tmp = json_array (); - for (i=0;i<md->num_melted_coins;i++) - { - const struct MeltedCoin *mc = &md->melted_coins[i]; - struct TALER_TransferPublicKeyP transfer_pub; + const struct MeltedCoin *mc = &md->melted_coin; + struct TALER_TransferPublicKeyP transfer_pub; - GNUNET_CRYPTO_ecdhe_key_get_public (&mc->transfer_priv[j].ecdhe_priv, - &transfer_pub.ecdhe_pub); - json_array_append (tmp, - GNUNET_JSON_from_data (&transfer_pub, - sizeof (transfer_pub))); - } + GNUNET_CRYPTO_ecdhe_key_get_public (&mc->transfer_priv[j].ecdhe_priv, + &transfer_pub.ecdhe_pub); json_array_append (transfer_pubs, - tmp); + GNUNET_JSON_from_data (&transfer_pub, + sizeof (transfer_pub))); } /* now secret_encs */ for (j=0;j<TALER_CNC_KAPPA;j++) { - tmp = json_array (); - for (i=0;i<md->num_melted_coins;i++) - { - const struct MeltedCoin *mc = &md->melted_coins[i]; - struct TALER_EncryptedLinkSecretP els; - struct TALER_TransferSecretP trans_sec; - - TALER_link_derive_transfer_secret (&mc->coin_priv, - &mc->transfer_priv[j], - &trans_sec); - GNUNET_assert (GNUNET_OK == - TALER_transfer_encrypt (&md->link_secrets[j], - &trans_sec, - &els)); - json_array_append (tmp, - GNUNET_JSON_from_data (&els, - sizeof (els))); - } + const struct MeltedCoin *mc = &md->melted_coin; + struct TALER_EncryptedLinkSecretP els; + struct TALER_TransferSecretP trans_sec; + + TALER_link_derive_transfer_secret (&mc->coin_priv, + &mc->transfer_priv[j], + &trans_sec); + GNUNET_assert (GNUNET_OK == + TALER_transfer_encrypt (&md->link_secrets[j], + &trans_sec, + &els)); json_array_append (secret_encs, - tmp); + GNUNET_JSON_from_data (&els, + sizeof (els))); } /* now new_denoms */ @@ -1569,7 +1492,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, /* finally, assemble main JSON request from constitutent arrays */ melt_obj = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}", "new_denoms", new_denoms, - "melt_coins", melt_coins, + "melt_coin", melt_coin, "coin_evs", coin_evs, "transfer_pubs", transfer_pubs, "secret_encs", secret_encs, @@ -1907,11 +1830,9 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange, struct TALER_EXCHANGE_RefreshRevealHandle *rrh; json_t *transfer_privs; json_t *reveal_obj; - json_t *tmp; CURL *eh; struct GNUNET_CURL_Context *ctx; struct MeltData *md; - unsigned int i; unsigned int j; if (GNUNET_YES != @@ -1947,17 +1868,9 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange, noreval index! */ continue; } - tmp = json_array (); - for (i=0;i<md->num_melted_coins;i++) - { - const struct MeltedCoin *mc = &md->melted_coins[i]; - - json_array_append (tmp, - GNUNET_JSON_from_data (&mc->transfer_priv[j], - sizeof (struct TALER_TransferPrivateKeyP))); - } json_array_append (transfer_privs, - tmp); + GNUNET_JSON_from_data (&md->melted_coin.transfer_priv[j], + sizeof (struct TALER_TransferPrivateKeyP))); } /* build main JSON request */ diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 49c124c80..a87141fce 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -398,7 +398,7 @@ struct Command /** * Information about coins to be melted. */ - struct MeltDetails *melted_coins; + struct MeltDetails melted_coin; /** * Denominations of the fresh coins to withdraw. @@ -1856,13 +1856,9 @@ interpreter_run (void *cls) } case OC_REFRESH_MELT: { - unsigned int num_melted_coins; unsigned int num_fresh_coins; cmd->details.refresh_melt.noreveal_index = UINT16_MAX; - for (num_melted_coins=0; - NULL != cmd->details.refresh_melt.melted_coins[num_melted_coins].amount; - num_melted_coins++) ; for (num_fresh_coins=0; NULL != cmd->details.refresh_melt.fresh_amounts[num_fresh_coins]; num_fresh_coins++) ; @@ -1871,36 +1867,33 @@ interpreter_run (void *cls) = GNUNET_new_array (num_fresh_coins, const struct TALER_EXCHANGE_DenomPublicKey *); { - struct TALER_CoinSpendPrivateKeyP melt_privs[num_melted_coins]; - struct TALER_Amount melt_amounts[num_melted_coins]; - struct TALER_DenominationSignature melt_sigs[num_melted_coins]; - struct TALER_EXCHANGE_DenomPublicKey melt_pks[num_melted_coins]; + struct TALER_CoinSpendPrivateKeyP melt_priv; + struct TALER_Amount melt_amount; + struct TALER_DenominationSignature melt_sig; + struct TALER_EXCHANGE_DenomPublicKey melt_pk; struct TALER_EXCHANGE_DenomPublicKey fresh_pks[num_fresh_coins]; unsigned int i; - for (i=0;i<num_melted_coins;i++) - { - const struct MeltDetails *md = &cmd->details.refresh_melt.melted_coins[i]; - ref = find_command (is, - md->coin_ref); - GNUNET_assert (NULL != ref); - GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc); + const struct MeltDetails *md = &cmd->details.refresh_melt.melted_coin; + ref = find_command (is, + md->coin_ref); + GNUNET_assert (NULL != ref); + GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc); - melt_privs[i] = ref->details.reserve_withdraw.coin_priv; - if (GNUNET_OK != - TALER_string_to_amount (md->amount, - &melt_amounts[i])) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse amount `%s' at %u\n", - md->amount, - is->ip); - fail (is); - return; - } - melt_sigs[i] = ref->details.reserve_withdraw.sig; - melt_pks[i] = *ref->details.reserve_withdraw.pk; + melt_priv = ref->details.reserve_withdraw.coin_priv; + if (GNUNET_OK != + TALER_string_to_amount (md->amount, + &melt_amount)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse amount `%s' at %u\n", + md->amount, + is->ip); + fail (is); + return; } + melt_sig = ref->details.reserve_withdraw.sig; + melt_pk = *ref->details.reserve_withdraw.pk; for (i=0;i<num_fresh_coins;i++) { if (GNUNET_OK != @@ -1920,15 +1913,14 @@ interpreter_run (void *cls) fresh_pks[i] = *cmd->details.refresh_melt.fresh_pks[i]; } cmd->details.refresh_melt.refresh_data - = TALER_EXCHANGE_refresh_prepare (num_melted_coins, - melt_privs, - melt_amounts, - melt_sigs, - melt_pks, - GNUNET_YES, - num_fresh_coins, - fresh_pks, - &cmd->details.refresh_melt.refresh_data_length); + = TALER_EXCHANGE_refresh_prepare (&melt_priv, + &melt_amount, + &melt_sig, + &melt_pk, + GNUNET_YES, + num_fresh_coins, + fresh_pks, + &cmd->details.refresh_melt.refresh_data_length); if (NULL == cmd->details.refresh_melt.refresh_data) { GNUNET_break (0); @@ -1979,16 +1971,9 @@ interpreter_run (void *cls) GNUNET_assert (NULL != ref); /* find reserve_withdraw command */ { - unsigned int idx; const struct MeltDetails *md; - unsigned int num_melted_coins; - - for (num_melted_coins=0; - NULL != ref->details.refresh_melt.melted_coins[num_melted_coins].amount; - num_melted_coins++) ; - idx = cmd->details.refresh_link.coin_idx; - GNUNET_assert (idx < num_melted_coins); - md = &ref->details.refresh_melt.melted_coins[idx]; + + md = &ref->details.refresh_melt.melted_coin; ref = find_command (is, md->coin_ref); GNUNET_assert (NULL != ref); @@ -2465,11 +2450,6 @@ static void run (void *cls) { struct InterpreterState *is; - static struct MeltDetails melt_coins_1[] = { - { .amount = "EUR:4", - .coin_ref = "refresh-withdraw-coin-1" }, - { NULL, NULL } - }; static const char *melt_fresh_amounts_1[] = { "EUR:1", "EUR:1", @@ -2613,7 +2593,9 @@ run (void *cls) { .oc = OC_REFRESH_MELT, .label = "refresh-melt-1", .expected_response_code = MHD_HTTP_OK, - .details.refresh_melt.melted_coins = melt_coins_1, + .details.refresh_melt.melted_coin = { + .amount = "EUR:4", + .coin_ref = "refresh-withdraw-coin-1" }, .details.refresh_melt.fresh_amounts = melt_fresh_amounts_1 }, @@ -2658,7 +2640,9 @@ run (void *cls) { .oc = OC_REFRESH_MELT, .label = "refresh-melt-failing", .expected_response_code = MHD_HTTP_FORBIDDEN, - .details.refresh_melt.melted_coins = melt_coins_1, + .details.refresh_melt.melted_coin = { + .amount = "EUR:4", + .coin_ref = "refresh-withdraw-coin-1" }, .details.refresh_melt.fresh_amounts = melt_fresh_amounts_1 }, // FIXME: also test with coin that was already melted diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 7c67e14f0..b6d31dbc9 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -868,18 +868,18 @@ TMH_DB_execute_reserve_withdraw (struct MHD_Connection *connection, * @param key_state the exchange's key state * @param session_hash hash identifying the refresh session * @param coin_details details about the coin being melted - * @param oldcoin_index what is the number assigned to this coin + * @param[out] meltp on success, set to melt details * @return #GNUNET_OK on success, * #GNUNET_NO if an error message was generated, * #GNUNET_SYSERR on internal errors (no response generated) */ static int -refresh_accept_melts (struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - const struct TMH_KS_StateHandle *key_state, - const struct GNUNET_HashCode *session_hash, - const struct TMH_DB_MeltDetails *coin_details, - uint16_t oldcoin_index) +refresh_check_melt (struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + const struct TMH_KS_StateHandle *key_state, + const struct GNUNET_HashCode *session_hash, + const struct TMH_DB_MeltDetails *coin_details, + struct TALER_EXCHANGEDB_RefreshMelt *meltp) { struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dk; struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki; @@ -887,7 +887,6 @@ refresh_accept_melts (struct MHD_Connection *connection, struct TALER_Amount coin_value; struct TALER_Amount coin_residual; struct TALER_Amount spent; - struct TALER_EXCHANGEDB_RefreshMelt melt; int res; dk = TMH_KS_denomination_key_lookup (key_state, @@ -943,22 +942,11 @@ refresh_accept_melts (struct MHD_Connection *connection, TMH_plugin->free_coin_transaction_list (TMH_plugin->cls, tl); - melt.coin = coin_details->coin_info; - melt.coin_sig = coin_details->melt_sig; - melt.session_hash = *session_hash; - melt.amount_with_fee = coin_details->melt_amount_with_fee; - melt.melt_fee = coin_details->melt_fee; - if (GNUNET_OK != - TMH_plugin->insert_refresh_melt (TMH_plugin->cls, - session, - oldcoin_index, - &melt)) - { - GNUNET_break (0); - return (MHD_YES == - TMH_RESPONSE_reply_internal_db_error (connection)) - ? GNUNET_NO : GNUNET_SYSERR; - } + meltp->coin = coin_details->coin_info; + meltp->coin_sig = coin_details->melt_sig; + meltp->session_hash = *session_hash; + meltp->amount_with_fee = coin_details->melt_amount_with_fee; + meltp->melt_fee = coin_details->melt_fee; return GNUNET_OK; } @@ -974,15 +962,13 @@ refresh_accept_melts (struct MHD_Connection *connection, * @param session_hash hash code of the session the coins are melted into * @param num_new_denoms number of entries in @a denom_pubs, size of y-dimension of @a commit_coin array * @param denom_pubs public keys of the coins we want to withdraw in the end - * @param coin_count number of entries in @a coin_melt_details, size of y-dimension of @a commit_link array - * @param coin_melt_details signatures and (residual) value of the respective coin should be melted + * @param coin_melt_detail signature and (residual) value of the respective coin should be melted * @param commit_coin 2d array of coin commitments (what the exchange is to sign * once the "/refres/reveal" of cut and choose is done), * x-dimension must be #TALER_CNC_KAPPA - * @param commit_link 2d array of coin link commitments (what the exchange is + * @param commit_link array of coin link commitments (what the exchange is * to return via "/refresh/link" to enable linkage in the - * future) - * x-dimension must be #TALER_CNC_KAPPA + * future) of length #TALER_CNC_KAPPA * @return MHD result code */ int @@ -990,10 +976,9 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, const struct GNUNET_HashCode *session_hash, unsigned int num_new_denoms, const struct TALER_DenominationPublicKey *denom_pubs, - unsigned int coin_count, - const struct TMH_DB_MeltDetails *coin_melt_details, + const struct TMH_DB_MeltDetails *coin_melt_detail, struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin, - struct TALER_RefreshCommitLinkP *const* commit_link) + const struct TALER_RefreshCommitLinkP *commit_link) { struct TMH_KS_StateHandle *key_state; struct TALER_EXCHANGEDB_RefreshSession refresh_session; @@ -1028,11 +1013,26 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, } /* store 'global' session data */ - refresh_session.num_oldcoins = coin_count; refresh_session.num_newcoins = num_new_denoms; refresh_session.noreveal_index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, TALER_CNC_KAPPA); + key_state = TMH_KS_acquire (); + if (GNUNET_OK != + (res = refresh_check_melt (connection, + session, + key_state, + session_hash, + coin_melt_detail, + &refresh_session.melt))) + { + TMH_KS_release (key_state); + TMH_plugin->rollback (TMH_plugin->cls, + session); + return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; + } + TMH_KS_release (key_state); + if (GNUNET_OK != (res = TMH_plugin->create_refresh_session (TMH_plugin->cls, session, @@ -1044,26 +1044,6 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, return TMH_RESPONSE_reply_internal_db_error (connection); } - /* Melt old coins and check that they had enough residual value */ - key_state = TMH_KS_acquire (); - for (i=0;i<coin_count;i++) - { - if (GNUNET_OK != - (res = refresh_accept_melts (connection, - session, - key_state, - session_hash, - &coin_melt_details[i], - i))) - { - TMH_KS_release (key_state); - TMH_plugin->rollback (TMH_plugin->cls, - session); - return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - } - } - TMH_KS_release (key_state); - /* store requested new denominations */ if (GNUNET_OK != TMH_plugin->insert_refresh_order (TMH_plugin->cls, @@ -1095,12 +1075,11 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, for (i = 0; i < TALER_CNC_KAPPA; i++) { if (GNUNET_OK != - TMH_plugin->insert_refresh_commit_links (TMH_plugin->cls, - session, - session_hash, - i, - coin_count, - commit_link[i])) + TMH_plugin->insert_refresh_commit_link (TMH_plugin->cls, + session, + session_hash, + i, + &commit_link[i])) { TMH_plugin->rollback (TMH_plugin->cls, session); @@ -1122,8 +1101,9 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, * @param connection the MHD connection to handle * @param session database connection to use * @param session_hash hash of session to query + * @param rm details about the original melt * @param off commitment offset to check - * @param index index of the mismatch + * @param index index of the mismatch, UINT_MAX if there is no such index * @param object_name name of the object with the problem * @return #GNUNET_NO if we generated the error message * #GNUNET_SYSERR if we could not even generate an error message @@ -1132,6 +1112,7 @@ static int send_melt_commitment_error (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, + const struct TALER_EXCHANGEDB_RefreshMelt *rm, unsigned int off, unsigned int index, const char *object_name) @@ -1152,6 +1133,7 @@ send_melt_commitment_error (struct MHD_Connection *connection, } ret = (MHD_YES == TMH_RESPONSE_reply_refresh_reveal_missmatch (connection, + rm, mc, off, index, @@ -1173,9 +1155,8 @@ send_melt_commitment_error (struct MHD_Connection *connection, * @param session database connection to use * @param session_hash hash of session to query * @param off commitment offset to check - * @param num_oldcoins size of the @a transfer_privs and @a melts arrays - * @param transfer_privs private transfer keys - * @param melts array of melted coins + * @param transfer_priv private transfer key + * @param melt information about the melted coin * @param num_newcoins number of newcoins being generated * @param denom_pubs array of @a num_newcoins keys for the new coins * @return #GNUNET_OK if the committment was honest, @@ -1187,91 +1168,58 @@ check_commitment (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, unsigned int off, - unsigned int num_oldcoins, - const struct TALER_TransferPrivateKeyP *transfer_privs, - const struct TALER_EXCHANGEDB_RefreshMelt *melts, + const struct TALER_TransferPrivateKeyP *transfer_priv, + const struct TALER_EXCHANGEDB_RefreshMelt *melt, unsigned int num_newcoins, const struct TALER_DenominationPublicKey *denom_pubs) { - unsigned int j; - struct TALER_LinkSecretP last_shared_secret; - int secret_initialized = GNUNET_NO; - struct TALER_RefreshCommitLinkP *commit_links; + struct TALER_RefreshCommitLinkP commit_link; + struct TALER_LinkSecretP shared_secret; + struct TALER_TransferPublicKeyP transfer_pub_check; struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins; + unsigned int j; - commit_links = GNUNET_malloc (num_oldcoins * - sizeof (struct TALER_RefreshCommitLinkP)); if (GNUNET_OK != - TMH_plugin->get_refresh_commit_links (TMH_plugin->cls, - session, - session_hash, - off, - num_oldcoins, - commit_links)) + TMH_plugin->get_refresh_commit_link (TMH_plugin->cls, + session, + session_hash, + off, + &commit_link)) { GNUNET_break (0); - GNUNET_free (commit_links); return (MHD_YES == TMH_RESPONSE_reply_internal_db_error (connection)) ? GNUNET_NO : GNUNET_SYSERR; } - for (j = 0; j < num_oldcoins; j++) + GNUNET_CRYPTO_ecdhe_key_get_public (&transfer_priv->ecdhe_priv, + &transfer_pub_check.ecdhe_pub); + if (0 != + memcmp (&transfer_pub_check, + &commit_link.transfer_pub, + sizeof (struct TALER_TransferPublicKeyP))) { - struct TALER_LinkSecretP shared_secret; - struct TALER_TransferPublicKeyP transfer_pub_check; - - GNUNET_CRYPTO_ecdhe_key_get_public (&transfer_privs[j].ecdhe_priv, - &transfer_pub_check.ecdhe_pub); - if (0 != - memcmp (&transfer_pub_check, - &commit_links[j].transfer_pub, - sizeof (struct TALER_TransferPublicKeyP))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "transfer keys do not match\n"); - GNUNET_free (commit_links); - return send_melt_commitment_error (connection, - session, - session_hash, - off, - j, - "transfer key"); - } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "transfer keys do not match\n"); + return send_melt_commitment_error (connection, + session, + session_hash, + melt, + off, + UINT_MAX, + "transfer key"); + } - if (GNUNET_OK != - TALER_link_decrypt_secret (&commit_links[j].shared_secret_enc, - &transfer_privs[j], - &melts[j].coin.coin_pub, - &shared_secret)) - { - GNUNET_free (commit_links); - return (MHD_YES == - TMH_RESPONSE_reply_internal_error (connection, - "Transfer secret decryption error")) - ? GNUNET_NO : GNUNET_SYSERR; - } - if (GNUNET_NO == secret_initialized) - { - secret_initialized = GNUNET_YES; - last_shared_secret = shared_secret; - } - else if (0 != memcmp (&shared_secret, - &last_shared_secret, - sizeof (struct GNUNET_HashCode))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "shared secrets do not match\n"); - GNUNET_free (commit_links); - return send_melt_commitment_error (connection, - session, - session_hash, - off, - j, - "transfer secret"); - } + if (GNUNET_OK != + TALER_link_decrypt_secret (&commit_link.shared_secret_enc, + transfer_priv, + &melt->coin.coin_pub, + &shared_secret)) + { + return (MHD_YES == + TMH_RESPONSE_reply_internal_error (connection, + "Transfer secret decryption error")) + ? GNUNET_NO : GNUNET_SYSERR; } - GNUNET_break (GNUNET_YES == secret_initialized); - GNUNET_free (commit_links); /* Check that the commitments for all new coins were correct */ commit_coins = GNUNET_malloc (num_newcoins * @@ -1300,7 +1248,7 @@ check_commitment (struct MHD_Connection *connection, size_t buf_len; link_data = TALER_refresh_decrypt (commit_coins[j].refresh_link, - &last_shared_secret); + &shared_secret); if (NULL == link_data) { GNUNET_break (0); @@ -1342,6 +1290,7 @@ check_commitment (struct MHD_Connection *connection, return send_melt_commitment_error (connection, session, session_hash, + melt, off, j, "envelope"); @@ -1422,7 +1371,6 @@ refresh_exchange_coin (struct MHD_Connection *connection, * @param session database session * @param session_hash hash identifying the refresh session * @param refresh_session information about the refresh operation we are doing - * @param melts array of "num_oldcoins" with information about melted coins * @param denom_pubs array of "num_newcoins" denomination keys for the new coins * @param[out] ev_sigs where to store generated signatures for the new coins, * array of length "num_newcoins", memory released by the @@ -1436,7 +1384,6 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, const struct TALER_EXCHANGEDB_RefreshSession *refresh_session, - const struct TALER_EXCHANGEDB_RefreshMelt *melts, const struct TALER_DenominationPublicKey *denom_pubs, struct TALER_DenominationSignature *ev_sigs, struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins) @@ -1461,12 +1408,12 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection, { if (NULL == ev_sigs[j].rsa_signature) /* could be non-NULL during retries */ ev_sigs[j] = refresh_exchange_coin (connection, - session, - session_hash, - key_state, - &denom_pubs[j], - &commit_coins[j], - j); + session, + session_hash, + key_state, + &denom_pubs[j], + &commit_coins[j], + j); if (NULL == ev_sigs[j].rsa_signature) { TMH_KS_release (key_state); @@ -1490,21 +1437,18 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection, * * @param connection the MHD connection to handle * @param session_hash hash identifying the refresh session - * @param num_oldcoins size of y-dimension of @a transfer_privs array * @param transfer_privs array with the revealed transfer keys, - * x-dimension must be #TALER_CNC_KAPPA - 1 + * length must be #TALER_CNC_KAPPA - 1 * @return MHD result code */ int TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, const struct GNUNET_HashCode *session_hash, - unsigned int num_oldcoins, - struct TALER_TransferPrivateKeyP **transfer_privs) + struct TALER_TransferPrivateKeyP *transfer_privs) { int res; struct TALER_EXCHANGEDB_Session *session; struct TALER_EXCHANGEDB_RefreshSession refresh_session; - struct TALER_EXCHANGEDB_RefreshMelt *melts; struct TALER_DenominationPublicKey *denom_pubs; struct TALER_DenominationSignature *ev_sigs; struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins; @@ -1527,33 +1471,6 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, "session_hash"); if (GNUNET_SYSERR == res) return TMH_RESPONSE_reply_internal_db_error (connection); - if (0 == refresh_session.num_oldcoins) - { - GNUNET_break (0); - return TMH_RESPONSE_reply_internal_db_error (connection); - } - - melts = GNUNET_malloc (refresh_session.num_oldcoins * - sizeof (struct TALER_EXCHANGEDB_RefreshMelt)); - for (j=0;j<refresh_session.num_oldcoins;j++) - { - if (GNUNET_OK != - TMH_plugin->get_refresh_melt (TMH_plugin->cls, - session, - session_hash, - j, - &melts[j])) - { - GNUNET_break (0); - for (i=0;i<j;i++) - { - GNUNET_CRYPTO_rsa_signature_free (melts[i].coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (melts[i].coin.denom_pub.rsa_public_key); - } - GNUNET_free (melts); - return TMH_RESPONSE_reply_internal_db_error (connection); - } - } denom_pubs = GNUNET_malloc (refresh_session.num_newcoins * sizeof (struct TALER_DenominationPublicKey)); if (GNUNET_OK != @@ -1565,12 +1482,8 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, { GNUNET_break (0); GNUNET_free (denom_pubs); - for (i=0;i<refresh_session.num_oldcoins;i++) - { - GNUNET_CRYPTO_rsa_signature_free (melts[i].coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (melts[i].coin.denom_pub.rsa_public_key); - } - GNUNET_free (melts); + GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature); + GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key); return (MHD_YES == TMH_RESPONSE_reply_internal_db_error (connection)) ? GNUNET_NO : GNUNET_SYSERR; } @@ -1586,30 +1499,19 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, session, session_hash, i + off, - refresh_session.num_oldcoins, - transfer_privs[i], - melts, + &transfer_privs[i], + &refresh_session.melt, refresh_session.num_newcoins, denom_pubs))) { for (j=0;j<refresh_session.num_newcoins;j++) GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key); GNUNET_free (denom_pubs); - for (i=0;i<refresh_session.num_oldcoins;i++) - { - GNUNET_CRYPTO_rsa_signature_free (melts[i].coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (melts[i].coin.denom_pub.rsa_public_key); - } - GNUNET_free (melts); + GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature); + GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key); return (GNUNET_NO == res) ? MHD_YES : MHD_NO; } } - for (i=0;i<refresh_session.num_oldcoins;i++) - { - GNUNET_CRYPTO_rsa_signature_free (melts[i].coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (melts[i].coin.denom_pub.rsa_public_key); - } - GNUNET_free (melts); /* Client request OK, start transaction */ commit_coins = GNUNET_malloc (refresh_session.num_newcoins * @@ -1620,7 +1522,6 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, session, session_hash, &refresh_session, - melts, denom_pubs, ev_sigs, commit_coins); @@ -1630,6 +1531,8 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, for (j=0;j<refresh_session.num_newcoins;j++) if (NULL != denom_pubs[j].rsa_public_key) GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key); + GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature); + GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key); GNUNET_free (ev_sigs); GNUNET_free (denom_pubs); GNUNET_free (commit_coins); diff --git a/src/exchange/taler-exchange-httpd_db.h b/src/exchange/taler-exchange-httpd_db.h index 7cf498285..c0fd110b6 100644 --- a/src/exchange/taler-exchange-httpd_db.h +++ b/src/exchange/taler-exchange-httpd_db.h @@ -133,13 +133,12 @@ struct TMH_DB_MeltDetails * @param session_hash hash code of the session the coins are melted into * @param num_new_denoms number of entries in @a denom_pubs, size of y-dimension of @a commit_coin array * @param denom_pubs array of public denomination keys for the refresh (?) - * @param coin_count number of entries in @ a coin_melt_details, size of y-dimension of @a commit_link array * @param coin_melt_details signatures and (residual) value of and information about the respective coin to be melted * @param commit_coin 2d array of coin commitments (what the exchange is to sign * once the "/refres/reveal" of cut and choose is done) - * @param commit_link 2d array of coin link commitments (what the exchange is + * @param commit_link array of coin link commitments (what the exchange is * to return via "/refresh/link" to enable linkage in the - * future) + * future) of length #TALER_CNC_KAPPA * @return MHD result code */ int @@ -147,10 +146,9 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, const struct GNUNET_HashCode *session_hash, unsigned int num_new_denoms, const struct TALER_DenominationPublicKey *denom_pubs, - unsigned int coin_count, const struct TMH_DB_MeltDetails *coin_melt_details, struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin, - struct TALER_RefreshCommitLinkP *const* commit_link); + const struct TALER_RefreshCommitLinkP *commit_link); /** @@ -162,15 +160,13 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, * * @param connection the MHD connection to handle * @param session_hash hash over the refresh session - * @param num_oldcoins size of y-dimension of @a transfer_privs array - * @param transfer_privs array with the revealed transfer keys, #TALER_CNC_KAPPA is 1st-dimension + * @param transfer_privs array of length #TALER_CNC_KAPPA-1 with the revealed transfer keys * @return MHD result code */ int TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, const struct GNUNET_HashCode *session_hash, - unsigned int num_oldcoins, - struct TALER_TransferPrivateKeyP **transfer_privs); + struct TALER_TransferPrivateKeyP *transfer_privs); /** diff --git a/src/exchange/taler-exchange-httpd_refresh.c b/src/exchange/taler-exchange-httpd_refresh.c index 2349d90ac..b147b57a9 100644 --- a/src/exchange/taler-exchange-httpd_refresh.c +++ b/src/exchange/taler-exchange-httpd_refresh.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -39,25 +39,23 @@ * @param connection the MHD connection to handle * @param num_new_denoms number of coins to be created, size of y-dimension of @a commit_link array * @param denom_pubs array of @a num_new_denoms keys - * @param coin_count number of coins to be melted, size of y-dimension of @a commit_coin array - * @param coin_melt_details array with @a coin_count entries with melting details + * @param coin_melt_details melting details * @param session_hash hash over the data that the client commits to * @param commit_coin 2d array of coin commitments (what the exchange is to sign * once the "/refres/reveal" of cut and choose is done) - * @param commit_link 2d array of coin link commitments (what the exchange is + * @param commit_link array of coin link commitments (what the exchange is * to return via "/refresh/link" to enable linkage in the - * future) + * future) of length #TALER_CNC_KAPPA * @return MHD result code */ static int handle_refresh_melt_binary (struct MHD_Connection *connection, unsigned int num_new_denoms, const struct TALER_DenominationPublicKey *denom_pubs, - unsigned int coin_count, const struct TMH_DB_MeltDetails *coin_melt_details, const struct GNUNET_HashCode *session_hash, struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin, - struct TALER_RefreshCommitLinkP *const* commit_link) + const struct TALER_RefreshCommitLinkP * commit_link) { unsigned int i; struct TMH_KS_StateHandle *key_state; @@ -65,7 +63,6 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki; struct TALER_Amount cost; struct TALER_Amount total_cost; - struct TALER_Amount melt; struct TALER_Amount value; struct TALER_Amount fee_withdraw; struct TALER_Amount fee_melt; @@ -108,45 +105,27 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, } } - GNUNET_assert (GNUNET_OK == - TALER_amount_get_zero (TMH_exchange_currency_string, - &total_melt)); - for (i=0;i<coin_count;i++) + dk = TMH_KS_denomination_key_lookup (key_state, + &coin_melt_details->coin_info.denom_pub, + TMH_KS_DKU_DEPOSIT); + if (NULL == dk) { - /* calculate contribution of the i-th melt by subtracting - the fee; add the rest to the total_melt value */ - dk = TMH_KS_denomination_key_lookup (key_state, - &coin_melt_details[i].coin_info.denom_pub, - TMH_KS_DKU_DEPOSIT); - if (NULL == dk) - { - GNUNET_break (0); - return TMH_RESPONSE_reply_arg_invalid (connection, - "denom_pub"); - } - dki = &dk->issue; - TALER_amount_ntoh (&fee_melt, - &dki->properties.fee_refresh); - if (GNUNET_OK != - TALER_amount_subtract (&melt, - &coin_melt_details->melt_amount_with_fee, - &fee_melt)) - { - GNUNET_break_op (0); - TMH_KS_release (key_state); - return TMH_RESPONSE_reply_external_error (connection, - "Melt contribution below melting fee"); - } - if (GNUNET_OK != - TALER_amount_add (&total_melt, - &melt, - &total_melt)) - { - GNUNET_break_op (0); - TMH_KS_release (key_state); - return TMH_RESPONSE_reply_internal_error (connection, - "balance calculation failure"); - } + GNUNET_break (0); + return TMH_RESPONSE_reply_arg_invalid (connection, + "denom_pub"); + } + dki = &dk->issue; + TALER_amount_ntoh (&fee_melt, + &dki->properties.fee_refresh); + if (GNUNET_OK != + TALER_amount_subtract (&total_melt, + &coin_melt_details->melt_amount_with_fee, + &fee_melt)) + { + GNUNET_break_op (0); + TMH_KS_release (key_state); + return TMH_RESPONSE_reply_external_error (connection, + "Melt contribution below melting fee"); } TMH_KS_release (key_state); if (0 != @@ -165,7 +144,6 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, session_hash, num_new_denoms, denom_pubs, - coin_count, coin_melt_details, commit_coin, commit_link); @@ -184,7 +162,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, */ static int get_coin_public_info (struct MHD_Connection *connection, - json_t *coin_info, + const json_t *coin_info, struct TMH_DB_MeltDetails *r_melt_detail) { int ret; @@ -336,29 +314,6 @@ free_commit_coins (struct TALER_EXCHANGEDB_RefreshCommitCoin **commit_coin, /** - * Release memory from the @a commit_link array. - * - * @param commit_link array to release - * @param kappa size of 1st dimension - * @param num_old_coins size of 2nd dimension - */ -static void -free_commit_links (struct TALER_RefreshCommitLinkP **commit_link, - unsigned int kappa, - unsigned int num_old_coins) -{ - unsigned int i; - - for (i=0;i<kappa;i++) - { - if (NULL == commit_link[i]) - break; - GNUNET_free (commit_link[i]); - } -} - - -/** * Handle a "/refresh/melt" request after the first parsing has happened. * We now need to validate the coins being melted and the session signature * and then hand things of to execute the melt operation. This function @@ -367,23 +322,19 @@ free_commit_links (struct TALER_RefreshCommitLinkP **commit_link, * * @param connection the MHD connection to handle * @param new_denoms array of denomination keys - * @param melt_coins array of coins to melt - * @param num_oldcoins number of coins that are being melted - * @param transfer_pubs #TALER_CNC_KAPPA-dimensional array of @a num_oldcoins transfer keys - * @param secret_encs #TALER_CNC_KAPPA-dimensional array of @a num_oldcoins secrets - * @param num_newcoins number of coins that the refresh will generate - * @param coin_evs #TALER_CNC_KAPPA-dimensional array of @a num_newcoins envelopes to sign - * @param link_encs #TALER_CNC_KAPPA-dimensional array of @a num_newcoins encrypted links + * @param melt_coin coin to melt + * @param transfer_pubs #TALER_CNC_KAPPA-dimensional array of transfer keys + * @param secret_encs #TALER_CNC_KAPPA-dimensional array of old coin secrets + * @param coin_evs #TALER_CNC_KAPPA-dimensional array of envelopes to sign + * @param link_encs #TALER_CNC_KAPPA-dimensional array of `length(@a new_denoms)` encrypted links (2D array) * @return MHD result code */ static int handle_refresh_melt_json (struct MHD_Connection *connection, const json_t *new_denoms, - const json_t *melt_coins, - unsigned int num_oldcoins, + const json_t *melt_coin, const json_t *transfer_pubs, const json_t *secret_encs, - unsigned int num_newcoins, const json_t *coin_evs, const json_t *link_encs) { @@ -391,27 +342,26 @@ handle_refresh_melt_json (struct MHD_Connection *connection, unsigned int i; unsigned int j; struct TALER_DenominationPublicKey *denom_pubs; - unsigned int num_new_denoms; - struct TMH_DB_MeltDetails *coin_melt_details; - unsigned int coin_count; + unsigned int num_newcoins; + struct TMH_DB_MeltDetails coin_melt_details; struct GNUNET_HashCode session_hash; struct GNUNET_HashContext *hash_context; struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coin[TALER_CNC_KAPPA]; - struct TALER_RefreshCommitLinkP *commit_link[TALER_CNC_KAPPA]; + struct TALER_RefreshCommitLinkP commit_link[TALER_CNC_KAPPA]; /* For the signature check, we hash most of the inputs together (except for the signatures on the coins). */ hash_context = GNUNET_CRYPTO_hash_context_start (); - num_new_denoms = json_array_size (new_denoms); - denom_pubs = GNUNET_malloc (num_new_denoms * - sizeof (struct TALER_DenominationPublicKey)); - for (i=0;i<num_new_denoms;i++) + num_newcoins = json_array_size (new_denoms); + denom_pubs = GNUNET_new_array (num_newcoins, + struct TALER_DenominationPublicKey); + for (i=0;i<num_newcoins;i++) { char *buf; size_t buf_size; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_denomination_public_key (NULL, - &denom_pubs[i]), + &denom_pubs[i]), GNUNET_JSON_spec_end () }; @@ -432,42 +382,23 @@ handle_refresh_melt_json (struct MHD_Connection *connection, GNUNET_free (buf); } - coin_count = json_array_size (melt_coins); - coin_melt_details = GNUNET_new_array (coin_count, - struct TMH_DB_MeltDetails); - for (i=0;i<coin_count;i++) { /* decode JSON data on coin to melt */ struct TALER_AmountNBO melt_amount; - // FIXME: check json_array_get() return value for NULL! res = get_coin_public_info (connection, - json_array_get (melt_coins, i), - &coin_melt_details[i]); + melt_coin, + &coin_melt_details); if (GNUNET_OK != res) { GNUNET_break_op (0); res = (GNUNET_NO == res) ? MHD_YES : MHD_NO; goto cleanup_melt_details; } - /* Check that the client does not try to melt the same coin twice - into the same session! */ - for (j=0;j<i;j++) - { - if (0 == memcmp (&coin_melt_details[i].coin_info.coin_pub, - &coin_melt_details[j].coin_info.coin_pub, - sizeof (struct TALER_CoinSpendPublicKeyP))) - { - GNUNET_break_op (0); - res = TMH_RESPONSE_reply_external_error (connection, - "melting same coin twice in same session is not allowed"); - goto cleanup_melt_details; - } - } TALER_amount_hton (&melt_amount, - &coin_melt_details[i].melt_amount_with_fee); + &coin_melt_details.melt_amount_with_fee); GNUNET_CRYPTO_hash_context_read (hash_context, - &coin_melt_details[i].coin_info.coin_pub, + &coin_melt_details.coin_info.coin_pub, sizeof (struct TALER_CoinSpendPublicKeyP)); GNUNET_CRYPTO_hash_context_read (hash_context, &melt_amount, @@ -480,8 +411,8 @@ handle_refresh_melt_json (struct MHD_Connection *connection, memset (commit_link, 0, sizeof (commit_link)); for (i = 0; i < TALER_CNC_KAPPA; i++) { - commit_coin[i] = GNUNET_malloc (num_newcoins * - sizeof (struct TALER_EXCHANGEDB_RefreshCommitCoin)); + commit_coin[i] = GNUNET_new_array (num_newcoins, + struct TALER_EXCHANGEDB_RefreshCommitCoin); for (j = 0; j < num_newcoins; j++) { char *link_enc; @@ -536,68 +467,59 @@ handle_refresh_melt_json (struct MHD_Connection *connection, for (i = 0; i < TALER_CNC_KAPPA; i++) { - commit_link[i] = GNUNET_malloc (num_oldcoins * - sizeof (struct TALER_RefreshCommitLinkP)); - for (j = 0; j < num_oldcoins; j++) - { - struct TALER_RefreshCommitLinkP *rcl = &commit_link[i][j]; - struct GNUNET_JSON_Specification trans_spec[] = { - GNUNET_JSON_spec_fixed_auto (NULL, &rcl->transfer_pub), - GNUNET_JSON_spec_end () - }; - struct GNUNET_JSON_Specification sec_spec[] = { - GNUNET_JSON_spec_fixed_auto (NULL, &rcl->shared_secret_enc), - GNUNET_JSON_spec_end () - }; + struct TALER_RefreshCommitLinkP *rcl = &commit_link[i]; + struct GNUNET_JSON_Specification trans_spec[] = { + GNUNET_JSON_spec_fixed_auto (NULL, &rcl->transfer_pub), + GNUNET_JSON_spec_end () + }; + struct GNUNET_JSON_Specification sec_spec[] = { + GNUNET_JSON_spec_fixed_auto (NULL, &rcl->shared_secret_enc), + GNUNET_JSON_spec_end () + }; - res = TMH_PARSE_json_array (connection, - transfer_pubs, - trans_spec, - i, j, -1); - if (GNUNET_OK != res) - { - GNUNET_break_op (0); - res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - goto cleanup; - } - res = TMH_PARSE_json_array (connection, - secret_encs, - sec_spec, - i, j, -1); - if (GNUNET_OK != res) - { - GNUNET_break_op (0); - res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - goto cleanup; - } - GNUNET_CRYPTO_hash_context_read (hash_context, - rcl, - sizeof (struct TALER_RefreshCommitLinkP)); + res = TMH_PARSE_json_array (connection, + transfer_pubs, + trans_spec, + i, -1); + if (GNUNET_OK != res) + { + GNUNET_break_op (0); + res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; + goto cleanup; } - } - GNUNET_CRYPTO_hash_context_finish (hash_context, - &session_hash); - hash_context = NULL; - for (i=0;i<coin_count;i++) - { - /* verify signatures on coins to melt */ - res = verify_coin_public_info (connection, - &session_hash, - &coin_melt_details[i]); + res = TMH_PARSE_json_array (connection, + secret_encs, + sec_spec, + i, -1); if (GNUNET_OK != res) { GNUNET_break_op (0); - res = (GNUNET_NO == res) ? MHD_YES : MHD_NO; + res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; goto cleanup; } + GNUNET_CRYPTO_hash_context_read (hash_context, + rcl, + sizeof (struct TALER_RefreshCommitLinkP)); + } + GNUNET_CRYPTO_hash_context_finish (hash_context, + &session_hash); + hash_context = NULL; + /* verify signature on coins to melt */ + res = verify_coin_public_info (connection, + &session_hash, + &coin_melt_details); + if (GNUNET_OK != res) + { + GNUNET_break_op (0); + res = (GNUNET_NO == res) ? MHD_YES : MHD_NO; + goto cleanup; } /* execute commit */ res = handle_refresh_melt_binary (connection, - num_new_denoms, + num_newcoins, denom_pubs, - coin_count, - coin_melt_details, + &coin_melt_details, &session_hash, commit_coin, commit_link); @@ -605,20 +527,13 @@ handle_refresh_melt_json (struct MHD_Connection *connection, free_commit_coins (commit_coin, TALER_CNC_KAPPA, num_newcoins); - free_commit_links (commit_link, - TALER_CNC_KAPPA, - num_oldcoins); cleanup_melt_details: - for (j=0;j<coin_count;j++) - { - if (NULL != coin_melt_details[j].coin_info.denom_pub.rsa_public_key) - GNUNET_CRYPTO_rsa_public_key_free (coin_melt_details[j].coin_info.denom_pub.rsa_public_key); - if (NULL != coin_melt_details[j].coin_info.denom_sig.rsa_signature) - GNUNET_CRYPTO_rsa_signature_free (coin_melt_details[j].coin_info.denom_sig.rsa_signature); - } - GNUNET_free (coin_melt_details); + if (NULL != coin_melt_details.coin_info.denom_pub.rsa_public_key) + GNUNET_CRYPTO_rsa_public_key_free (coin_melt_details.coin_info.denom_pub.rsa_public_key); + if (NULL != coin_melt_details.coin_info.denom_sig.rsa_signature) + GNUNET_CRYPTO_rsa_signature_free (coin_melt_details.coin_info.denom_sig.rsa_signature); cleanup_denoms: - for (j=0;j<num_new_denoms;j++) + for (j=0;j<num_newcoins;j++) if (NULL != denom_pubs[j].rsa_public_key) GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key); GNUNET_free (denom_pubs); @@ -650,19 +565,16 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh, { json_t *root; json_t *new_denoms; - json_t *melt_coins; + json_t *melt_coin; json_t *coin_evs; json_t *link_encs; json_t *transfer_pubs; json_t *secret_encs; - unsigned int num_oldcoins; - unsigned int num_newcoins; json_t *coin_detail; - json_t *trans_detail; int res; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_json ("new_denoms", &new_denoms), - GNUNET_JSON_spec_json ("melt_coins", &melt_coins), + GNUNET_JSON_spec_json ("melt_coin", &melt_coin), GNUNET_JSON_spec_json ("coin_evs", &coin_evs), GNUNET_JSON_spec_json ("link_encs", &link_encs), GNUNET_JSON_spec_json ("transfer_pubs", &transfer_pubs), @@ -710,24 +622,11 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh, GNUNET_JSON_parse_free (spec); return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } - num_newcoins = json_array_size (coin_detail); - - trans_detail = json_array_get (transfer_pubs, 0); - if (NULL == trans_detail) - { - // FIXME: generate proper HTTP response! - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - } - num_oldcoins = json_array_size (trans_detail); res = handle_refresh_melt_json (connection, new_denoms, - melt_coins, - num_oldcoins, + melt_coin, transfer_pubs, secret_encs, - num_newcoins, coin_evs, link_encs); GNUNET_JSON_parse_free (spec); @@ -744,53 +643,41 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh, * * @param connection the MHD connection to handle * @param session_hash hash identifying the melting session - * @param num_oldcoins length of the 2nd dimension of @a transfer_privs array * @param tp_json private transfer keys in JSON format * @return MHD result code */ static int handle_refresh_reveal_json (struct MHD_Connection *connection, const struct GNUNET_HashCode *session_hash, - unsigned int num_oldcoins, const json_t *tp_json) { - struct TALER_TransferPrivateKeyP *transfer_privs[TALER_CNC_KAPPA - 1]; + struct TALER_TransferPrivateKeyP transfer_privs[TALER_CNC_KAPPA - 1]; unsigned int i; - unsigned int j; int res; - for (i = 0; i < TALER_CNC_KAPPA - 1; i++) - transfer_privs[i] = GNUNET_malloc (num_oldcoins * - sizeof (struct TALER_TransferPrivateKeyP)); res = GNUNET_OK; for (i = 0; i < TALER_CNC_KAPPA - 1; i++) { if (GNUNET_OK != res) break; - for (j = 0; j < num_oldcoins; j++) - { - struct GNUNET_JSON_Specification tp_spec[] = { - GNUNET_JSON_spec_fixed_auto (NULL, &transfer_privs[i][j]), - GNUNET_JSON_spec_end () - }; - if (GNUNET_OK != res) - break; - res = TMH_PARSE_json_array (connection, - tp_json, - tp_spec, - i, j, -1); - GNUNET_break_op (GNUNET_OK == res); - } + struct GNUNET_JSON_Specification tp_spec[] = { + GNUNET_JSON_spec_fixed_auto (NULL, &transfer_privs[i]), + GNUNET_JSON_spec_end () + }; + if (GNUNET_OK != res) + break; + res = TMH_PARSE_json_array (connection, + tp_json, + tp_spec, + i, -1); + GNUNET_break_op (GNUNET_OK == res); } if (GNUNET_OK != res) res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; else res = TMH_DB_execute_refresh_reveal (connection, session_hash, - num_oldcoins, transfer_privs); - for (i = 0; i < TALER_CNC_KAPPA - 1; i++) - GNUNET_free (transfer_privs[i]); return res; } @@ -820,7 +707,6 @@ TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh, { struct GNUNET_HashCode session_hash; int res; - unsigned int num_oldcoins; json_t *reveal_detail; json_t *root; json_t *transfer_privs; @@ -866,10 +752,8 @@ TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh, GNUNET_break_op (0); return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } - num_oldcoins = json_array_size (reveal_detail); res = handle_refresh_reveal_json (connection, &session_hash, - num_oldcoins, transfer_privs); GNUNET_JSON_parse_free (spec); return res; diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 6a21d8ac4..26f0d76a4 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015, 2016 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -978,6 +978,7 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, * revealed value(s) do not match the original commitment. * * @param connection the connection to send the response to + * @param rm details about the original melt * @param mc all information about the original commitment * @param off offset in the array of kappa-commitments where * the missmatch was detected @@ -989,43 +990,35 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, */ int TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, + const struct TALER_EXCHANGEDB_RefreshMelt *rm, const struct TALER_EXCHANGEDB_MeltCommitment *mc, unsigned int off, unsigned int j, const char *missmatch_object) { - json_t *info_old; json_t *info_new; json_t *info_commit; json_t *info_links; unsigned int i; unsigned int k; + json_t *rm_json; + + rm_json = json_object (); + json_object_set_new (rm_json, + "coin_sig", + GNUNET_JSON_from_data (&rm->coin_sig, + sizeof (struct TALER_CoinSpendSignatureP))); + json_object_set_new (rm_json, + "coin_pub", + GNUNET_JSON_from_data (&rm->coin.coin_pub, + sizeof (struct TALER_CoinSpendPublicKeyP))); + json_object_set_new (rm_json, + "melt_amount_with_fee", + TALER_JSON_from_amount (&rm->amount_with_fee)); + json_object_set_new (rm_json, + "melt_fee", + TALER_JSON_from_amount (&rm->melt_fee)); - info_old = json_array (); - for (i=0;i<mc->num_oldcoins;i++) - { - const struct TALER_EXCHANGEDB_RefreshMelt *rm; - json_t *rm_json; - - rm = &mc->melts[i]; - rm_json = json_object (); - json_object_set_new (rm_json, - "coin_sig", - GNUNET_JSON_from_data (&rm->coin_sig, - sizeof (struct TALER_CoinSpendSignatureP))); - json_object_set_new (rm_json, - "coin_pub", - GNUNET_JSON_from_data (&rm->coin.coin_pub, - sizeof (struct TALER_CoinSpendPublicKeyP))); - json_object_set_new (rm_json, - "melt_amount_with_fee", - TALER_JSON_from_amount (&rm->amount_with_fee)); - json_object_set_new (rm_json, - "melt_fee", - TALER_JSON_from_amount (&rm->melt_fee)); - json_array_append_new (info_old, - rm_json); - } info_new = json_array (); for (i=0;i<mc->num_newcoins;i++) { @@ -1042,6 +1035,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, { json_t *info_commit_k; json_t *info_link_k; + const struct TALER_RefreshCommitLinkP *cl; info_commit_k = json_array (); for (i=0;i<mc->num_newcoins;i++) @@ -1069,25 +1063,17 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, } json_array_append_new (info_commit, info_commit_k); - info_link_k = json_array (); - for (i=0;i<mc->num_oldcoins;i++) - { - const struct TALER_RefreshCommitLinkP *cl; - json_t *cl_json; - - cl = &mc->commit_links[k][i]; - cl_json = json_object (); - json_object_set_new (cl_json, - "transfer_pub", - GNUNET_JSON_from_data (&cl->transfer_pub, - sizeof (struct TALER_TransferPublicKeyP))); - json_object_set_new (cl_json, - "shared_secret_enc", - GNUNET_JSON_from_data (&cl->shared_secret_enc, - sizeof (struct TALER_EncryptedLinkSecretP))); - json_array_append_new (info_link_k, - cl_json); - } + + info_link_k = json_object (); + cl = &mc->commit_links[k]; + json_object_set_new (info_link_k, + "transfer_pub", + GNUNET_JSON_from_data (&cl->transfer_pub, + sizeof (struct TALER_TransferPublicKeyP))); + json_object_set_new (info_link_k, + "shared_secret_enc", + GNUNET_JSON_from_data (&cl->shared_secret_enc, + sizeof (struct TALER_EncryptedLinkSecretP))); json_array_append_new (info_links, info_link_k); } @@ -1097,7 +1083,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, "error", "commitment violation", "offset", (int) off, "index", (int) j, - "oldcoin_infos", info_old, + "refresh_melt_info", rm_json, "newcoin_infos", info_new, "commit_infos", info_commit, "link_infos", info_links, diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h index 85c2e1f32..57857560c 100644 --- a/src/exchange/taler-exchange-httpd_responses.h +++ b/src/exchange/taler-exchange-httpd_responses.h @@ -492,6 +492,7 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, * revealed value(s) do not match the original commitment. * * @param connection the connection to send the response to + * @param rm details about the original melt * @param mc all information about the original commitment * @param off offset in the array of kappa-commitments where * the missmatch was detected @@ -503,6 +504,7 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, */ int TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, + const struct TALER_EXCHANGEDB_RefreshMelt *rm, const struct TALER_EXCHANGEDB_MeltCommitment *mc, unsigned int off, unsigned int j, diff --git a/src/exchangedb/perf_taler_exchangedb.c b/src/exchangedb/perf_taler_exchangedb.c index bac8f4cb8..49f6ca080 100644 --- a/src/exchangedb/perf_taler_exchangedb.c +++ b/src/exchangedb/perf_taler_exchangedb.c @@ -144,7 +144,7 @@ main (int argc, char ** argv) PERF_TALER_EXCHANGEDB_INIT_CMD_LOOP ("06 - refresh melt init loop", NB_MELT_INIT), PERF_TALER_EXCHANGEDB_INIT_CMD_START_TRANSACTION (""), - /* TODO: initialize using coins & sessions created localy + /* TODO: initialize using coins & sessions created localy * in order to make sure the same coin are not melted twice*/ PERF_TALER_EXCHANGEDB_INIT_CMD_LOAD_ARRAY ("06 - session hash", "06 - refresh melt init loop", @@ -152,9 +152,6 @@ main (int argc, char ** argv) PERF_TALER_EXCHANGEDB_INIT_CMD_LOAD_ARRAY ("06 - coin", "06 - refresh melt init loop", "03 - save coin"), - PERF_TALER_EXCHANGEDB_INIT_CMD_INSERT_REFRESH_MELT ("06 - refresh melt", - "06 - session hash", - "06 - coin"), PERF_TALER_EXCHANGEDB_INIT_CMD_COMMIT_TRANSACTION (""), PERF_TALER_EXCHANGEDB_INIT_CMD_END_LOOP ("06 - end", "06 - refresh melt init loop"), diff --git a/src/exchangedb/perf_taler_exchangedb_init.c b/src/exchangedb/perf_taler_exchangedb_init.c index 2d018bdf0..988014a11 100644 --- a/src/exchangedb/perf_taler_exchangedb_init.c +++ b/src/exchangedb/perf_taler_exchangedb_init.c @@ -447,7 +447,6 @@ PERF_TALER_EXCHANGEDB_refresh_session_init () GNUNET_assert (NULL != (refresh_session = GNUNET_new (struct TALER_EXCHANGEDB_RefreshSession))); refresh_session->noreveal_index = 1; - refresh_session->num_oldcoins = 1; refresh_session->num_newcoins = 1; return refresh_session; @@ -459,7 +458,7 @@ PERF_TALER_EXCHANGEDB_refresh_session_init () */ int PERF_TALER_EXCHANGEDB_refresh_session_copy (struct TALER_EXCHANGEDB_RefreshSession *session, - struct TALER_EXCHANGEDB_RefreshSession *copy) + struct TALER_EXCHANGEDB_RefreshSession *copy) { *copy = *session; return GNUNET_OK; diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c b/src/exchangedb/perf_taler_exchangedb_interpreter.c index cb805a0b3..661cfeef3 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.c +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c @@ -101,13 +101,6 @@ data_free (struct PERF_TALER_EXCHANGEDB_Data *data) data->data.session_hash = NULL; break; - case PERF_TALER_EXCHANGEDB_REFRESH_MELT: - if (NULL == data->data.refresh_melt) - break; - PERF_TALER_EXCHANGEDB_refresh_melt_free (data->data.refresh_melt); - data->data.refresh_melt = NULL; - break; - case PERF_TALER_EXCHANGEDB_NONE: break; } @@ -158,11 +151,6 @@ data_copy (const struct PERF_TALER_EXCHANGEDB_Data *data, = *data->data.session_hash; break; - case PERF_TALER_EXCHANGEDB_REFRESH_MELT: - copy->data.refresh_melt - = PERF_TALER_EXCHANGEDB_refresh_melt_copy (data->data.refresh_melt); - break; - case PERF_TALER_EXCHANGEDB_NONE: break; } @@ -770,75 +758,6 @@ cmd_init (struct PERF_TALER_EXCHANGEDB_Cmd cmd[]) } break; - case PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_MELT: - { - int ret; - - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_melt.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_melt.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_EXCHANGEDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_melt.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_melt.index_hash = ret; - ret = cmd_find (cmd, - cmd[i].details.insert_refresh_melt.label_coin); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.insert_refresh_melt.label_coin); - return GNUNET_SYSERR; - } - if (PERF_TALER_EXCHANGEDB_COIN != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.insert_refresh_melt.label_coin); - return GNUNET_SYSERR; - } - cmd[i].details.insert_refresh_melt.index_coin = ret; } - break; - - case PERF_TALER_EXCHANGEDB_CMD_GET_REFRESH_MELT: - { - int ret; - ret = cmd_find (cmd, - cmd[i].details.get_refresh_melt.label_hash); - if (GNUNET_SYSERR == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Undefined reference to %s\n", - i, - cmd[i].details.get_refresh_melt.label_hash); - return GNUNET_SYSERR; - } - if (PERF_TALER_EXCHANGEDB_REFRESH_HASH != cmd[ret].exposed.type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%d:Wrong type reference to %s\n", - i, - cmd[i].details.get_refresh_melt.label_hash); - return GNUNET_SYSERR; - } - cmd[i].details.get_refresh_melt.index_hash = ret; - } - break; - case PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_ORDER: { int ret; @@ -1645,46 +1564,6 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) } break; - case PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_MELT: - { - unsigned int hash_index; - unsigned int coin_index; - struct GNUNET_HashCode *hash; - struct TALER_EXCHANGEDB_RefreshMelt *melt; - struct PERF_TALER_EXCHANGEDB_Coin *coin; - - hash_index = state->cmd[state->i].details.insert_refresh_melt.index_hash; - coin_index = state->cmd[state->i].details.insert_refresh_melt.index_coin; - hash = state->cmd[hash_index].exposed.data.session_hash; - coin = state->cmd[coin_index].exposed.data.coin; - melt = PERF_TALER_EXCHANGEDB_refresh_melt_init (hash, - coin); - state->plugin->insert_refresh_melt (state->plugin->cls, - state->session, - 1, - melt); - } - break; - - case PERF_TALER_EXCHANGEDB_CMD_GET_REFRESH_MELT: - { - int ret; - unsigned int hash_index; - struct GNUNET_HashCode *hash; - struct TALER_EXCHANGEDB_RefreshMelt melt; - - hash_index = cmd_find (state->cmd, - state->cmd[state->i].details.get_refresh_melt.label_hash); - hash = state->cmd[hash_index].exposed.data.session_hash; - ret = state->plugin->get_refresh_melt (state->plugin->cls, - state->session, - hash, - 1, - &melt); - GNUNET_assert (GNUNET_SYSERR != ret); - } - break; - case PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_ORDER: { unsigned int hash_index; diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.h b/src/exchangedb/perf_taler_exchangedb_interpreter.h index 1c2659dd1..cf4f0bfd7 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.h +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.h @@ -479,38 +479,6 @@ .exposed.type = PERF_TALER_EXCHANGEDB_NONE \ } -/** - * Insert a melt operation in the database - * - * @param _label the label of the command - * @param _label_hash the label of the hash of the session - * @param _label_coin the label of the coin to melt - */ -#define PERF_TALER_EXCHANGEDB_INIT_CMD_INSERT_REFRESH_MELT(_label, \ - _label_hash, \ - _label_coin) \ -{ \ - .command = PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_MELT, \ - .label = _label, \ - .details.insert_refresh_melt.label_hash = _label_hash, \ - .details.insert_refresh_melt.label_coin = _label_coin, \ - .exposed.type = PERF_TALER_EXCHANGEDB_NONE \ -} - -/** - * Get informations about a melt operation - * - * @param _label the label of the command - * @param _label_hash the label of the hash of the refresh session - */ -#define PERF_TALER_EXCHANGEDB_INIT_CMD_GET_REFRESH_MELT(_label, \ - _label_hash) \ -{ \ - .command = PERF_TALER_EXCHANGEDB_CMD_GET_REFRESH_MELT, \ - .label = _label, \ - .detail.get_refresh_melt.label_hash = _label_hash, \ - .exposed.type = PERF_TALER_EXCHANGEDB_NONE \ -} /** * The type of data stored in #PERF_TALER_EXCHANGEDB_Memory @@ -523,8 +491,7 @@ enum PERF_TALER_EXCHANGEDB_Type PERF_TALER_EXCHANGEDB_RESERVE, PERF_TALER_EXCHANGEDB_COIN, PERF_TALER_EXCHANGEDB_DEPOSIT, - PERF_TALER_EXCHANGEDB_REFRESH_HASH, - PERF_TALER_EXCHANGEDB_REFRESH_MELT + PERF_TALER_EXCHANGEDB_REFRESH_HASH }; @@ -553,8 +520,6 @@ struct PERF_TALER_EXCHANGEDB_Data struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; /** #PERF_TALER_EXCHANGEDB_REFRESH_HASH */ struct GNUNET_HashCode *session_hash; - /** #PERF_TALER_EXCHANGEDB_REFRESH_MELT */ - struct TALER_EXCHANGEDB_RefreshMelt *refresh_melt; } data; }; @@ -714,16 +679,6 @@ enum PERF_TALER_EXCHANGEDB_CMD_Name PERF_TALER_EXCHANGEDB_CMD_GET_REFRESH_SESSION, /** - * Insert a refresh melt - */ - PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_MELT, - - /** - * Get informations about a refresh melt operation - */ - PERF_TALER_EXCHANGEDB_CMD_GET_REFRESH_MELT, - - /** * Insert a melt refresh order */ PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_ORDER, @@ -1086,36 +1041,6 @@ union PERF_TALER_EXCHANGEDB_CMD_Details } get_refresh_session; /** - * Data requiered for the #PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_MELT command - */ - struct PERF_TALER_EXCHANGEDB_CMD_insertRefreshMeltDetails - { - /** - * The label of the hash of the refresh session - */ - const char *label_hash; - unsigned int index_hash; - - /** - * The label of the coin to melt - */ - const char *label_coin; - unsigned int index_coin; - } insert_refresh_melt; - - /** - * Data requiered for the #PERF_TALER_EXCHANGEDB_CMD_GET_REFRESH_MELT command - */ - struct PERF_TALER_EXCHANGEDB_CMD_getRefreshMeltDetails - { - /** - * The label of the hash of the session - */ - const char *label_hash; - unsigned int index_hash; - } get_refresh_melt; - - /** * Data requiered for the #PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_ORDER command */ struct PERF_TALER_EXCHANGEDB_CMD_insertRefreshOrderDetails diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c index 8bb214efb..9b62d688f 100644 --- a/src/exchangedb/plugin_exchangedb_common.c +++ b/src/exchangedb/plugin_exchangedb_common.c @@ -132,15 +132,6 @@ common_free_melt_commitment (void *cls, unsigned int i; unsigned int k; - if (NULL != mc->melts) - { - for (i=0;i<mc->num_oldcoins;i++) - { - GNUNET_CRYPTO_rsa_signature_free (mc->melts[i].coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (mc->melts[i].coin.denom_pub.rsa_public_key); - } - GNUNET_free (mc->melts); - } if (NULL != mc->denom_pubs) { for (i=0;i<mc->num_newcoins;i++) @@ -161,7 +152,6 @@ common_free_melt_commitment (void *cls, } GNUNET_free (mc->commit_coins[k]); } - GNUNET_free_non_null (mc->commit_links[k]); } GNUNET_free (mc); } diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 6f5599d6f..cda2df0d0 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -160,8 +160,6 @@ postgres_drop_tables (void *cls, SQLEXEC_ (session->conn, "DROP TABLE IF EXISTS refresh_order;"); SQLEXEC_ (session->conn, - "DROP TABLE IF EXISTS refresh_melts;"); - SQLEXEC_ (session->conn, "DROP TABLE IF EXISTS refresh_sessions;"); SQLEXEC_ (session->conn, "DROP TABLE IF EXISTS known_coins;"); @@ -338,36 +336,24 @@ postgres_create_tables (void *cls) /** * The DB will show negative values for some values of the following fields as * we use them as 16 bit unsigned integers - * @a num_oldcoins * @a num_newcoins + * @a noreveal_index * Do not do arithmetic in SQL on these fields. * NOTE: maybe we should instead forbid values >= 2^15 categorically? */ SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_sessions " "(session_hash BYTEA PRIMARY KEY CHECK (LENGTH(session_hash)=64)" - ",num_oldcoins INT2 NOT NULL" - ",num_newcoins INT2 NOT NULL" - ",noreveal_index INT2 NOT NULL" - ")"); - /* Table with coins that have been melted. Gives the coin's public - key (coin_pub), the melting session, the index of this coin in that - session, the signature affirming the melting and the amount that - this coin contributed to the melting session. - */ - SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_melts " - "(coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)" - ",session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash)" - ",oldcoin_index INT2 NOT NULL" - ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)" + ",old_coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)" + ",old_coin_sig BYTEA NOT NULL CHECK(LENGTH(old_coin_sig)=64)" ",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" ",melt_fee_val INT8 NOT NULL" ",melt_fee_frac INT4 NOT NULL" ",melt_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",PRIMARY KEY (session_hash, oldcoin_index)" /* a coin can be used only - once in a refresh session */ - ") "); + ",num_newcoins INT2 NOT NULL" + ",noreveal_index INT2 NOT NULL" + ")"); /* Table with information about coins that have been refunded. (Technically one of the deposit operations that a coin was involved with is refunded.)*/ SQLEXEC("CREATE TABLE IF NOT EXISTS refunds " @@ -401,15 +387,11 @@ postgres_create_tables (void *cls) the session_hash for which this is the link information, the oldcoin index and the cut-and-choose index (from 0 to #TALER_CNC_KAPPA-1), as well as the actual link data (the transfer public key and the encrypted - link secret). - NOTE: We might want to simplify this and not have the oldcoin_index - and instead store all link secrets, one after the other, in one big BYTEA. - (#3814) */ + link secret) */ SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_link " "(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash)" ",transfer_pub BYTEA NOT NULL CHECK(LENGTH(transfer_pub)=32)" ",link_secret_enc BYTEA NOT NULL" - ",oldcoin_index INT2 NOT NULL" ",cnc_index INT2 NOT NULL" ")"); /* Table with the commitments for the new coins that are to be created @@ -726,7 +708,14 @@ postgres_prepare (PGconn *db_conn) high-level information about a refresh session */ PREPARE ("get_refresh_session", "SELECT" - " num_oldcoins" + " old_coin_pub" + ",old_coin_sig" + ",amount_with_fee_val" + ",amount_with_fee_frac" + ",amount_with_fee_curr" + ",melt_fee_val " + ",melt_fee_frac " + ",melt_fee_curr " ",num_newcoins" ",noreveal_index" " FROM refresh_sessions " @@ -738,12 +727,19 @@ postgres_prepare (PGconn *db_conn) PREPARE ("insert_refresh_session", "INSERT INTO refresh_sessions " "(session_hash " - ",num_oldcoins " + ",old_coin_pub " + ",old_coin_sig " + ",amount_with_fee_val " + ",amount_with_fee_frac " + ",amount_with_fee_curr " + ",melt_fee_val " + ",melt_fee_frac " + ",melt_fee_curr " ",num_newcoins " ",noreveal_index " ") VALUES " - "($1, $2, $3, $4);", - 4, NULL); + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);", + 11, NULL); /* Used in #postgres_get_known_coin() to fetch the denomination public key and signature for @@ -787,54 +783,19 @@ postgres_prepare (PGconn *db_conn) " WHERE session_hash=$1 AND newcoin_index=$2", 2, NULL); - /* Used in #postgres_insert_refresh_melt to store information - about melted coins */ - PREPARE ("insert_refresh_melt", - "INSERT INTO refresh_melts " - "(coin_pub " - ",session_hash" - ",oldcoin_index " - ",coin_sig " - ",amount_with_fee_val " - ",amount_with_fee_frac " - ",amount_with_fee_curr " - ",melt_fee_val " - ",melt_fee_frac " - ",melt_fee_curr " - ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);", - 10, NULL); - - /* Used in #postgres_get_refresh_melt to obtain information - about melted coins */ - PREPARE ("get_refresh_melt", - "SELECT" - " coin_pub" - ",coin_sig" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",amount_with_fee_curr" - ",melt_fee_val " - ",melt_fee_frac " - ",melt_fee_curr " - " FROM refresh_melts" - " WHERE session_hash=$1 AND oldcoin_index=$2", - 2, NULL); - - /* Query the 'refresh_melts' by coin public key */ - PREPARE ("get_refresh_melt_by_coin", + /* Query the 'refresh_sessions' by coin public key */ + PREPARE ("get_refresh_session_by_coin", "SELECT" " session_hash" - /* ",oldcoin_index" // not needed */ - ",coin_sig" + ",old_coin_sig" ",amount_with_fee_val" ",amount_with_fee_frac" ",amount_with_fee_curr" ",melt_fee_val " ",melt_fee_frac " ",melt_fee_curr " - " FROM refresh_melts" - " WHERE coin_pub=$1", + " FROM refresh_sessions" + " WHERE old_coin_pub=$1", 1, NULL); /* Query the 'refunds' by coin public key */ @@ -856,28 +817,27 @@ postgres_prepare (PGconn *db_conn) 1, NULL); - /* Used in #postgres_insert_refresh_commit_links() to + /* Used in #postgres_insert_refresh_commit_link() to store commitments */ PREPARE ("insert_refresh_commit_link", "INSERT INTO refresh_commit_link " "(session_hash" ",transfer_pub" ",cnc_index" - ",oldcoin_index" ",link_secret_enc" ") VALUES " - "($1, $2, $3, $4, $5);", - 5, NULL); + "($1, $2, $3, $4);", + 4, NULL); - /* Used in #postgres_get_refresh_commit_links() to + /* Used in #postgres_get_refresh_commit_link() to retrieve original commitments during /refresh/reveal */ PREPARE ("get_refresh_commit_link", "SELECT" " transfer_pub" ",link_secret_enc" " FROM refresh_commit_link" - " WHERE session_hash=$1 AND cnc_index=$2 AND oldcoin_index=$3", - 3, NULL); + " WHERE session_hash=$1 AND cnc_index=$2", + 2, NULL); /* Used in #postgres_insert_refresh_commit_coins() to store coin commitments. */ @@ -1110,10 +1070,9 @@ postgres_prepare (PGconn *db_conn) efficient ways to express the same query. */ PREPARE ("get_link", "SELECT link_vector_enc,ev_sig,ro.denom_pub" - " FROM refresh_melts rm " + " FROM refresh_sessions rs " " JOIN refresh_order ro USING (session_hash)" " JOIN refresh_commit_coin rcc USING (session_hash)" - " JOIN refresh_sessions rs USING (session_hash)" " JOIN refresh_out rc USING (session_hash)" " WHERE ro.session_hash=$1" " AND ro.newcoin_index=rcc.newcoin_index" @@ -1125,18 +1084,14 @@ postgres_prepare (PGconn *db_conn) melted coin, we obtain the corresponding encrypted link secret and the transfer public key. This is done by first finding the session_hash(es) of all sessions the coin was melted into, - and then constraining the result to the selected "noreveal_index" - and the transfer public key to the corresponding index of the - old coin. + and then constraining the result to the selected "noreveal_index". NOTE: This may (in theory) return multiple results, one per session that the old coin was melted into. */ PREPARE ("get_transfer", "SELECT transfer_pub,link_secret_enc,session_hash" - " FROM refresh_melts rm" + " FROM refresh_sessions rs" " JOIN refresh_commit_link rcl USING (session_hash)" - " JOIN refresh_sessions rs USING (session_hash)" - " WHERE rm.coin_pub=$1" - " AND rm.oldcoin_index = rcl.oldcoin_index" + " WHERE rs.old_coin_pub=$1" " AND rcl.cnc_index=rs.noreveal_index", 1, NULL); @@ -2288,7 +2243,7 @@ postgres_test_deposit_done (void *cls, { /* NOTE: maybe wrong type for a 'boolean' */ - uint32_t done; + uint32_t done = 0; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint32 ("done", &done), @@ -2812,12 +2767,14 @@ postgres_get_refresh_session (void *cls, sizeof (struct TALER_EXCHANGEDB_RefreshSession)); { struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint16 ("num_oldcoins", - &refresh_session->num_oldcoins), GNUNET_PQ_result_spec_uint16 ("num_newcoins", &refresh_session->num_newcoins), GNUNET_PQ_result_spec_uint16 ("noreveal_index", &refresh_session->noreveal_index), + GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub", &refresh_session->melt.coin.coin_pub), + GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig", &refresh_session->melt.coin_sig), + TALER_PQ_result_spec_amount ("amount_with_fee", &refresh_session->melt.amount_with_fee), + TALER_PQ_result_spec_amount ("melt_fee", &refresh_session->melt.melt_fee), GNUNET_PQ_result_spec_end }; if (GNUNET_OK != @@ -2829,6 +2786,16 @@ postgres_get_refresh_session (void *cls, } } PQclear (result); + if (GNUNET_OK != + get_known_coin (cls, + session, + &refresh_session->melt.coin.coin_pub, + &refresh_session->melt.coin)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + refresh_session->melt.session_hash = *session_hash; return GNUNET_YES; } @@ -2852,59 +2819,20 @@ postgres_create_refresh_session (void *cls, PGresult *result; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&refresh_session->num_oldcoins), + GNUNET_PQ_query_param_auto_from_type (&refresh_session->melt.coin.coin_pub), + GNUNET_PQ_query_param_auto_from_type (&refresh_session->melt.coin_sig), + TALER_PQ_query_param_amount (&refresh_session->melt.amount_with_fee), + TALER_PQ_query_param_amount (&refresh_session->melt.melt_fee), GNUNET_PQ_query_param_uint16 (&refresh_session->num_newcoins), GNUNET_PQ_query_param_uint16 (&refresh_session->noreveal_index), GNUNET_PQ_query_param_end }; - - result = GNUNET_PQ_exec_prepared (session->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 cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param oldcoin_index index of the coin to store - * @param melt melt operation details to store; includes - * the session hash of the melt - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on internal error - */ -static int -postgres_insert_refresh_melt (void *cls, - struct TALER_EXCHANGEDB_Session *session, - uint16_t oldcoin_index, - const struct TALER_EXCHANGEDB_RefreshMelt *melt) -{ - PGresult *result; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&melt->coin.coin_pub), - GNUNET_PQ_query_param_auto_from_type (&melt->session_hash), - GNUNET_PQ_query_param_uint16 (&oldcoin_index), - GNUNET_PQ_query_param_auto_from_type (&melt->coin_sig), - TALER_PQ_query_param_amount (&melt->amount_with_fee), - TALER_PQ_query_param_amount (&melt->melt_fee), - GNUNET_PQ_query_param_end - }; int ret; /* check if the coin is already known */ ret = get_known_coin (cls, session, - &melt->coin.coin_pub, + &refresh_session->melt.coin.coin_pub, NULL); if (GNUNET_SYSERR == ret) { @@ -2916,15 +2844,15 @@ postgres_insert_refresh_melt (void *cls, if (GNUNET_SYSERR == insert_known_coin (cls, session, - &melt->coin)) + &refresh_session->melt.coin)) { GNUNET_break (0); return GNUNET_SYSERR; } } - /* insert the melt */ + /* insert session */ result = GNUNET_PQ_exec_prepared (session->conn, - "insert_refresh_melt", + "insert_refresh_session", params); if (PGRES_COMMAND_OK != PQresultStatus (result)) { @@ -2938,93 +2866,6 @@ postgres_insert_refresh_melt (void *cls, /** - * Get information about melted coin details from the database. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param session database connection - * @param session_hash session hash of the melt operation - * @param oldcoin_index index of the coin to retrieve - * @param melt melt data to fill in, can be NULL - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on internal error - */ -static int -postgres_get_refresh_melt (void *cls, - struct TALER_EXCHANGEDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t oldcoin_index, - struct TALER_EXCHANGEDB_RefreshMelt *melt) -{ - PGresult *result; - struct TALER_CoinPublicInfo coin; - struct TALER_CoinSpendSignatureP coin_sig; - struct TALER_Amount amount_with_fee; - struct TALER_Amount melt_fee; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&oldcoin_index), - GNUNET_PQ_query_param_end - }; - int nrows; - - /* check if the melt record exists and get it */ - result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_melt", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } - nrows = PQntuples (result); - if (0 == nrows) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "get_refresh_melt() returned 0 matching rows\n"); - PQclear (result); - return GNUNET_NO; - } - GNUNET_assert (1 == nrows); /* due to primary key constraint */ - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("coin_pub", &coin.coin_pub), - GNUNET_PQ_result_spec_auto_from_type ("coin_sig", &coin_sig), - TALER_PQ_result_spec_amount ("amount_with_fee", &amount_with_fee), - TALER_PQ_result_spec_amount ("melt_fee", &melt_fee), - GNUNET_PQ_result_spec_end - }; - if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, 0)) - { - GNUNET_break (0); - PQclear (result); - return GNUNET_SYSERR; - } - PQclear (result); - } - /* fetch the coin info and denomination info */ - if (GNUNET_OK != - get_known_coin (cls, - session, - &coin.coin_pub, - &coin)) - return GNUNET_SYSERR; - if (NULL == melt) - { - GNUNET_CRYPTO_rsa_signature_free (coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (coin.denom_pub.rsa_public_key); - return GNUNET_OK; - } - melt->coin = coin; - melt->coin_sig = coin_sig; - melt->session_hash = *session_hash; - melt->amount_with_fee = amount_with_fee; - melt->melt_fee = melt_fee; - return GNUNET_OK; -} - - -/** * Store in the database which coin(s) we want to create * in a given refresh operation. * @@ -3369,48 +3210,42 @@ postgres_get_refresh_commit_coins (void *cls, * @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 - * @param[out] links array of link information to store return + * @param[out] link link information to store return * @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success */ static int -postgres_insert_refresh_commit_links (void *cls, - struct TALER_EXCHANGEDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t cnc_index, - uint16_t num_links, - const struct TALER_RefreshCommitLinkP *links) +postgres_insert_refresh_commit_link (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct GNUNET_HashCode *session_hash, + uint16_t cnc_index, + const struct TALER_RefreshCommitLinkP *link) { - uint16_t i; - - for (i=0;i<num_links;i++) - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_auto_from_type (&links[i].transfer_pub), - GNUNET_PQ_query_param_uint16 (&cnc_index), - GNUNET_PQ_query_param_uint16 (&i), - GNUNET_PQ_query_param_auto_from_type (&links[i].shared_secret_enc), - GNUNET_PQ_query_param_end - }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (session_hash), + GNUNET_PQ_query_param_auto_from_type (&link->transfer_pub), + GNUNET_PQ_query_param_uint16 (&cnc_index), + GNUNET_PQ_query_param_auto_from_type (&link->shared_secret_enc), + GNUNET_PQ_query_param_end + }; - PGresult *result = GNUNET_PQ_exec_prepared (session->conn, - "insert_refresh_commit_link", - params); - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } + PGresult *result; - if (0 != strcmp ("1", PQcmdTuples (result))) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } + result = GNUNET_PQ_exec_prepared (session->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; } @@ -3423,64 +3258,56 @@ postgres_insert_refresh_commit_links (void *cls, * @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 commit_link array - * @param[out] links array of link information to return + * @param[out] link information to return * @return #GNUNET_SYSERR on internal error, * #GNUNET_NO if commitment was not found * #GNUNET_OK on success */ static int -postgres_get_refresh_commit_links (void *cls, - struct TALER_EXCHANGEDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t cnc_index, - uint16_t num_links, - struct TALER_RefreshCommitLinkP *links) +postgres_get_refresh_commit_link (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct GNUNET_HashCode *session_hash, + uint16_t cnc_index, + struct TALER_RefreshCommitLinkP *link) { - uint16_t i; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (session_hash), + GNUNET_PQ_query_param_uint16 (&cnc_index), + GNUNET_PQ_query_param_end + }; + PGresult *result; - for (i=0;i<num_links;i++) + result = GNUNET_PQ_exec_prepared (session->conn, + "get_refresh_commit_link", + params); + if (PGRES_TUPLES_OK != PQresultStatus (result)) { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (session_hash), - GNUNET_PQ_query_param_uint16 (&cnc_index), - GNUNET_PQ_query_param_uint16 (&i), - GNUNET_PQ_query_param_end + BREAK_DB_ERR (result); + PQclear (result); + return GNUNET_SYSERR; + } + if (0 == PQntuples (result)) + { + PQclear (result); + return GNUNET_NO; + } + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("transfer_pub", + &link->transfer_pub), + GNUNET_PQ_result_spec_auto_from_type ("link_secret_enc", + &link->shared_secret_enc), + GNUNET_PQ_result_spec_end }; - PGresult *result; - result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_commit_link", - params); - if (PGRES_TUPLES_OK != PQresultStatus (result)) + if (GNUNET_YES != + GNUNET_PQ_extract_result (result, rs, 0)) { - BREAK_DB_ERR (result); PQclear (result); return GNUNET_SYSERR; } - if (0 == PQntuples (result)) - { - PQclear (result); - return GNUNET_NO; - } - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("transfer_pub", - &links[i].transfer_pub), - GNUNET_PQ_result_spec_auto_from_type ("link_secret_enc", - &links[i].shared_secret_enc), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_YES != - GNUNET_PQ_extract_result (result, rs, 0)) - { - PQclear (result); - return GNUNET_SYSERR; - } - } - PQclear (result); } + PQclear (result); return GNUNET_OK; } @@ -3502,7 +3329,6 @@ postgres_get_melt_commitment (void *cls, struct TALER_EXCHANGEDB_RefreshSession rs; struct TALER_EXCHANGEDB_MeltCommitment *mc; uint16_t cnc_index; - unsigned int i; if (GNUNET_OK != postgres_get_refresh_session (cls, @@ -3512,17 +3338,6 @@ postgres_get_melt_commitment (void *cls, return NULL; mc = GNUNET_new (struct TALER_EXCHANGEDB_MeltCommitment); mc->num_newcoins = rs.num_newcoins; - mc->num_oldcoins = rs.num_oldcoins; - mc->melts = GNUNET_malloc (mc->num_oldcoins * - sizeof (struct TALER_EXCHANGEDB_RefreshMelt)); - for (i=0;i<mc->num_oldcoins;i++) - if (GNUNET_OK != - postgres_get_refresh_melt (cls, - session, - session_hash, - (uint16_t) i, - &mc->melts[i])) - goto cleanup; mc->denom_pubs = GNUNET_malloc (mc->num_newcoins * sizeof (struct TALER_DenominationPublicKey)); if (GNUNET_OK != @@ -3545,16 +3360,12 @@ postgres_get_melt_commitment (void *cls, mc->num_newcoins, mc->commit_coins[cnc_index])) goto cleanup; - mc->commit_links[cnc_index] - = GNUNET_malloc (mc->num_oldcoins * - sizeof (struct TALER_RefreshCommitLinkP)); if (GNUNET_OK != - postgres_get_refresh_commit_links (cls, - session, - session_hash, - cnc_index, - mc->num_oldcoins, - mc->commit_links[cnc_index])) + postgres_get_refresh_commit_link (cls, + session, + session_hash, + cnc_index, + &mc->commit_links[cnc_index])) goto cleanup; } return mc; @@ -3803,8 +3614,8 @@ postgres_get_coin_transactions (void *cls, struct TALER_EXCHANGEDB_TransactionList *tl; result = GNUNET_PQ_exec_prepared (session->conn, - "get_deposit_with_coin_pub", - params); + "get_deposit_with_coin_pub", + params); if (PGRES_TUPLES_OK != PQresultStatus (result)) { QUERY_ERR (result); @@ -3820,21 +3631,21 @@ postgres_get_coin_transactions (void *cls, { struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint64 ("transaction_id", - &deposit->transaction_id), + &deposit->transaction_id), TALER_PQ_result_spec_amount ("amount_with_fee", &deposit->amount_with_fee), TALER_PQ_result_spec_amount ("deposit_fee", &deposit->deposit_fee), GNUNET_PQ_result_spec_absolute_time ("timestamp", - &deposit->timestamp), + &deposit->timestamp), GNUNET_PQ_result_spec_absolute_time ("refund_deadline", - &deposit->refund_deadline), + &deposit->refund_deadline), GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", - &deposit->merchant_pub), + &deposit->merchant_pub), GNUNET_PQ_result_spec_auto_from_type ("h_contract", - &deposit->h_contract), + &deposit->h_contract), GNUNET_PQ_result_spec_auto_from_type ("h_wire", - &deposit->h_wire), + &deposit->h_wire), TALER_PQ_result_spec_json ("wire", &deposit->wire), GNUNET_PQ_result_spec_auto_from_type ("coin_sig", @@ -3874,8 +3685,8 @@ postgres_get_coin_transactions (void *cls, /* check if the melt records exist and get them */ result = GNUNET_PQ_exec_prepared (session->conn, - "get_refresh_melt_by_coin", - params); + "get_refresh_session_by_coin", + params); if (PGRES_TUPLES_OK != PQresultStatus (result)) { BREAK_DB_ERR (result); @@ -3891,10 +3702,10 @@ postgres_get_coin_transactions (void *cls, { struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("session_hash", - &melt->session_hash), + &melt->session_hash), /* oldcoin_index not needed */ - GNUNET_PQ_result_spec_auto_from_type ("coin_sig", - &melt->coin_sig), + GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig", + &melt->coin_sig), TALER_PQ_result_spec_amount ("amount_with_fee", &melt->amount_with_fee), TALER_PQ_result_spec_amount ("melt_fee", @@ -4506,14 +4317,12 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) plugin->insert_refund = &postgres_insert_refund; plugin->get_refresh_session = &postgres_get_refresh_session; plugin->create_refresh_session = &postgres_create_refresh_session; - plugin->insert_refresh_melt = &postgres_insert_refresh_melt; - plugin->get_refresh_melt = &postgres_get_refresh_melt; plugin->insert_refresh_order = &postgres_insert_refresh_order; plugin->get_refresh_order = &postgres_get_refresh_order; plugin->insert_refresh_commit_coins = &postgres_insert_refresh_commit_coins; plugin->get_refresh_commit_coins = &postgres_get_refresh_commit_coins; - plugin->insert_refresh_commit_links = &postgres_insert_refresh_commit_links; - plugin->get_refresh_commit_links = &postgres_get_refresh_commit_links; + plugin->insert_refresh_commit_link = &postgres_insert_refresh_commit_link; + plugin->get_refresh_commit_link = &postgres_get_refresh_commit_link; plugin->get_melt_commitment = &postgres_get_melt_commitment; plugin->free_melt_commitment = &common_free_melt_commitment; plugin->insert_refresh_out = &postgres_insert_refresh_out; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 2feeb5247..3169f06db 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -458,14 +458,13 @@ test_refresh_commit_links (struct TALER_EXCHANGEDB_Session *session, static int test_melting (struct TALER_EXCHANGEDB_Session *session) { -#define MELT_OLD_COINS 10 struct TALER_EXCHANGEDB_RefreshSession refresh_session; struct TALER_EXCHANGEDB_RefreshSession ret_refresh_session; struct GNUNET_HashCode session_hash; struct DenomKeyPair *dkp; struct DenomKeyPair **new_dkp; /* struct TALER_CoinPublicInfo *coins; */ - struct TALER_EXCHANGEDB_RefreshMelt *melts; + struct TALER_EXCHANGEDB_RefreshMelt *meltp; struct TALER_DenominationPublicKey *new_denom_pubs; struct TALER_DenominationPublicKey *ret_denom_pubs; struct TALER_EXCHANGEDB_MeltCommitment *mc; @@ -475,89 +474,77 @@ test_melting (struct TALER_EXCHANGEDB_Session *session) ret = GNUNET_SYSERR; RND_BLK (&refresh_session); RND_BLK (&session_hash); - melts = NULL; dkp = NULL; new_dkp = NULL; new_denom_pubs = NULL; ret_denom_pubs = NULL; /* create and test a refresh session */ - refresh_session.num_oldcoins = MELT_OLD_COINS; refresh_session.num_newcoins = 1; refresh_session.noreveal_index = 1; - FAILIF (GNUNET_OK != plugin->create_refresh_session (plugin->cls, - session, - &session_hash, - &refresh_session)); - FAILIF (GNUNET_OK != plugin->get_refresh_session (plugin->cls, - session, - &session_hash, - &ret_refresh_session)); - FAILIF (0 != memcmp (&ret_refresh_session, - &refresh_session, - sizeof (refresh_session))); - /* create a denomination (value: 1; fraction: 100) */ - dkp = create_denom_key_pair (512, session, + dkp = create_denom_key_pair (512, + session, &value, &fee_withdraw, &fee_deposit, &fee_refresh, &fee_refund); - /* create MELT_OLD_COINS number of refresh melts */ - melts = GNUNET_new_array (MELT_OLD_COINS, - struct TALER_EXCHANGEDB_RefreshMelt); - for (cnt=0; cnt < MELT_OLD_COINS; cnt++) + /* initialize refresh session melt data */ { struct GNUNET_HashCode hc; - RND_BLK (&melts[cnt].coin.coin_pub); - GNUNET_CRYPTO_hash (&melts[cnt].coin.coin_pub, - sizeof (melts[cnt].coin.coin_pub), + meltp = &refresh_session.melt; + RND_BLK (&meltp->coin.coin_pub); + GNUNET_CRYPTO_hash (&meltp->coin.coin_pub, + sizeof (meltp->coin.coin_pub), &hc); - melts[cnt].coin.denom_sig.rsa_signature = + meltp->coin.denom_sig.rsa_signature = GNUNET_CRYPTO_rsa_sign_fdh (dkp->priv.rsa_private_key, &hc); - melts[cnt].coin.denom_pub = dkp->pub; - RND_BLK (&melts[cnt].coin_sig); - melts[cnt].session_hash = session_hash; - melts[cnt].amount_with_fee = amount_with_fee; - melts[cnt].melt_fee = fee_refresh; - FAILIF (GNUNET_OK != - plugin->insert_refresh_melt (plugin->cls, - session, - cnt, - &melts[cnt])); + meltp->coin.denom_pub = dkp->pub; + RND_BLK (&meltp->coin_sig); + meltp->session_hash = session_hash; + meltp->amount_with_fee = amount_with_fee; + meltp->melt_fee = fee_refresh; } - for (cnt = 0; cnt < MELT_OLD_COINS; cnt++) + + FAILIF (GNUNET_OK != plugin->create_refresh_session (plugin->cls, + session, + &session_hash, + &refresh_session)); + FAILIF (GNUNET_OK != plugin->get_refresh_session (plugin->cls, + session, + &session_hash, + &ret_refresh_session)); + FAILIF (ret_refresh_session.num_newcoins != refresh_session.num_newcoins); + FAILIF (ret_refresh_session.noreveal_index != refresh_session.noreveal_index); + + /* check refresh sesison melt data */ { - struct TALER_EXCHANGEDB_RefreshMelt ret_melt; - FAILIF (GNUNET_OK != - plugin->get_refresh_melt (plugin->cls, - session, - &session_hash, - cnt, - &ret_melt)); + struct TALER_EXCHANGEDB_RefreshMelt *ret_melt; + + ret_melt = &ret_refresh_session.melt; FAILIF (0 != GNUNET_CRYPTO_rsa_signature_cmp - (ret_melt.coin.denom_sig.rsa_signature, - melts[cnt].coin.denom_sig.rsa_signature)); - FAILIF (0 != memcmp (&ret_melt.coin.coin_pub, - &melts[cnt].coin.coin_pub, - sizeof (ret_melt.coin.coin_pub))); + (ret_melt->coin.denom_sig.rsa_signature, + meltp->coin.denom_sig.rsa_signature)); + FAILIF (0 != memcmp (&ret_melt->coin.coin_pub, + &meltp->coin.coin_pub, + sizeof (ret_melt->coin.coin_pub))); FAILIF (0 != GNUNET_CRYPTO_rsa_public_key_cmp - (ret_melt.coin.denom_pub.rsa_public_key, - melts[cnt].coin.denom_pub.rsa_public_key)); - FAILIF (0 != memcmp (&ret_melt.coin_sig, - &melts[cnt].coin_sig, - sizeof (ret_melt.coin_sig))); - FAILIF (0 != memcmp (&ret_melt.session_hash, - &melts[cnt].session_hash, - sizeof (ret_melt.session_hash))); - FAILIF (0 != TALER_amount_cmp (&ret_melt.amount_with_fee, - &melts[cnt].amount_with_fee)); - FAILIF (0 != TALER_amount_cmp (&ret_melt.melt_fee, - &melts[cnt].melt_fee)); - GNUNET_CRYPTO_rsa_signature_free (ret_melt.coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (ret_melt.coin.denom_pub.rsa_public_key); + (ret_melt->coin.denom_pub.rsa_public_key, + meltp->coin.denom_pub.rsa_public_key)); + FAILIF (0 != memcmp (&ret_melt->coin_sig, + &meltp->coin_sig, + sizeof (ret_melt->coin_sig))); + FAILIF (0 != memcmp (&ret_melt->session_hash, + &meltp->session_hash, + sizeof (ret_melt->session_hash))); + FAILIF (0 != TALER_amount_cmp (&ret_melt->amount_with_fee, + &meltp->amount_with_fee)); + FAILIF (0 != TALER_amount_cmp (&ret_melt->melt_fee, + &meltp->melt_fee)); + GNUNET_CRYPTO_rsa_signature_free (ret_melt->coin.denom_sig.rsa_signature); + GNUNET_CRYPTO_rsa_public_key_free (ret_melt->coin.denom_pub.rsa_public_key); } new_dkp = GNUNET_new_array (MELT_NEW_COINS, struct DenomKeyPair *); new_denom_pubs = GNUNET_new_array (MELT_NEW_COINS, @@ -619,15 +606,10 @@ test_melting (struct TALER_EXCHANGEDB_Session *session) drop: if (NULL != dkp) destroy_denom_key_pair (dkp); - if (NULL != melts) - { - for (cnt = 0; cnt < MELT_OLD_COINS; cnt++) - GNUNET_CRYPTO_rsa_signature_free (melts[cnt].coin.denom_sig.rsa_signature); - GNUNET_free (melts); - } + GNUNET_CRYPTO_rsa_signature_free (meltp->coin.denom_sig.rsa_signature); for (cnt = 0; (NULL != ret_denom_pubs) && (cnt < MELT_NEW_COINS) - && (NULL != ret_denom_pubs[cnt].rsa_public_key); + && (NULL != ret_denom_pubs[cnt].rsa_public_key); cnt++) GNUNET_CRYPTO_rsa_public_key_free (ret_denom_pubs[cnt].rsa_public_key); GNUNET_free_non_null (ret_denom_pubs); diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 09cbd7868..fd09b5286 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -711,12 +711,12 @@ typedef void */ struct TALER_EXCHANGE_ReserveWithdrawHandle * TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_EXCHANGE_DenomPublicKey *pk, - const struct TALER_ReservePrivateKeyP *reserve_priv, - const struct TALER_CoinSpendPrivateKeyP *coin_priv, - const struct TALER_DenominationBlindingKey *blinding_key, - TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb, - void *res_cb_cls); + const struct TALER_EXCHANGE_DenomPublicKey *pk, + const struct TALER_ReservePrivateKeyP *reserve_priv, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + const struct TALER_DenominationBlindingKey *blinding_key, + TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb, + void *res_cb_cls); /** @@ -745,8 +745,8 @@ TALER_EXCHANGE_reserve_withdraw_cancel (struct TALER_EXCHANGE_ReserveWithdrawHan * to #TALER_EXCHANGE_refresh_melt() that will generate the request. * * This function does verify that the given request data is internally - * consistent. However, the @a melts_sigs are only verified if @a - * check_sigs is set to #GNUNET_YES, as this may be relatively + * consistent. However, the @a melts_sig is only verified if @a + * check_sig is set to #GNUNET_YES, as this may be relatively * expensive and should be redundant. * * Aside from some non-trivial cryptographic operations that might @@ -754,17 +754,16 @@ TALER_EXCHANGE_reserve_withdraw_cancel (struct TALER_EXCHANGE_ReserveWithdrawHan * its result immediately and does not start any asynchronous * processing. This function is also thread-safe. * - * @param num_melts number of coins that are being melted (typically 1) - * @param melt_privs array of @a num_melts private keys of the coins to melt - * @param melt_amounts array of @a num_melts amounts specifying how much - * each coin will contribute to the melt (including fee) - * @param melt_sigs array of @a num_melts signatures affirming the + * @param melt_priv private keys of the coin to melt + * @param melt_amount amount specifying how much + * the coin will contribute to the melt (including fee) + * @param melt_sig signatures affirming the * validity of the public keys corresponding to the - * @a melt_privs private keys - * @param melt_pks array of @a num_melts denomination key information - * records corresponding to the @a melt_sigs + * @a melt_priv private key + * @param melt_pk denomination key information + * record corresponding to the @a melt_sig * validity of the keys - * @param check_sigs verify the validity of the signatures of @a melt_sigs + * @param check_sig verify the validity of the signatures of @a melt_sig * @param fresh_pks_len length of the @a pks array * @param fresh_pks array of @a pks_len denominations of fresh coins to create * @param[out] res_size set to the size of the return value, or 0 on error @@ -775,12 +774,11 @@ TALER_EXCHANGE_reserve_withdraw_cancel (struct TALER_EXCHANGE_ReserveWithdrawHan * Non-null results should be freed using #GNUNET_free(). */ char * -TALER_EXCHANGE_refresh_prepare (unsigned int num_melts, - const struct TALER_CoinSpendPrivateKeyP *melt_privs, - const struct TALER_Amount *melt_amounts, - const struct TALER_DenominationSignature *melt_sigs, - const struct TALER_EXCHANGE_DenomPublicKey *melt_pks, - int check_sigs, +TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_priv, + const struct TALER_Amount *melt_amount, + const struct TALER_DenominationSignature *melt_sig, + const struct TALER_EXCHANGE_DenomPublicKey *melt_pk, + int check_sig, unsigned int fresh_pks_len, const struct TALER_EXCHANGE_DenomPublicKey *fresh_pks, size_t *res_size); diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index fff6e251d..2cc3b439c 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -359,33 +359,6 @@ struct TALER_EXCHANGEDB_Refund /** - * @brief Global information for a refreshing session. Includes - * dimensions of the operation, security parameters and - * client signatures from "/refresh/melt" and "/refresh/commit". - */ -struct TALER_EXCHANGEDB_RefreshSession -{ - - /** - * Number of coins we are melting. - */ - uint16_t num_oldcoins; - - /** - * Number of new coins we are creating. - */ - uint16_t num_newcoins; - - /** - * Index (smaller #TALER_CNC_KAPPA) which the exchange has chosen to not - * have revealed during cut and choose. - */ - uint16_t noreveal_index; - -}; - - -/** * @brief Specification for coin in a /refresh/melt operation. */ struct TALER_EXCHANGEDB_RefreshMelt @@ -430,6 +403,33 @@ struct TALER_EXCHANGEDB_RefreshMelt /** + * @brief Global information for a refreshing session. Includes + * dimensions of the operation, security parameters and + * client signatures from "/refresh/melt" and "/refresh/commit". + */ +struct TALER_EXCHANGEDB_RefreshSession +{ + + /** + * Melt operation details. + */ + struct TALER_EXCHANGEDB_RefreshMelt melt; + + /** + * Number of new coins we are creating. + */ + uint16_t num_newcoins; + + /** + * Index (smaller #TALER_CNC_KAPPA) which the exchange has chosen to not + * have revealed during cut and choose. + */ + uint16_t noreveal_index; + +}; + + +/** * @brief We have as many `struct TALER_EXCHANGEDB_RefreshCommitCoin` as there are new * coins being created by the refresh (for each of the #TALER_CNC_KAPPA * sets). These are the coins we ask the exchange to sign if the @@ -558,21 +558,11 @@ struct TALER_EXCHANGEDB_MeltCommitment { /** - * Number of coins we are melting. - */ - uint16_t num_oldcoins; - - /** * Number of new coins we are creating. */ uint16_t num_newcoins; /** - * Array of @e num_oldcoins melt operation details. - */ - struct TALER_EXCHANGEDB_RefreshMelt *melts; - - /** * Array of @e num_newcoins denomination keys */ struct TALER_DenominationPublicKey *denom_pubs; @@ -583,9 +573,9 @@ struct TALER_EXCHANGEDB_MeltCommitment struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins[TALER_CNC_KAPPA]; /** - * 2D-Array of #TALER_CNC_KAPPA and @e new_oldcoins links. + * Array of #TALER_CNC_KAPPA links. */ - struct TALER_RefreshCommitLinkP *commit_links[TALER_CNC_KAPPA]; + struct TALER_RefreshCommitLinkP commit_links[TALER_CNC_KAPPA]; }; @@ -1117,43 +1107,6 @@ struct TALER_EXCHANGEDB_Plugin /** - * Store the given /refresh/melt request in the database. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @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 - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on internal error - */ - int - (*insert_refresh_melt) (void *cls, - struct TALER_EXCHANGEDB_Session *session, - uint16_t oldcoin_index, - const struct TALER_EXCHANGEDB_RefreshMelt *melt); - - - /** - * Get information about melted coin details from the database. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @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 - * @return #GNUNET_OK on success - * #GNUNET_SYSERR on internal error - */ - int - (*get_refresh_melt) (void *cls, - struct TALER_EXCHANGEDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t oldcoin_index, - struct TALER_EXCHANGEDB_RefreshMelt *melt); - - - /** * Store in the database which coin(s) we want to create * in a given refresh operation. * @@ -1245,18 +1198,16 @@ struct TALER_EXCHANGEDB_Plugin * @param cls the @e cls of this struct with the plugin-specific state * @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 - * @param commit_links array of link information to store + * @param cnc_index cut and choose index, relating to #TALER_CNC_KAPPA + * @param link link information to store * @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success */ int - (*insert_refresh_commit_links) (void *cls, - struct TALER_EXCHANGEDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t cnc_index, - uint16_t num_links, - const struct TALER_RefreshCommitLinkP *commit_links); + (*insert_refresh_commit_link) (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct GNUNET_HashCode *session_hash, + uint16_t cnc_index, + const struct TALER_RefreshCommitLinkP *link); /** * Obtain the commited (encrypted) refresh link data @@ -1266,19 +1217,17 @@ struct TALER_EXCHANGEDB_Plugin * @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 - * @param[out] links array link information to return + * @param[out] link information to return * @return #GNUNET_SYSERR on internal error, * #GNUNET_NO if commitment was not found * #GNUNET_OK on success */ int - (*get_refresh_commit_links) (void *cls, - struct TALER_EXCHANGEDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t cnc_index, - uint16_t num_links, - struct TALER_RefreshCommitLinkP *links); + (*get_refresh_commit_link) (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct GNUNET_HashCode *session_hash, + uint16_t cnc_index, + struct TALER_RefreshCommitLinkP *link); /** |