commit 66c969bdb0ec6c02f97780e86bb9323bccd4269a
parent 4a83e23f67e2f5ca7acc242137e2bea94d6c4c00
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 3 Mar 2026 23:44:49 +0100
post-withdraw code cleanup
Diffstat:
6 files changed, 479 insertions(+), 218 deletions(-)
diff --git a/src/include/taler/taler-exchange/post-withdraw_blinded.h b/src/include/taler/taler-exchange/post-withdraw_blinded.h
@@ -0,0 +1,336 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2026 Taler Systems SA
+
+ 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file include/taler/taler-exchange/post-withdraw_blinded.h
+ * @brief low-level C interface for POST /withdraw
+ * @author Christian Grothoff
+ */
+#ifndef _TALER_EXCHANGE__POST_WITHDRAW_BLINDED_H
+#define _TALER_EXCHANGE__POST_WITHDRAW_BLINDED_H
+
+#include <taler/taler-exchange/common.h>
+#include <taler/taler-exchange/post-withdraw.h>
+
+
+/**
+ * @brief Information needed to withdraw coins (low-level, pre-blinded).
+ */
+struct TALER_EXCHANGE_WithdrawBlindedCoinInput
+{
+ /**
+ * The denomination of the coin.
+ */
+ const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
+
+ /**
+ * Blinded planchet for a single coin.
+ */
+ struct TALER_PlanchetDetail planchet_details;
+};
+
+/**
+ * @brief Information needed to withdraw age-restricted coins (low-level, pre-blinded).
+ */
+struct TALER_EXCHANGE_WithdrawBlindedAgeRestrictedCoinInput
+{
+ /**
+ * The denomination of the coin. MUST support age restriction.
+ */
+ const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
+
+ /**
+ * Tuple of length kappa of planchet candidates for a single coin.
+ */
+ struct TALER_PlanchetDetail planchet_details[TALER_CNC_KAPPA];
+};
+
+
+/**
+ * Handle for an operation to POST /withdraw (low-level, pre-blinded variant).
+ */
+struct TALER_EXCHANGE_PostWithdrawBlindedHandle;
+
+
+/**
+ * Set up POST /withdraw operation (low-level variant with pre-blinded
+ * planchets).
+ * Note that you must explicitly start the operation after setup.
+ *
+ * This variant does not do the blinding/unblinding and only
+ * fetches the blind signatures on the already blinded planchets.
+ *
+ * For age-restricted coins requiring a proof, pass @a blinded_input as NULL
+ * and supply the age-restricted input via the
+ * #TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_WITH_AGE_PROOF option.
+ *
+ * @param curl_ctx The curl context to use
+ * @param keys The /keys material from the exchange
+ * @param exchange_url The base-URL of the exchange
+ * @param reserve_priv private key of the reserve to withdraw from
+ * @param blinding_seed seed used for blinding of CS denominations, might be NULL
+ * @param num_input number of entries in the @a blinded_input array
+ * @param blinded_input array of planchet details to withdraw, or NULL if using WITH_AGE_PROOF option
+ * @return handle to operation, NULL on error
+ */
+struct TALER_EXCHANGE_PostWithdrawBlindedHandle *
+TALER_EXCHANGE_post_withdraw_blinded_create (
+ struct GNUNET_CURL_Context *curl_ctx,
+ struct TALER_EXCHANGE_Keys *keys,
+ const char *exchange_url,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_BlindingMasterSeedP *blinding_seed,
+ size_t num_input,
+ const struct TALER_EXCHANGE_WithdrawBlindedCoinInput *blinded_input);
+
+
+/**
+ * Possible options we can set for the POST /withdraw request
+ * (low-level, pre-blinded variant).
+ */
+enum TALER_EXCHANGE_PostWithdrawBlindedOption
+{
+ /**
+ * End of list of options.
+ */
+ TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_END = 0,
+
+ /**
+ * Upgrade to an age-proof withdrawal for age-restricted coins, requiring
+ * an additional call to POST /reveal-withdraw.
+ * The @e details.with_age_proof.max_age field gives the maximum age to
+ * (provably) commit to.
+ * The @e details.with_age_proof.input field gives the KAPPA planchet
+ * candidates per coin.
+ */
+ TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_WITH_AGE_PROOF
+
+};
+
+
+/**
+ * Value for an option we can set for the POST /withdraw request
+ * (low-level, pre-blinded variant).
+ */
+struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue
+{
+ /**
+ * Type of the option being set.
+ */
+ enum TALER_EXCHANGE_PostWithdrawBlindedOption option;
+
+ /**
+ * Specific option value.
+ */
+ union
+ {
+ /**
+ * Value if @e option is
+ * #TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_WITH_AGE_PROOF.
+ */
+ struct
+ {
+ /**
+ * The maximum age to commit to.
+ */
+ uint8_t max_age;
+
+ /**
+ * Array of KAPPA planchet candidates per coin, length matches
+ * the @e num_input given to _create().
+ */
+ const struct TALER_EXCHANGE_WithdrawBlindedAgeRestrictedCoinInput *input;
+
+ } with_age_proof;
+
+ } details;
+
+};
+
+
+/**
+ * Terminate the list of options.
+ *
+ * @return the terminating object
+ */
+#define TALER_EXCHANGE_post_withdraw_blinded_option_end_() \
+ (const struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue) \
+ { \
+ .option = TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_END \
+ }
+
+/**
+ * Upgrade to an age-proof withdrawal for age-restricted coins.
+ *
+ * @param age the maximum age to commit to
+ * @param inp pointer to array of KAPPA planchet candidates per coin
+ * @return representation of the option
+ */
+#define TALER_EXCHANGE_post_withdraw_blinded_option_with_age_proof(age, inp) \
+ (const struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue) \
+ { \
+ .option = TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_WITH_AGE_PROOF, \
+ .details.with_age_proof.max_age = (age), \
+ .details.with_age_proof.input = (inp) \
+ }
+
+
+/**
+ * Set the requested options for the operation.
+ *
+ * If any option fails, other options may or may not be applied.
+ *
+ * @param pwbh the request to set the options for
+ * @param num_options length of the @a options array
+ * @param options an array of options
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO on failure,
+ * #GNUNET_SYSERR on internal error
+ */
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_post_withdraw_blinded_set_options_ (
+ struct TALER_EXCHANGE_PostWithdrawBlindedHandle *pwbh,
+ unsigned int num_options,
+ const struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue options[]);
+
+
+/**
+ * Set the requested options for the operation.
+ *
+ * If any option fails, other options may or may not be applied.
+ *
+ * @param pwbh the request to set the options for
+ * @param ... the list of the options, each created by a
+ * TALER_EXCHANGE_post_withdraw_blinded_option_NAME(VALUE) macro
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO on failure,
+ * #GNUNET_SYSERR on internal error
+ */
+#define TALER_EXCHANGE_post_withdraw_blinded_set_options(pwbh,...) \
+ TALER_EXCHANGE_post_withdraw_blinded_set_options_ ( \
+ pwbh, \
+ TALER_EXCHANGE_COMMON_OPTIONS_ARRAY_MAX_SIZE, \
+ ((const struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue[]) \
+ {__VA_ARGS__, \
+ TALER_EXCHANGE_post_withdraw_blinded_option_end_ ()} \
+ ))
+
+
+/**
+ * Response from a POST /withdraw request (low-level, pre-blinded variant).
+ */
+struct TALER_EXCHANGE_PostWithdrawBlindedResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details about the response
+ */
+ union
+ {
+ /**
+ * Details if the status is #MHD_HTTP_OK
+ */
+ struct
+ {
+ /**
+ * Number of signatures returned.
+ */
+ unsigned int num_sigs;
+
+ /**
+ * Array of @e num_sigs blinded denomination signatures, giving each
+ * coin its value and validity. The array gives these coins in the same
+ * order (and should have the same length) in which the original
+ * withdraw request specified the respective denomination keys.
+ */
+ const struct TALER_BlindedDenominationSignature *blinded_denom_sigs;
+
+ /**
+ * The commitment of the withdraw request, needed for the later calls to /recoup
+ */
+ struct TALER_HashBlindedPlanchetsP planchets_h;
+
+ } ok;
+
+ /**
+ * Details if the status is MHD_HTTP_CREATED, i.e. in case of
+ * age-restriction. The response is input to prepare the required
+ * follow-up call to /reveal-withdraw.
+ */
+ struct TALER_EXCHANGE_WithdrawCreated created;
+
+ /**
+ * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS.
+ */
+ struct TALER_EXCHANGE_KycNeededRedirect unavailable_for_legal_reasons;
+
+ } details;
+};
+
+
+#ifndef TALER_EXCHANGE_POST_WITHDRAW_BLINDED_RESULT_CLOSURE
+/**
+ * Type of the closure used by
+ * the #TALER_EXCHANGE_PostWithdrawBlindedCallback.
+ */
+#define TALER_EXCHANGE_POST_WITHDRAW_BLINDED_RESULT_CLOSURE void
+#endif /* TALER_EXCHANGE_POST_WITHDRAW_BLINDED_RESULT_CLOSURE */
+
+/**
+ * Type of the function that receives the result of a
+ * POST /withdraw request (low-level, pre-blinded variant).
+ *
+ * @param cls closure
+ * @param result result returned by the HTTP server
+ */
+typedef void
+(*TALER_EXCHANGE_PostWithdrawBlindedCallback)(
+ TALER_EXCHANGE_POST_WITHDRAW_BLINDED_RESULT_CLOSURE *cls,
+ const struct TALER_EXCHANGE_PostWithdrawBlindedResponse *result);
+
+
+/**
+ * Start POST /withdraw operation (low-level, pre-blinded variant).
+ *
+ * @param[in,out] pwbh operation to start
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return status code, #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_EXCHANGE_post_withdraw_blinded_start (
+ struct TALER_EXCHANGE_PostWithdrawBlindedHandle *pwbh,
+ TALER_EXCHANGE_PostWithdrawBlindedCallback cb,
+ TALER_EXCHANGE_POST_WITHDRAW_BLINDED_RESULT_CLOSURE *cb_cls);
+
+
+/**
+ * Cancel POST /withdraw operation (low-level, pre-blinded variant). This
+ * function must not be called by clients after the
+ * TALER_EXCHANGE_PostWithdrawBlindedCallback has been invoked (as in those
+ * cases it'll be called internally by the implementation already).
+ *
+ * @param[in] pwbh operation to cancel
+ */
+void
+TALER_EXCHANGE_post_withdraw_blinded_cancel (
+ struct TALER_EXCHANGE_PostWithdrawBlindedHandle *pwbh);
+
+
+#endif /* _TALER_EXCHANGE__POST_WITHDRAW_H */
diff --git a/src/lib/exchange_api_post-withdraw.c b/src/lib/exchange_api_post-withdraw.c
@@ -429,7 +429,6 @@ copy_results_with_age_proof (
};
wh->withdraw_blinded_handle = NULL;
-
switch (wbr->hr.http_status)
{
case MHD_HTTP_OK:
@@ -565,6 +564,7 @@ call_withdraw_blinded (
wh);
if (TALER_EC_NONE != ec)
{
+ TALER_EXCHANGE_post_withdraw_blinded_cancel (wh->withdraw_blinded_handle);
wh->withdraw_blinded_handle = NULL;
return ec;
}
@@ -941,11 +941,8 @@ ERROR:
if (0 < cs_num)
{
GNUNET_free (wh->bp_nonces);
- wh->bp_nonces = NULL;
GNUNET_free (wh->bp_coins);
- wh->bp_coins = NULL;
GNUNET_free (wh->bp_nonce_keys);
- wh->bp_nonce_keys = NULL;
wh->num_bp_coins = 0;
wh->num_bp_nonces = 0;
wh->num_bp_nonce_keys = 0;
@@ -955,34 +952,6 @@ ERROR:
}
-/**
- * Allocate and set up the common fields of a PostWithdrawHandle.
- *
- * @param curl_ctx The curl context to use
- * @param keys The keys from the exchange
- * @param exchange_url The base url to the exchange
- * @param reserve_priv The private key of the reserve
- * @return the handle
- */
-static struct TALER_EXCHANGE_PostWithdrawHandle *
-setup_withdraw_handle (
- struct GNUNET_CURL_Context *curl_ctx,
- struct TALER_EXCHANGE_Keys *keys,
- const char *exchange_url,
- const struct TALER_ReservePrivateKeyP *reserve_priv)
-{
- struct TALER_EXCHANGE_PostWithdrawHandle *wh;
-
- wh = GNUNET_new (struct TALER_EXCHANGE_PostWithdrawHandle);
- wh->exchange_url = exchange_url;
- wh->keys = TALER_EXCHANGE_keys_incref (keys);
- wh->curl_ctx = curl_ctx;
- wh->reserve_priv = reserve_priv;
-
- return wh;
-}
-
-
struct TALER_EXCHANGE_PostWithdrawHandle *
TALER_EXCHANGE_post_withdraw_create (
struct GNUNET_CURL_Context *curl_ctx,
@@ -996,11 +965,11 @@ TALER_EXCHANGE_post_withdraw_create (
{
struct TALER_EXCHANGE_PostWithdrawHandle *wh;
- wh = setup_withdraw_handle (curl_ctx,
- keys,
- exchange_url,
- reserve_priv);
- GNUNET_assert (NULL != wh);
+ wh = GNUNET_new (struct TALER_EXCHANGE_PostWithdrawHandle);
+ wh->exchange_url = exchange_url;
+ wh->keys = TALER_EXCHANGE_keys_incref (keys);
+ wh->curl_ctx = curl_ctx;
+ wh->reserve_priv = reserve_priv;
wh->seed = *seed;
wh->max_age = opaque_max_age;
wh->init_num_coins = num_coins;
diff --git a/src/lib/exchange_api_post-withdraw_blinded.c b/src/lib/exchange_api_post-withdraw_blinded.c
@@ -456,16 +456,76 @@ handle_withdraw_blinded_finished (
}
-/**
- * Runs the actual withdraw operation with the blinded planchets.
- *
- * @param[in,out] wbh withdraw blinded handle
- * @return #TALER_EC_NONE on success, error code on failure
- */
-static enum TALER_ErrorCode
-perform_withdraw_protocol (
- struct TALER_EXCHANGE_PostWithdrawBlindedHandle *wbh)
+struct TALER_EXCHANGE_PostWithdrawBlindedHandle *
+TALER_EXCHANGE_post_withdraw_blinded_create (
+ struct GNUNET_CURL_Context *curl_ctx,
+ struct TALER_EXCHANGE_Keys *keys,
+ const char *exchange_url,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_BlindingMasterSeedP *blinding_seed,
+ size_t num_input,
+ const struct TALER_EXCHANGE_WithdrawBlindedCoinInput *blinded_input)
+{
+ struct TALER_EXCHANGE_PostWithdrawBlindedHandle *wbh =
+ GNUNET_new (struct TALER_EXCHANGE_PostWithdrawBlindedHandle);
+
+ wbh->keys = TALER_EXCHANGE_keys_incref (keys);
+ wbh->curl_ctx = curl_ctx;
+ wbh->reserve_priv = reserve_priv;
+ wbh->request_url = TALER_url_join (exchange_url,
+ "withdraw",
+ NULL);
+ GNUNET_CRYPTO_eddsa_key_get_public (
+ &wbh->reserve_priv->eddsa_priv,
+ &wbh->reserve_pub.eddsa_pub);
+ wbh->num_input = num_input;
+ wbh->blinded.input = blinded_input;
+ wbh->blinding_seed = blinding_seed;
+
+ return wbh;
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_post_withdraw_blinded_set_options_ (
+ struct TALER_EXCHANGE_PostWithdrawBlindedHandle *pwbh,
+ unsigned int num_options,
+ const struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue options[])
{
+ for (unsigned int i = 0; i < num_options; i++)
+ {
+ const struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue *opt =
+ &options[i];
+ switch (opt->option)
+ {
+ case TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_END:
+ return GNUNET_OK;
+ case TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_WITH_AGE_PROOF:
+ pwbh->with_age_proof = true;
+ pwbh->max_age = opt->details.with_age_proof.max_age;
+ pwbh->blinded.with_age_proof_input = opt->details.with_age_proof.input;
+ break;
+ }
+ }
+ return GNUNET_OK;
+}
+
+
+enum TALER_ErrorCode
+TALER_EXCHANGE_post_withdraw_blinded_start (
+ struct TALER_EXCHANGE_PostWithdrawBlindedHandle *pwbh,
+ TALER_EXCHANGE_PostWithdrawBlindedCallback cb,
+ TALER_EXCHANGE_POST_WITHDRAW_BLINDED_RESULT_CLOSURE *cb_cls)
+{
+ json_t *j_denoms = NULL;
+ json_t *j_planchets = NULL;
+ json_t *j_request_body = NULL;
+ CURL *curlh = NULL;
+ struct GNUNET_HashContext *coins_hctx = NULL;
+ struct TALER_BlindedCoinHashP bch;
+
+ pwbh->callback = cb;
+ pwbh->callback_cls = cb_cls;
#define FAIL_IF(cond) \
do { \
if ((cond)) \
@@ -475,60 +535,53 @@ perform_withdraw_protocol (
} \
} while (0)
- json_t * j_denoms = NULL;
- json_t *j_planchets = NULL;
- json_t *j_request_body = NULL;
- CURL *curlh = NULL;
- struct GNUNET_HashContext *coins_hctx = NULL;
- struct TALER_BlindedCoinHashP bch;
-
- GNUNET_assert (0 < wbh->num_input);
+ GNUNET_assert (0 < pwbh->num_input);
FAIL_IF (GNUNET_OK !=
- TALER_amount_set_zero (wbh->keys->currency,
- &wbh->amount));
+ TALER_amount_set_zero (pwbh->keys->currency,
+ &pwbh->amount));
FAIL_IF (GNUNET_OK !=
- TALER_amount_set_zero (wbh->keys->currency,
- &wbh->fee));
+ TALER_amount_set_zero (pwbh->keys->currency,
+ &pwbh->fee));
/* Accumulate total value with fees */
- for (size_t i = 0; i < wbh->num_input; i++)
+ for (size_t i = 0; i < pwbh->num_input; i++)
{
const struct TALER_EXCHANGE_DenomPublicKey *dpub =
- wbh->with_age_proof ?
- wbh->blinded.with_age_proof_input[i].denom_pub :
- wbh->blinded.input[i].denom_pub;
+ pwbh->with_age_proof ?
+ pwbh->blinded.with_age_proof_input[i].denom_pub :
+ pwbh->blinded.input[i].denom_pub;
FAIL_IF (0 >
- TALER_amount_add (&wbh->amount,
- &wbh->amount,
+ TALER_amount_add (&pwbh->amount,
+ &pwbh->amount,
&dpub->value));
FAIL_IF (0 >
- TALER_amount_add (&wbh->fee,
- &wbh->fee,
+ TALER_amount_add (&pwbh->fee,
+ &pwbh->fee,
&dpub->fees.withdraw));
if (GNUNET_CRYPTO_BSA_CS ==
dpub->key.bsign_pub_key->cipher)
- GNUNET_assert (NULL != wbh->blinding_seed);
+ GNUNET_assert (NULL != pwbh->blinding_seed);
}
- if (wbh->with_age_proof || wbh->max_age > 0)
+ if (pwbh->with_age_proof || pwbh->max_age > 0)
{
- wbh->age_mask =
- wbh->blinded.with_age_proof_input[0].denom_pub->key.age_mask;
+ pwbh->age_mask =
+ pwbh->blinded.with_age_proof_input[0].denom_pub->key.age_mask;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Attempting to withdraw from reserve %s with maximum age %d to proof\n",
- TALER_B2S (&wbh->reserve_pub),
- wbh->max_age);
+ TALER_B2S (&pwbh->reserve_pub),
+ pwbh->max_age);
}
else
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Attempting to withdraw from reserve %s\n",
- TALER_B2S (&wbh->reserve_pub));
+ TALER_B2S (&pwbh->reserve_pub));
}
coins_hctx = GNUNET_CRYPTO_hash_context_start ();
@@ -539,19 +592,19 @@ perform_withdraw_protocol (
FAIL_IF ((NULL == j_denoms) ||
(NULL == j_planchets));
- for (size_t i = 0; i< wbh->num_input; i++)
+ for (size_t i = 0; i< pwbh->num_input; i++)
{
/* Build the denomination array */
const struct TALER_EXCHANGE_DenomPublicKey *denom_pub =
- wbh->with_age_proof ?
- wbh->blinded.with_age_proof_input[i].denom_pub :
- wbh->blinded.input[i].denom_pub;
+ pwbh->with_age_proof ?
+ pwbh->blinded.with_age_proof_input[i].denom_pub :
+ pwbh->blinded.input[i].denom_pub;
const struct TALER_DenominationHashP *denom_h = &denom_pub->h_key;
json_t *jdenom;
/* The mask must be the same for all coins */
- FAIL_IF (wbh->with_age_proof &&
- (wbh->age_mask.bits != denom_pub->key.age_mask.bits));
+ FAIL_IF (pwbh->with_age_proof &&
+ (pwbh->age_mask.bits != denom_pub->key.age_mask.bits));
jdenom = GNUNET_JSON_from_data_auto (denom_h);
FAIL_IF (NULL == jdenom);
@@ -561,12 +614,12 @@ perform_withdraw_protocol (
/* Build the planchet array and calculate the hash over all planchets. */
- if (! wbh->with_age_proof)
+ if (! pwbh->with_age_proof)
{
- for (size_t i = 0; i< wbh->num_input; i++)
+ for (size_t i = 0; i< pwbh->num_input; i++)
{
const struct TALER_PlanchetDetail *planchet =
- &wbh->blinded.input[i].planchet_details;
+ &pwbh->blinded.input[i].planchet_details;
json_t *jc = GNUNET_JSON_PACK (
TALER_JSON_pack_blinded_planchet (
NULL,
@@ -599,10 +652,10 @@ perform_withdraw_protocol (
batch_ctx = GNUNET_CRYPTO_hash_context_start ();
FAIL_IF (NULL == batch_ctx);
- for (size_t i = 0; i< wbh->num_input; i++)
+ for (size_t i = 0; i< pwbh->num_input; i++)
{
const struct TALER_PlanchetDetail *planchet =
- &wbh->blinded.with_age_proof_input[i].planchet_details[k];
+ &pwbh->blinded.with_age_proof_input[i].planchet_details[k];
json_t *jc = GNUNET_JSON_PACK (
TALER_JSON_pack_blinded_planchet (
NULL,
@@ -634,48 +687,46 @@ perform_withdraw_protocol (
}
}
- /* Build the hash of the planchets */
GNUNET_CRYPTO_hash_context_finish (
coins_hctx,
- &wbh->planchets_h.hash);
+ &pwbh->planchets_h.hash);
coins_hctx = NULL;
- /* Sign the request */
TALER_wallet_withdraw_sign (
- &wbh->amount,
- &wbh->fee,
- &wbh->planchets_h,
- wbh->blinding_seed,
- wbh->with_age_proof ? &wbh->age_mask: NULL,
- wbh->with_age_proof ? wbh->max_age : 0,
- wbh->reserve_priv,
- &wbh->reserve_sig);
+ &pwbh->amount,
+ &pwbh->fee,
+ &pwbh->planchets_h,
+ pwbh->blinding_seed,
+ pwbh->with_age_proof ? &pwbh->age_mask: NULL,
+ pwbh->with_age_proof ? pwbh->max_age : 0,
+ pwbh->reserve_priv,
+ &pwbh->reserve_sig);
/* Initiate the POST-request */
j_request_body = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("cipher",
"ED25519"),
GNUNET_JSON_pack_data_auto ("reserve_pub",
- &wbh->reserve_pub),
+ &pwbh->reserve_pub),
GNUNET_JSON_pack_array_steal ("denoms_h",
j_denoms),
GNUNET_JSON_pack_array_steal ("coin_evs",
j_planchets),
GNUNET_JSON_pack_allow_null (
- wbh->with_age_proof
+ pwbh->with_age_proof
? GNUNET_JSON_pack_int64 ("max_age",
- wbh->max_age)
+ pwbh->max_age)
: GNUNET_JSON_pack_string ("max_age",
NULL) ),
GNUNET_JSON_pack_data_auto ("reserve_sig",
- &wbh->reserve_sig));
+ &pwbh->reserve_sig));
FAIL_IF (NULL == j_request_body);
- if (NULL != wbh->blinding_seed)
+ if (NULL != pwbh->blinding_seed)
{
json_t *j_seed = GNUNET_JSON_PACK (
GNUNET_JSON_pack_data_auto ("blinding_seed",
- wbh->blinding_seed));
+ pwbh->blinding_seed));
GNUNET_assert (NULL != j_seed);
GNUNET_assert (0 ==
json_object_update_new (
@@ -683,25 +734,24 @@ perform_withdraw_protocol (
j_seed));
}
- curlh = TALER_EXCHANGE_curl_easy_get_ (wbh->request_url);
+ curlh = TALER_EXCHANGE_curl_easy_get_ (pwbh->request_url);
FAIL_IF (NULL == curlh);
FAIL_IF (GNUNET_OK !=
TALER_curl_easy_post (
- &wbh->post_ctx,
+ &pwbh->post_ctx,
curlh,
j_request_body));
json_decref (j_request_body);
j_request_body = NULL;
- wbh->job = GNUNET_CURL_job_add2 (
- wbh->curl_ctx,
+ pwbh->job = GNUNET_CURL_job_add2 (
+ pwbh->curl_ctx,
curlh,
- wbh->post_ctx.headers,
+ pwbh->post_ctx.headers,
&handle_withdraw_blinded_finished,
- wbh);
- FAIL_IF (NULL == wbh->job);
+ pwbh);
+ FAIL_IF (NULL == pwbh->job);
- /* No errors, return */
return TALER_EC_NONE;
ERROR:
@@ -720,120 +770,21 @@ ERROR:
}
-/**
- * @brief Prepare the handler for blinded withdraw
- *
- * Allocates the handler struct and prepares all fields of the handler
- * except the blinded planchets,
- * which depend on them being age-restricted or not.
- *
- * @param curl_ctx the context for curl
- * @param keys the exchange keys
- * @param exchange_url the url to the exchange
- * @param reserve_priv the reserve's private key
- * @return the handler, NULL on error
- */
-static struct TALER_EXCHANGE_PostWithdrawBlindedHandle *
-setup_handler_common (
- struct GNUNET_CURL_Context *curl_ctx,
- struct TALER_EXCHANGE_Keys *keys,
- const char *exchange_url,
- const struct TALER_ReservePrivateKeyP *reserve_priv)
-{
- struct TALER_EXCHANGE_PostWithdrawBlindedHandle *wbh =
- GNUNET_new (struct TALER_EXCHANGE_PostWithdrawBlindedHandle);
-
- wbh->keys = TALER_EXCHANGE_keys_incref (keys);
- wbh->curl_ctx = curl_ctx;
- wbh->reserve_priv = reserve_priv;
- wbh->request_url = TALER_url_join (exchange_url,
- "withdraw",
- NULL);
- GNUNET_CRYPTO_eddsa_key_get_public (
- &wbh->reserve_priv->eddsa_priv,
- &wbh->reserve_pub.eddsa_pub);
-
- return wbh;
-}
-
-
-struct TALER_EXCHANGE_PostWithdrawBlindedHandle *
-TALER_EXCHANGE_post_withdraw_blinded_create (
- struct GNUNET_CURL_Context *curl_ctx,
- struct TALER_EXCHANGE_Keys *keys,
- const char *exchange_url,
- const struct TALER_ReservePrivateKeyP *reserve_priv,
- const struct TALER_BlindingMasterSeedP *blinding_seed,
- size_t num_input,
- const struct TALER_EXCHANGE_WithdrawBlindedCoinInput *blinded_input)
-{
- struct TALER_EXCHANGE_PostWithdrawBlindedHandle *wbh =
- setup_handler_common (curl_ctx,
- keys,
- exchange_url,
- reserve_priv);
-
- wbh->with_age_proof = false;
- wbh->num_input = num_input;
- wbh->blinded.input = blinded_input;
- wbh->blinding_seed = blinding_seed;
-
- return wbh;
-}
-
-
-enum GNUNET_GenericReturnValue
-TALER_EXCHANGE_post_withdraw_blinded_set_options_ (
- struct TALER_EXCHANGE_PostWithdrawBlindedHandle *pwbh,
- unsigned int num_options,
- const struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue options[])
-{
- for (unsigned int i = 0; i < num_options; i++)
- {
- const struct TALER_EXCHANGE_PostWithdrawBlindedOptionValue *opt =
- &options[i];
- switch (opt->option)
- {
- case TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_END:
- return GNUNET_OK;
- case TALER_EXCHANGE_POST_WITHDRAW_BLINDED_OPTION_WITH_AGE_PROOF:
- pwbh->with_age_proof = true;
- pwbh->max_age = opt->details.with_age_proof.max_age;
- pwbh->blinded.with_age_proof_input = opt->details.with_age_proof.input;
- break;
- }
- }
- return GNUNET_OK;
-}
-
-
-enum TALER_ErrorCode
-TALER_EXCHANGE_post_withdraw_blinded_start (
- struct TALER_EXCHANGE_PostWithdrawBlindedHandle *pwbh,
- TALER_EXCHANGE_PostWithdrawBlindedCallback cb,
- TALER_EXCHANGE_POST_WITHDRAW_BLINDED_RESULT_CLOSURE *cb_cls)
-{
- pwbh->callback = cb;
- pwbh->callback_cls = cb_cls;
- return perform_withdraw_protocol (pwbh);
-}
-
-
void
TALER_EXCHANGE_post_withdraw_blinded_cancel (
- struct TALER_EXCHANGE_PostWithdrawBlindedHandle *wbh)
+ struct TALER_EXCHANGE_PostWithdrawBlindedHandle *pwbh)
{
- if (NULL == wbh)
+ if (NULL == pwbh)
return;
- if (NULL != wbh->job)
+ if (NULL != pwbh->job)
{
- GNUNET_CURL_job_cancel (wbh->job);
- wbh->job = NULL;
+ GNUNET_CURL_job_cancel (pwbh->job);
+ pwbh->job = NULL;
}
- GNUNET_free (wbh->request_url);
- TALER_EXCHANGE_keys_decref (wbh->keys);
- TALER_curl_easy_post_finished (&wbh->post_ctx);
- GNUNET_free (wbh);
+ GNUNET_free (pwbh->request_url);
+ TALER_EXCHANGE_keys_decref (pwbh->keys);
+ TALER_curl_easy_post_finished (&pwbh->post_ctx);
+ GNUNET_free (pwbh);
}
diff --git a/src/testing/test-taler-exchange-aggregator-postgres.conf b/src/testing/test-taler-exchange-aggregator-postgres.conf
@@ -15,6 +15,7 @@ DURATION = 14 days
[exchange]
CURRENCY = EUR
CURRENCY_ROUND_UNIT = EUR:0.01
+TINY_AMOUNT = EUR:0.01
AML_THRESHOLD = EUR:1000000
DB = postgres
PORT = 8081
@@ -24,6 +25,7 @@ BASE_URL = "http://localhost:8081/"
[auditor]
BASE_URL = "http://auditor.example.com/"
PORT = 8083
+TINY_AMOUNT = EUR:0.01
[auditordb-postgres]
CONFIG = "postgres:///talercheck"
diff --git a/src/testing/test-taler-exchange-wirewatch-postgres.conf b/src/testing/test-taler-exchange-wirewatch-postgres.conf
@@ -14,6 +14,7 @@ DURATION = 14 days
[exchange]
CURRENCY = EUR
CURRENCY_ROUND_UNIT = EUR:0.01
+TINY_AMOUNT = EUR:0.01
AML_THRESHOLD = EUR:1000000
DB = postgres
PORT = 8081
@@ -30,6 +31,7 @@ CONFIG = "postgres:///talercheck"
[auditor]
BASE_URL = "http://localhost:8083/"
PORT = 8083
+TINY_AMOUNT = EUR:0.01
[auditordb-postgres]
CONFIG = "postgres:///talercheck"
diff --git a/src/testing/test_exchange_api_keys_cherry_picking.conf b/src/testing/test_exchange_api_keys_cherry_picking.conf
@@ -7,7 +7,7 @@ TALER_TEST_HOME = test_exchange_api_keys_cherry_picking_home/
[auditor]
BASE_URL = "http://localhost:8083/"
PORT = 8083
-
+TINY_AMOUNT = EUR:0.01
[taler-exchange-secmod-eddsa]
OVERLAP_DURATION = 1 s
@@ -17,6 +17,7 @@ LOOKAHEAD_SIGN = 20 s
[exchange]
CURRENCY = EUR
CURRENCY_ROUND_UNIT = EUR:0.01
+TINY_AMOUNT = EUR:0.01
AML_THRESHOLD = EUR:1000000
PORT = 8081
MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG