aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-05-16 11:55:47 +0200
committerChristian Grothoff <christian@grothoff.org>2016-05-16 11:55:47 +0200
commitc8b9370413d6a330f3b457359ed309ac9e964533 (patch)
tree5ae6cc04d2d04731fdf802704ab2570dc3587040 /src
parent068dbf020b1f762d4364ca378c1396d16fa6eb1a (diff)
fixing #3814 by removing ability to melt multiple oldcoins at the same time
Diffstat (limited to 'src')
-rw-r--r--src/exchange-lib/exchange_api_refresh.c259
-rw-r--r--src/exchange-lib/test_exchange_api.c94
-rw-r--r--src/exchange/taler-exchange-httpd_db.c295
-rw-r--r--src/exchange/taler-exchange-httpd_db.h14
-rw-r--r--src/exchange/taler-exchange-httpd_refresh.c330
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c80
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h2
-rw-r--r--src/exchangedb/perf_taler_exchangedb.c5
-rw-r--r--src/exchangedb/perf_taler_exchangedb_init.c3
-rw-r--r--src/exchangedb/perf_taler_exchangedb_interpreter.c121
-rw-r--r--src/exchangedb/perf_taler_exchangedb_interpreter.h77
-rw-r--r--src/exchangedb/plugin_exchangedb_common.c10
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c483
-rw-r--r--src/exchangedb/test_exchangedb.c120
-rw-r--r--src/include/taler_exchange_service.h44
-rw-r--r--src/include/taler_exchangedb_plugin.h135
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);
/**