From d833966d521e9b836c8c854595671197c64c24f6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 4 Feb 2022 22:02:48 +0100 Subject: -API work --- src/lib/exchange_api_melt.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/lib/exchange_api_melt.c') diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index f375171b..204e5254 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -427,7 +427,8 @@ handle_melt_finished (void *cls, struct TALER_EXCHANGE_MeltHandle * TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, - const json_t *refresh_data, + const struct TALER_PlanchetSecretsP *ps, + const struct TALER_EXCHANGE_RefreshData *rd, TALER_EXCHANGE_MeltCallback melt_cb, void *melt_cb_cls) { @@ -445,9 +446,10 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, GNUNET_assert (GNUNET_YES == TEAH_handle_is_ready (exchange)); - md = TALER_EXCHANGE_deserialize_melt_data_ (refresh_data, - exchange->key_data.currency); - if (NULL == md) + if (GNUNET_OK != + TALER_EXCHANGE_get_melt_data (ps, + rd, + &md)) { GNUNET_break (0); return NULL; @@ -510,6 +512,7 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, if (NULL == mh->url) { json_decref (melt_obj); + TALER_EXCHANGE_free_melt_data_ (&md); GNUNET_free (mh); return NULL; } @@ -523,6 +526,7 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, GNUNET_break (0); if (NULL != eh) curl_easy_cleanup (eh); + TALER_EXCHANGE_free_melt_data_ (&md); json_decref (melt_obj); GNUNET_free (mh->url); GNUNET_free (mh); -- cgit v1.2.3 From cfc6c3fcd04e9bed639816828d05e8645d80860f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 4 Feb 2022 23:09:19 +0100 Subject: make API actually workable: --- src/include/taler_exchange_service.h | 11 +++++++++-- src/lib/exchange_api_melt.c | 2 +- src/lib/exchange_api_refreshes_reveal.c | 20 ++++++++++++++------ 3 files changed, 24 insertions(+), 9 deletions(-) (limited to 'src/lib/exchange_api_melt.c') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index ba80da3e..8fe1bf7d 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1609,6 +1609,8 @@ struct TALER_EXCHANGE_MeltHandle; * * @param cls closure * @param hr HTTP response data + * @param num_coins number of fresh coins to be created, length of the @a exchange_vals array, 0 if the operation failed + * @param alg_values array @a num_coins of exchange values contributed to the refresh operation * @param noreveal_index choice by the exchange in the cut-and-choose protocol, * UINT32_MAX on error * @param sign_key exchange key used to sign @a full_response, or NULL @@ -1617,6 +1619,8 @@ typedef void (*TALER_EXCHANGE_MeltCallback) ( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + unsigned int num_coins, + const struct TALER_ExchangeWithdrawValues *alg_values, uint32_t noreveal_index, const struct TALER_ExchangePublicKeyP *sign_key); @@ -1670,7 +1674,7 @@ TALER_EXCHANGE_melt_cancel (struct TALER_EXCHANGE_MeltHandle *mh); * * @param cls closure * @param hr HTTP response data - * @param num_coins number of fresh coins created, length of the @a exchange_vals, @a sigs and @a coin_privs arrays, 0 if the operation failed + * @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed * @param exchange_vals array of contributions from the exchange on the refreshes * @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error * @param sigs array of signature over @a num_coins coins, NULL on error @@ -1681,7 +1685,6 @@ typedef void const struct TALER_EXCHANGE_HttpResponse *hr, unsigned int num_coins, const struct TALER_CoinSpendPrivateKeyP *coin_privs, - const struct TALER_ExchangeWithdrawValues *exchange_vals, const struct TALER_DenominationSignature *sigs); @@ -1703,6 +1706,8 @@ struct TALER_EXCHANGE_RefreshesRevealHandle; * @param exchange the exchange handle; the exchange must be ready to operate * @param ps the fresh secret that defines the refresh operation * @param rd the refresh data that characterizes the refresh operation + * @param num_coins number of fresh coins to be created, length of the @a exchange_vals array, must match value in @a rd + * @param alg_values array @a num_coins of exchange values contributed to the refresh operation * @param noreveal_index response from the exchange to the * #TALER_EXCHANGE_melt() invocation * @param reveal_cb the callback to call with the final result of the @@ -1716,6 +1721,8 @@ TALER_EXCHANGE_refreshes_reveal ( struct TALER_EXCHANGE_Handle *exchange, const struct TALER_PlanchetSecretsP *ps, const struct TALER_EXCHANGE_RefreshData *rd, + unsigned int num_coins, + const struct TALER_ExchangeWithdrawValues *alg_values, uint32_t noreveal_index, TALER_EXCHANGE_RefreshesRevealCallback reveal_cb, void *reveal_cb_cls); diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index 204e5254..b93d255e 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015-2021 Taler Systems SA + Copyright (C) 2015-2022 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c index 85d20e55..a233df4b 100644 --- a/src/lib/exchange_api_refreshes_reveal.c +++ b/src/lib/exchange_api_refreshes_reveal.c @@ -95,12 +95,14 @@ struct TALER_EXCHANGE_RefreshesRevealHandle * * @param rrh operation handle * @param json reply from the exchange - * @param[out] sigs array of length `num_fresh_coins`, initialized to contain RSA signatures + * @param[out] sigs array of length `num_fresh_coins`, initialized to contain the coin private keys + * @param[out] sigs array of length `num_fresh_coins`, initialized to contain signatures * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors */ static enum GNUNET_GenericReturnValue refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh, const json_t *json, + struct TALER_CoinSpendPrivateKeyP *coin_privs, struct TALER_DenominationSignature *sigs) { json_t *jsona; @@ -165,6 +167,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh, /* needed to verify the signature, and we didn't store it earlier, hence recomputing it here... */ + coin_privs[i] = fc->coin_priv; GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv, &coin_pub.eddsa_pub); /* FIXME-Oec: Age commitment hash. */ @@ -223,13 +226,15 @@ handle_refresh_reveal_finished (void *cls, case MHD_HTTP_OK: { struct TALER_DenominationSignature sigs[rrh->md->num_fresh_coins]; - int ret; + struct TALER_CoinSpendPrivateKeyP coin_privs[rrh->md->num_fresh_coins]; + enum GNUNET_GenericReturnValue ret; memset (sigs, 0, sizeof (sigs)); ret = refresh_reveal_ok (rrh, j, + coin_privs, sigs); if (GNUNET_OK != ret) { @@ -241,7 +246,7 @@ handle_refresh_reveal_finished (void *cls, rrh->reveal_cb (rrh->reveal_cb_cls, &hr, rrh->md->num_fresh_coins, - rrh->md->fresh_coins[rrh->noreveal_index], + coin_privs, sigs); rrh->reveal_cb = NULL; } @@ -300,6 +305,8 @@ TALER_EXCHANGE_refreshes_reveal ( struct TALER_EXCHANGE_Handle *exchange, const struct TALER_PlanchetSecretsP *ps, const struct TALER_EXCHANGE_RefreshData *rd, + unsigned int num_coins, + const struct TALER_ExchangeWithdrawValues *alg_values, uint32_t noreveal_index, TALER_EXCHANGE_RefreshesRevealCallback reveal_cb, void *reveal_cb_cls) @@ -363,11 +370,9 @@ TALER_EXCHANGE_refreshes_reveal ( GNUNET_JSON_from_data_auto ( &denom_hash))); - // TODO: implement cipher handling - alg_values.cipher = TALER_DENOMINATION_RSA; if (GNUNET_OK != TALER_planchet_prepare (&md.fresh_pks[i], - &alg_values, + &rrh->exchange_vals[i], &md.fresh_coins[noreveal_index][i], &c_hash, &pd)) @@ -452,6 +457,8 @@ TALER_EXCHANGE_refreshes_reveal ( } /* finally, we can actually issue the request */ rrh = GNUNET_new (struct TALER_EXCHANGE_RefreshesRevealHandle); + rrh->exchange_vals = GNUNET_new_array (struct TALER_ExchangeWithdrawValues, + md.num_fresh_coins); rrh->exchange = exchange; rrh->noreveal_index = noreveal_index; rrh->reveal_cb = reveal_cb; @@ -505,6 +512,7 @@ TALER_EXCHANGE_refreshes_reveal_cancel ( GNUNET_free (rrh->url); TALER_curl_easy_post_finished (&rrh->ctx); TALER_EXCHANGE_free_melt_data_ (rrh->md); /* does not free 'md' itself */ + GNUNET_free (rrh->exchange_vals); GNUNET_free (rrh->md); GNUNET_free (rrh); } -- cgit v1.2.3 From b30765c7d07240a48e66a551e6f82dc0a5670bec Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 4 Feb 2022 23:58:41 +0100 Subject: make API actually workable, sketch out melt --- src/include/taler_exchange_service.h | 30 ++++- src/lib/exchange_api_melt.c | 230 +++++++++++++++++++++++++++------- src/lib/exchange_api_refresh_common.c | 1 + src/lib/exchange_api_refresh_common.h | 10 +- 4 files changed, 221 insertions(+), 50 deletions(-) (limited to 'src/lib/exchange_api_melt.c') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 8fe1bf7d..44ef48d4 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1063,9 +1063,10 @@ struct TALER_EXCHANGE_CsRResponse struct { /** - * Signature over the coin. + * Values contributed by the exchange for the + * respective coin's withdraw operation. */ - struct TALER_DenominationCsPublicR r_pubs; + const struct TALER_ExchangeWithdrawValues *alg_values; } success; /** @@ -1092,12 +1093,29 @@ typedef void const struct TALER_EXCHANGE_CsRResponse *csrr); +/** + * Information we pass per coin to a /csr request. + */ +struct TALER_EXCHANGE_NonceKey +{ + /** + * Which denomination key is the /csr request for? + */ + const struct TALER_EXCHANGE_DenomPublicKey *pk; + + /** + * What is the client nonce for the request? + */ + struct TALER_CsNonce nonce; +}; + + /** * Get a CS R using a /csr request. * * @param exchange the exchange handle; the exchange must be ready to operate - * @param pk denomination of coin the R's will be used for - * @param nonce public nonce for CS R request + * @param nks_len length of the @a nks array + * @param nks array of denominations and nonces * @param res_cb the callback to call when the final result for this request is available * @param res_cb_cls closure for the above callback * @return handle for the operation on success, NULL on error, i.e. @@ -1106,8 +1124,8 @@ typedef void */ struct TALER_EXCHANGE_CsRHandle * TALER_EXCHANGE_csr (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_EXCHANGE_DenomPublicKey *pk, - const struct TALER_CsNonce *nonce, + unsigned int nks_len, + struct TALER_EXCHANGE_NonceKey *nks, TALER_EXCHANGE_CsRCallback res_cb, void *res_cb_cls); diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index b93d255e..dc9a400d 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -73,7 +73,23 @@ struct TALER_EXCHANGE_MeltHandle /** * Actual information about the melt operation. */ - struct MeltData *md; + struct MeltData md; + + /** + * The secret the entire melt operation is seeded from. + */ + const struct TALER_PlanchetSecretsP *ps; + + /** + * Details about the characteristics of the requested melt operation. + */ + const struct TALER_EXCHANGE_RefreshData *rd; + + /** + * Array of `num_fresh_coins` contributory values of + * the exchange to the melt operation. + */ + struct TALER_ExchangeWithdrawValues *alg_values; /** * Public key of the coin being melted. @@ -106,9 +122,12 @@ verify_melt_signature_ok (struct TALER_EXCHANGE_MeltHandle *mh, struct TALER_ExchangeSignatureP exchange_sig; const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), - GNUNET_JSON_spec_uint32 ("noreveal_index", noreveal_index), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", + &exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", + exchange_pub), + GNUNET_JSON_spec_uint32 ("noreveal_index", + noreveal_index), GNUNET_JSON_spec_end () }; struct TALER_RefreshMeltConfirmationPS confirm; @@ -338,6 +357,12 @@ handle_melt_finished (void *cls, { mh->melt_cb (mh->melt_cb_cls, &hr, + (0 == hr.http_status) + ? 0 + : mh->rd->fresh_pks_len, + (0 == hr.http_status) + ? NULL + : mh->alg_values, noreveal_index, (0 == hr.http_status) ? NULL @@ -419,42 +444,37 @@ handle_melt_finished (void *cls, if (NULL != mh->melt_cb) mh->melt_cb (mh->melt_cb_cls, &hr, + 0, + NULL, UINT32_MAX, NULL); TALER_EXCHANGE_melt_cancel (mh); } -struct TALER_EXCHANGE_MeltHandle * -TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_PlanchetSecretsP *ps, - const struct TALER_EXCHANGE_RefreshData *rd, - TALER_EXCHANGE_MeltCallback melt_cb, - void *melt_cb_cls) +static enum GNUNET_GenericReturnValue +start_melt (struct TALER_EXCHANGE_MeltHandle *mh) { const struct TALER_EXCHANGE_Keys *key_state; const struct TALER_EXCHANGE_DenomPublicKey *dki; json_t *melt_obj; - struct TALER_EXCHANGE_MeltHandle *mh; CURL *eh; struct GNUNET_CURL_Context *ctx; - struct MeltData *md; struct TALER_CoinSpendSignatureP confirm_sig; char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32]; struct TALER_DenominationHash h_denom_pub; struct TALER_CoinSpendPublicKeyP coin_pub; - GNUNET_assert (GNUNET_YES == - TEAH_handle_is_ready (exchange)); if (GNUNET_OK != - TALER_EXCHANGE_get_melt_data (ps, - rd, - &md)) + TALER_EXCHANGE_get_melt_data_ (mh->ps, + mh->rd, + mh->alg_values, + &mh->md)) { GNUNET_break (0); - return NULL; + return GNUNET_SYSERR; } - TALER_denom_pub_hash (&md->melted_coin.pub_key, + TALER_denom_pub_hash (&mh->md.melted_coin.pub_key, &h_denom_pub); TALER_wallet_melt_sign (&md->melted_coin.melt_amount_with_fee, &md->melted_coin.fee_melt, @@ -491,30 +511,19 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, pub_str); } - key_state = TALER_EXCHANGE_get_keys (exchange); + ctx = TEAH_handle_to_context (mh->exchange); + key_state = TALER_EXCHANGE_get_keys (mh->exchange); dki = TALER_EXCHANGE_get_denomination_key (key_state, - &md->melted_coin.pub_key); + &mh->md.melted_coin.pub_key); /* and now we can at last begin the actual request handling */ - mh = GNUNET_new (struct TALER_EXCHANGE_MeltHandle); - mh->exchange = exchange; - mh->coin_pub = coin_pub; - mh->dki = *dki; - memset (&mh->dki.key, - 0, - sizeof (mh->dki.key)); /* lifetime not warranted, so better - not copy the pointers */ - mh->melt_cb = melt_cb; - mh->melt_cb_cls = melt_cb_cls; - mh->md = md; - mh->url = TEAH_path_to_url (exchange, + + mh->url = TEAH_path_to_url (mh->exchange, arg_str); if (NULL == mh->url) { json_decref (melt_obj); - TALER_EXCHANGE_free_melt_data_ (&md); - GNUNET_free (mh); - return NULL; + return GNUNET_SYSERR; } eh = TALER_EXCHANGE_curl_easy_get_ (mh->url); if ( (NULL == eh) || @@ -526,19 +535,155 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, GNUNET_break (0); if (NULL != eh) curl_easy_cleanup (eh); - TALER_EXCHANGE_free_melt_data_ (&md); json_decref (melt_obj); - GNUNET_free (mh->url); - GNUNET_free (mh); - return NULL; + return GNUNET_SYSERR; } json_decref (melt_obj); - ctx = TEAH_handle_to_context (exchange); mh->job = GNUNET_CURL_job_add2 (ctx, eh, mh->ctx.headers, &handle_melt_finished, mh); + return GNUNET_OK; +} + + +static void +fail_mh (struct TALER_EXCHANGE_MeltHandle *mh) +{ + // FIXME: do return more than NULLs if + // the /csr failed! + mh->melt_cb (mh->melt_cb_cls, + NULL, + 0, + NULL, + UINT32_MAX, + NULL); + TALER_EXCHANGE_melt_cancel (mh); +} + + +/** + * Callbacks of this type are used to serve the result of submitting a + * CS R request to a exchange. + * + * @param cls closure with our `struct TALER_EXCHANGE_MeltHandle *` + * @param csrr response details + */ +static void +csr_cb (void *cls, + const struct TALER_EXCHANGE_CsRResponse *csrr) +{ + struct TALER_EXCHANGE_MeltHandle *mh = cls; + unsigned int nks_off = 0; + + for (unsigned int i = 0; ifresh_pks_len; i++) + { + const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk = &rd->fresh_pks[i]; + struct TALER_ExchangeWithdrawValues *wv = &mh->alg_values[i]; + + switch (fresh_pk->cipher) + { + case TALER_DENOMINATION_INVALID: + GNUNET_break (0); + fail_mh (mh). + return; + case TALER_DENOMINATION_RSA: + GNUNET_assert (TALER_DENOMINATION_RSA == wv->cipher); + break; + case TALER_DENOMINATION_CS: + GNUNET_assert (TALER_DENOMINATION_CS == wv->cipher); + *wv = csrr->details.success.alg_values[nks_off]; + nks_off++; + break; + } + } + if (GNUNET_OK != + start_melt (mh)) + { + GNUNET_break (0); + fail_mh (mh); + return; + } +} + + +struct TALER_EXCHANGE_MeltHandle * +TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, + const struct TALER_PlanchetSecretsP *ps, + const struct TALER_EXCHANGE_RefreshData *rd, + TALER_EXCHANGE_MeltCallback melt_cb, + void *melt_cb_cls) +s +{ + const struct TALER_EXCHANGE_NonceKey *nks[GNUNET_NZL (rd->refresh_pks_len)]; + unsigned int nks_off = 0; + + if (0 == rd->refresh_pks_len) + { + GNUNET_break (0); + return NULL; + } + GNUNET_assert (GNUNET_YES == + TEAH_handle_is_ready (exchange)); + mh = GNUNET_new (struct TALER_EXCHANGE_MeltHandle); + mh->exchange = exchange; + mh->rd = rd; + mh->ps = ps; + mh->melt_cb = melt_cb; + mh->melt_cb_cls = melt_cb_cls; + mh->alg_values = GNUNET_new_array (struct TALER_ExchangeWithdrawValues, + rd->fresh_pks_len); + for (unsigned int i = 0; ifresh_pks_len; i++) + { + const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk = &rd->fresh_pks[i]; + struct TALER_ExchangeWithdrawValues *wv = &mh->alg_values[i]; + + switch (fresh_pk->cipher) + { + case TALER_DENOMINATION_INVALID: + GNUNET_break (0); + GNUNET_free (mh->alg_values); + GNUNET_free (mh); + return NULL; + case TALER_DENOMINATION_RSA: + wv->cipher = TALER_DENOMINATION_RSA; + break; + case TALER_DENOMINATION_CS: + wv->cipher = TALER_DENOMINATION_CS; + nks[nks_off].pk = fresh_pk; + // derive nonce for refresh by index and ps; + // FIXME: include fresh_pk or not? + TALER_CRYPTO_XXX (ps, + fresh_pk, + i, + &nks[nks_off].nonce); + nks_off++; + break; + } + } + if (0 != nks_off) + { + mh->csr = TALER_EXCHANGE_csr (exchange, + nks_off, + nks, + &csr_cb, + mh); + if (NULL == mh->csr) + { + GNUNET_break (0); + TALER_EXCHANGE_melt_cancel (mh->csr); + return NULL; + } + return mh; + } + if (GNUNET_OK != + start_melt (mh)) + { + GNUNET_break (0); + TALER_EXCHANGE_melt_cancel (mh->csr); + return NULL; + } return mh; } @@ -551,8 +696,7 @@ TALER_EXCHANGE_melt_cancel (struct TALER_EXCHANGE_MeltHandle *mh) GNUNET_CURL_job_cancel (mh->job); mh->job = NULL; } - TALER_EXCHANGE_free_melt_data_ (mh->md); /* does not free 'md' itself */ - GNUNET_free (mh->md); + TALER_EXCHANGE_free_melt_data_ (&mh->md); /* does not free 'md' itself */ GNUNET_free (mh->url); TALER_curl_easy_post_finished (&mh->ctx); GNUNET_free (mh); diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c index 9fcc2687..cf04bca5 100644 --- a/src/lib/exchange_api_refresh_common.c +++ b/src/lib/exchange_api_refresh_common.c @@ -46,6 +46,7 @@ enum GNUNET_GenericReturnValue TALER_EXCHANGE_get_melt_data_ ( const struct TALER_PlanchetSecretsP *ps, const struct struct TALER_EXCHANGE_RefreshData *rd, + const struct TALER_ExchangeWithdrawValues *alg_values, struct MeltData *md) { struct MeltData md; diff --git a/src/lib/exchange_api_refresh_common.h b/src/lib/exchange_api_refresh_common.h index 1ce513ef..653d4886 100644 --- a/src/lib/exchange_api_refresh_common.h +++ b/src/lib/exchange_api_refresh_common.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015-2020 Taler Systems SA + Copyright (C) 2015-2022 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -102,6 +102,12 @@ struct MeltData */ struct TALER_DenominationPublicKey *fresh_pks; + /** + * Array of @e num_fresh_coins with exchange contributions + * made during the refresh. + */ + struct TALER_ExchangeWithdrawValues *exchange_vals; + /** * Arrays of @e num_fresh_coins with information about the fresh * coins to be created, for each cut-and-choose dimension. @@ -115,12 +121,14 @@ struct MeltData * * @param ps secret internals of the refresh-reveal operation * @param rd refresh data with the characteristics of the operation + * @param alg_values contributions from the exchange into the melt * @param[out] rd where to write the derived melt data */ enum GNUNET_GenericReturnValue TALER_EXCHANGE_get_melt_data_ ( const struct TALER_PlanchetSecretsP *ps, const struct struct TALER_EXCHANGE_RefreshData *rd, + const struct TALER_ExchangeWithdrawValues *alg_values, struct MeltData *md); -- cgit v1.2.3