more exchange API refactoring

This commit is contained in:
Christian Grothoff 2023-07-04 15:37:34 +02:00
parent 47620fa81b
commit ff8349e6e7
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
29 changed files with 750 additions and 1635 deletions

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2020-2021 Taler Systems SA
Copyright (C) 2020-2023 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
@ -174,7 +174,7 @@ static struct DenominationAddRequest *dar_tail;
/**
* Handle to the exchange, used to request /keys.
*/
static struct TALER_EXCHANGE_Handle *exchange;
static struct TALER_EXCHANGE_GetKeysHandle *exchange;
/**
@ -219,7 +219,7 @@ do_shutdown (void *cls)
}
if (NULL != exchange)
{
TALER_EXCHANGE_disconnect (exchange);
TALER_EXCHANGE_get_keys_cancel (exchange);
exchange = NULL;
}
if (NULL != nxt)
@ -646,22 +646,23 @@ do_upload (char *const *args)
*
* @param cls closure with the `char **` remaining args
* @param kr response data
* @param keys key data from the exchange
*/
static void
keys_cb (
void *cls,
const struct TALER_EXCHANGE_KeysResponse *kr)
const struct TALER_EXCHANGE_KeysResponse *kr,
struct TALER_EXCHANGE_Keys *keys)
{
char *const *args = cls;
exchange = NULL;
switch (kr->hr.http_status)
{
case MHD_HTTP_OK:
if (! json_is_object (kr->hr.reply))
if (NULL == kr->hr.reply)
{
GNUNET_break (0);
TALER_EXCHANGE_disconnect (exchange);
exchange = NULL;
test_shutdown ();
global_ret = EXIT_FAILURE;
return;
@ -673,8 +674,6 @@ keys_cb (
kr->hr.hint,
kr->hr.http_status,
(unsigned int) kr->hr.ec);
TALER_EXCHANGE_disconnect (exchange);
exchange = NULL;
test_shutdown ();
global_ret = EXIT_FAILURE;
return;
@ -692,9 +691,8 @@ keys_cb (
json_decref (in);
in = NULL;
}
TALER_EXCHANGE_disconnect (exchange);
exchange = NULL;
next (args);
TALER_EXCHANGE_keys_decref (keys);
}
@ -721,11 +719,11 @@ do_download (char *const *args)
global_ret = EXIT_NOTCONFIGURED;
return;
}
exchange = TALER_EXCHANGE_connect (ctx,
exchange_url,
&keys_cb,
(void *) args,
TALER_EXCHANGE_OPTION_END);
exchange = TALER_EXCHANGE_get_keys (ctx,
exchange_url,
NULL,
&keys_cb,
(void *) args);
GNUNET_free (exchange_url);
}

View File

@ -32,27 +32,6 @@
/* ********************* /keys *********************** */
/**
* List of possible options to be passed to
* #TALER_EXCHANGE_connect().
*/
enum TALER_EXCHANGE_Option
{
/**
* Terminator (end of option list).
*/
TALER_EXCHANGE_OPTION_END = 0,
/**
* Followed by a "const json_t *" that was previously returned for
* this exchange URL by #TALER_EXCHANGE_serialize_data(). Used to
* resume a connection to an exchange without having to re-download
* /keys data (or at least only download the deltas).
*/
TALER_EXCHANGE_OPTION_DATA
};
/**
* @brief Exchange's signature key
@ -294,11 +273,18 @@ struct TALER_EXCHANGE_Keys
char *currency;
/**
* How long after a reserve went idle will the exchange close it?
* This is an approximate number, not cryptographically signed by
* the exchange (advisory-only, may change anytime).
* What is the base URL of the exchange that returned
* these keys?
*/
struct GNUNET_TIME_Relative reserve_closing_delay;
char *exchange_url;
/**
* Asset type used by the exchange. Typical values
* are "fiat" or "crypto" or "regional" or "stock".
* Wallets should adjust their UI/UX based on this
* value.
*/
char *asset_type;
/**
* Array of amounts a wallet is allowed to hold from
@ -307,16 +293,22 @@ struct TALER_EXCHANGE_Keys
struct TALER_Amount *wallet_balance_limit_without_kyc;
/**
* Length of the @e wallet_balance_limit_without_kyc
* array.
* How long after a reserve went idle will the exchange close it?
* This is an approximate number, not cryptographically signed by
* the exchange (advisory-only, may change anytime).
*/
unsigned int wblwk_length;
struct GNUNET_TIME_Relative reserve_closing_delay;
/**
* Timestamp indicating the /keys generation.
*/
struct GNUNET_TIME_Timestamp list_issue_date;
/**
* When does this keys data expire?
*/
struct GNUNET_TIME_Timestamp key_data_expiration;
/**
* Timestamp indicating the creation time of the last
* denomination key in /keys.
@ -329,6 +321,12 @@ struct TALER_EXCHANGE_Keys
*/
struct TALER_AgeMask age_mask;
/**
* Length of the @e wallet_balance_limit_without_kyc
* array.
*/
unsigned int wblwk_length;
/**
* Length of the @e global_fees array.
*/
@ -360,12 +358,10 @@ struct TALER_EXCHANGE_Keys
unsigned int denom_keys_size;
/**
* Asset type used by the exchange. Typical values
* are "fiat" or "crypto" or "regional" or "stock".
* Wallets should adjust their UI/UX based on this
* value.
* Reference counter for this structure.
* Freed when it reaches 0.
*/
char *asset_type;
unsigned int rc;
/**
* Set to true if tipping is allowed at this exchange.
@ -505,77 +501,82 @@ struct TALER_EXCHANGE_KeysResponse
/**
* Function called with information about who is auditing
* a particular exchange and what keys the exchange is using.
* The ownership over the @a keys object is passed to
* the callee, thus it is given explicitly and not
* (only) via @a kr.
*
* @param cls closure
* @param kr response from /keys
* @param[in] keys keys object passed to callback with
* reference counter of 1. Must be freed by callee
* using #TALER_EXCHANGE_keys_decref(). NULL on failure.
*/
typedef void
(*TALER_EXCHANGE_CertificationCallback) (
(*TALER_EXCHANGE_GetKeysCallback) (
void *cls,
const struct TALER_EXCHANGE_KeysResponse *kr);
const struct TALER_EXCHANGE_KeysResponse *kr,
struct TALER_EXCHANGE_Keys *keys);
/**
* @brief Handle to the exchange. This is where we interact with
* a particular exchange and keep the per-exchange information.
* @brief Handle for a GET /keys request.
*/
struct TALER_EXCHANGE_Handle;
struct TALER_EXCHANGE_GetKeysHandle;
/**
* Initialise a connection to the exchange. Will connect to the
* exchange and obtain information about the exchange's master public
* key and the exchange's auditor. The respective information will
* be passed to the @a cert_cb once available, and all future
* interactions with the exchange will be checked to be signed
* (where appropriate) by the respective master key.
* Fetch the main /keys resources from ane exchange. Does an incremental
* fetch if @a last_keys is given. The obtained information will be passed to
* the @a cert_cb (possibly after first merging it with @a last_keys to
* produce a full picture; expired keys (for deposit) will be removed from @a
* last_keys if there are any).
*
* @param ctx the context
* @param url HTTP base URL for the exchange
* @param[in,out] last_keys previous keys object, NULL for none
* @param cert_cb function to call with the exchange's certification information,
* possibly called repeatedly if the information changes
* @param cert_cb_cls closure for @a cert_cb
* @param ... list of additional arguments, terminated by #TALER_EXCHANGE_OPTION_END.
* @return the exchange handle; NULL upon error
*/
struct TALER_EXCHANGE_Handle *
TALER_EXCHANGE_connect (struct GNUNET_CURL_Context *ctx,
const char *url,
TALER_EXCHANGE_CertificationCallback cert_cb,
void *cert_cb_cls,
...);
struct TALER_EXCHANGE_GetKeysHandle *
TALER_EXCHANGE_get_keys (
struct GNUNET_CURL_Context *ctx,
const char *url,
struct TALER_EXCHANGE_Keys *last_keys,
TALER_EXCHANGE_GetKeysCallback cert_cb,
void *cert_cb_cls);
/**
* Serialize the latest key data from @a exchange to be persisted
* on disk (to be used with #TALER_EXCHANGE_OPTION_DATA to more
* efficiently recover the state).
* Serialize the latest data from @a keys to be persisted
* (for example, to be used as @a last_keys later).
*
* @param exchange which exchange's key and wire data should be serialized
* @return NULL on error (i.e. no current data available); otherwise
* json object owned by the caller
* @param kd the key data to serialize
* @return NULL on error; otherwise JSON object owned by the caller
*/
json_t *
TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange);
TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd);
/**
* Disconnect from the exchange.
* Deserialize keys data stored in @a j.
*
* @param exchange the exchange handle
*/
void
TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange);
/**
* Obtain the keys from the exchange.
*
* @param exchange the exchange handle
* @return the exchange's key set
* @param j JSON keys data previously returned from #TALER_EXCHANGE_keys_to_json()
* @return NULL on error (i.e. invalid JSON); otherwise
* keys object with reference counter 1 owned by the caller
*/
struct TALER_EXCHANGE_Keys *
TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle *exchange);
TALER_EXCHANGE_keys_from_json (const json_t *j);
/**
* Cancel GET /keys operation.
*
* @param[in] gkh the GET /keys handle
*/
void
TALER_EXCHANGE_get_keys_cancel (struct TALER_EXCHANGE_GetKeysHandle *gkh);
/**
@ -598,90 +599,6 @@ void
TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys);
/**
* Let the user set the last valid denomination time manually.
*
* @param exchange the exchange handle.
* @param last_denom_new new last denomination time.
*/
void
TALER_EXCHANGE_set_last_denom (
struct TALER_EXCHANGE_Handle *exchange,
struct GNUNET_TIME_Timestamp last_denom_new);
/**
* Flags for #TALER_EXCHANGE_check_keys_current().
*/
enum TALER_EXCHANGE_CheckKeysFlags
{
/**
* No special options.
*/
TALER_EXCHANGE_CKF_NONE,
/**
* Force downloading /keys now, even if /keys is still valid
* (that is, the period advertised by the exchange for re-downloads
* has not yet expired).
*/
TALER_EXCHANGE_CKF_FORCE_DOWNLOAD = 1,
/**
* Pull all keys again, resetting the client state to the original state.
* Using this flag disables the incremental download, and also prevents using
* the context until the re-download has completed.
*/
TALER_EXCHANGE_CKF_PULL_ALL_KEYS = 2,
/**
* Force downloading all keys now.
*/
TALER_EXCHANGE_CKF_FORCE_ALL_NOW = TALER_EXCHANGE_CKF_FORCE_DOWNLOAD
| TALER_EXCHANGE_CKF_PULL_ALL_KEYS
};
/**
* Check if our current response for /keys is valid, and if
* not, trigger /keys download. If @a cb is given, changes
* the @a exchange callback for the /keys response.
*
* @param exchange exchange to check keys for
* @param flags options controlling when to download what
* @param cb function to call with the /keys response, can be NULL
* @param cb_cls closure for @a cb
* @return until when the existing response is current, 0 if we are re-downloading now
*/
struct GNUNET_TIME_Timestamp
TALER_EXCHANGE_check_keys_current (
struct TALER_EXCHANGE_Handle *exchange,
enum TALER_EXCHANGE_CheckKeysFlags flags,
TALER_EXCHANGE_CertificationCallback cb,
void *cb_cls);
/**
* Obtain the keys from the exchange in the raw JSON format.
*
* @param exchange the exchange handle
* @return the exchange's keys in raw JSON
*/
json_t *
TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange);
/**
* Obtain the keys from the exchange in the raw JSON format.
*
* @param keys the keys structure
* @return the keys in raw JSON
*/
json_t *
TALER_EXCHANGE_keys_to_json (struct TALER_EXCHANGE_Keys *keys);
/**
* Test if the given @a pub is a the current signing key from the exchange
* according to @a keys.
@ -691,18 +608,9 @@ TALER_EXCHANGE_keys_to_json (struct TALER_EXCHANGE_Keys *keys);
* @return #GNUNET_OK if @a pub is (according to /keys) a current signing key
*/
enum GNUNET_GenericReturnValue
TALER_EXCHANGE_test_signing_key (const struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ExchangePublicKeyP *pub);
/**
* Get exchange's base URL.
*
* @param exchange exchange handle.
* @return the base URL from the handle.
*/
const char *
TALER_EXCHANGE_get_base_url (const struct TALER_EXCHANGE_Handle *exchange);
TALER_EXCHANGE_test_signing_key (
const struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ExchangePublicKeyP *pub);
/**
@ -736,7 +644,8 @@ TALER_EXCHANGE_get_global_fee (
* Create a copy of a denomination public key.
*
* @param key key to copy
* @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key
* @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key()
* @deprecated
*/
struct TALER_EXCHANGE_DenomPublicKey *
TALER_EXCHANGE_copy_denomination_key (
@ -745,9 +654,10 @@ TALER_EXCHANGE_copy_denomination_key (
/**
* Destroy a denomination public key.
* Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key.
* Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key().
*
* @param key key to destroy.
* @deprecated
*/
void
TALER_EXCHANGE_destroy_denomination_key (

View File

@ -1797,17 +1797,6 @@ struct TALER_TESTING_Command
TALER_TESTING_cmd_check_keys (const char *label);
/**
* Make a "check keys" command that forcedly does NOT cherry pick;
* just redownload the whole /keys.
*
* @param label command label
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label);
/**
* Make a "check keys" command. It lets the user set a last denom issue date to be
* used in the request for /keys.
@ -2703,7 +2692,6 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \
op (claim_token, const struct TALER_ClaimTokenP) \
op (relative_time, const struct GNUNET_TIME_Relative) \
op (exchange, struct TALER_EXCHANGE_Handle) \
op (fakebank, struct TALER_FAKEBANK_Handle) \
op (keys, struct TALER_EXCHANGE_Keys) \
op (process, struct GNUNET_OS_Process *)
@ -2742,16 +2730,6 @@ TALER_TESTING_INDEXED_TRAITS (TALER_TESTING_MAKE_DECL_INDEXED_TRAIT)
/* ****************** convenience functions ************** */
/**
* Get exchange handle from interpreter. Convenience function.
*
* @param is interpreter state.
* @return the exchange handle, or NULL on error
*/
struct TALER_EXCHANGE_Handle *
TALER_TESTING_get_exchange (struct TALER_TESTING_Interpreter *is);
/**
* Get exchange URL from interpreter. Convenience function.
*

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015 Taler Systems SA
Copyright (C) 2014, 2015, 2023 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
@ -28,124 +28,6 @@
#include "taler_util.h"
#include "taler_curl_lib.h"
/**
* Entry in DLL of auditors used by an exchange.
*/
struct TEAH_AuditorListEntry;
/**
* Stages of initialization for the `struct TALER_EXCHANGE_Handle`
*/
enum ExchangeHandleState
{
/**
* Just allocated.
*/
MHS_INIT = 0,
/**
* Obtained the exchange's certification data and keys.
*/
MHS_CERT = 1,
/**
* Failed to initialize (fatal).
*/
MHS_FAILED = 2
};
/**
* Handle to the exchange
*/
struct TALER_EXCHANGE_Handle
{
/**
* The context of this handle
*/
struct GNUNET_CURL_Context *ctx;
/**
* The URL of the exchange (i.e. "http://exchange.taler.net/")
*/
char *url;
/**
* Function to call with the exchange's certification data,
* NULL if this has already been done.
*/
TALER_EXCHANGE_CertificationCallback cert_cb;
/**
* Closure to pass to @e cert_cb.
*/
void *cert_cb_cls;
/**
* Data for the request to get the /keys of a exchange,
* NULL once we are past stage #MHS_INIT.
*/
struct KeysRequest *kr;
/**
* Task for retrying /keys request.
*/
struct GNUNET_SCHEDULER_Task *retry_task;
/**
* Raw key data of the exchange, only valid if
* @e handshake_complete is past stage #MHS_CERT.
*/
json_t *key_data_raw;
/**
* Head of DLL of auditors of this exchange.
*/
struct TEAH_AuditorListEntry *auditors_head;
/**
* Tail of DLL of auditors of this exchange.
*/
struct TEAH_AuditorListEntry *auditors_tail;
/**
* Key data of the exchange, only valid if
* @e handshake_complete is past stage #MHS_CERT.
*/
struct TALER_EXCHANGE_Keys key_data;
/**
* Retry /keys frequency.
*/
struct GNUNET_TIME_Relative retry_delay;
/**
* When does @e key_data expire?
*/
struct GNUNET_TIME_Timestamp key_data_expiration;
/**
* Number of subsequent failed requests to /keys.
*
* Used to compute the CURL timeout for the request.
*/
unsigned int keys_error_count;
/**
* Number of subsequent failed requests to /wire.
*
* Used to compute the CURL timeout for the request.
*/
unsigned int wire_error_count;
/**
* Stage of the exchange's initialization routines.
*/
enum ExchangeHandleState state;
};
/**
* Function called for each auditor to give us a chance to possibly
@ -156,9 +38,10 @@ struct TALER_EXCHANGE_Handle
* @param auditor_pub public key of the auditor
*/
typedef void
(*TEAH_AuditorCallback)(void *cls,
const char *auditor_url,
const struct TALER_AuditorPublicKeyP *auditor_pub);
(*TEAH_AuditorCallback)(
void *cls,
const char *auditor_url,
const struct TALER_AuditorPublicKeyP *auditor_pub);
/**
@ -171,50 +54,11 @@ typedef void
* @param ac_cls closure for @a ac
*/
void
TEAH_get_auditors_for_dc (struct TALER_EXCHANGE_Keys *keys,
TEAH_AuditorCallback ac,
void *ac_cls);
TEAH_get_auditors_for_dc (
struct TALER_EXCHANGE_Keys *keys,
TEAH_AuditorCallback ac,
void *ac_cls);
/**
* Get the context of a exchange.
*
* @param h the exchange handle to query
* @return ctx context to execute jobs in
*/
struct GNUNET_CURL_Context *
TEAH_handle_to_context (struct TALER_EXCHANGE_Handle *h);
/**
* Check if the handle is ready to process requests.
*
* @param h the exchange handle to query
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
*/
enum GNUNET_GenericReturnValue
TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h);
/**
* Check if the handle is ready to process requests.
*
* @param h the exchange handle to query
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
*/
enum GNUNET_GenericReturnValue
TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h);
/**
* Obtain the URL to use for an API request.
*
* @param h the exchange handle to query
* @param path Taler API path (i.e. "/reserve/withdraw")
* @return the full URL to use with cURL
*/
char *
TEAH_path_to_url (struct TALER_EXCHANGE_Handle *h,
const char *path);
/* end of exchange_api_handle.h */
#endif

View File

@ -658,7 +658,7 @@ run (void *cls,
TALER_TESTING_cmd_get_auditor ("get-auditor",
cred.cfg,
true),
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
TALER_TESTING_cmd_exec_auditor_offline ("auditor-offline",
config_file),
CMD_RUN_AUDITOR ("virgin-auditor"),

View File

@ -1238,7 +1238,7 @@ run (void *cls,
cred.cfg,
true,
true),
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
TALER_TESTING_cmd_batch ("wire",
wire),
TALER_TESTING_cmd_batch ("withdraw",

View File

@ -67,7 +67,7 @@ run (void *cls,
cred.cfg,
true,
true),
TALER_TESTING_cmd_check_keys_pull_all_keys ("initial-/keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("initial-/keys"),
TALER_TESTING_cmd_sleep ("sleep",
6 /* seconds */),
TALER_TESTING_cmd_check_keys ("check-keys-1"),

View File

@ -71,7 +71,7 @@ run (void *cls,
cred.cfg,
true,
true),
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
TALER_TESTING_cmd_check_keys ("first-download"),
/* Causes GET /keys?last_denom_issue=0 */
TALER_TESTING_cmd_check_keys_with_last_denom ("second-download",

View File

@ -80,7 +80,7 @@ run (void *cls,
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
config_file),
#endif
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
/**
* Fill reserve with EUR:10.02, as withdraw fee is 1 ct per
* config.

View File

@ -145,7 +145,7 @@ run (void *cls,
false),
TALER_TESTING_cmd_exec_offline_sign_keys ("download-future-keys",
config_file),
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
TALER_TESTING_cmd_end ()
};

View File

@ -506,7 +506,7 @@ run (void *cls,
cred.cfg,
true,
true),
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
TALER_TESTING_cmd_batch ("withdraw",
withdraw),
TALER_TESTING_cmd_batch ("push",

View File

@ -525,7 +525,7 @@ run (void *cls,
cred.cfg,
true,
true),
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
TALER_TESTING_cmd_batch ("withdraw",
withdraw),
TALER_TESTING_cmd_batch ("spend",

View File

@ -89,7 +89,7 @@ run (void *cls,
cred.cfg,
true,
true),
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
// FIXME: TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
TALER_TESTING_cmd_check_bank_empty ("expect-empty-transactions-on-start"),
CMD_EXEC_AGGREGATOR ("run-aggregator-on-empty"),
TALER_TESTING_cmd_exec_wirewatch ("run-wirewatch-on-empty",

View File

@ -211,12 +211,8 @@ deposit_confirmation_run (void *cls,
const struct TALER_EXCHANGE_Keys *keys;
const struct TALER_EXCHANGE_SigningPublicKey *spk;
const char *auditor_url;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
(void) cmd;
if (NULL == exchange)
return;
dcs->is = is;
GNUNET_assert (NULL != dcs->deposit_reference);
{
@ -267,7 +263,7 @@ deposit_confirmation_run (void *cls,
dcs->coin_index,
&wire_deadline));
GNUNET_assert (NULL != exchange_timestamp);
keys = TALER_EXCHANGE_get_keys (exchange);
keys = TALER_TESTING_get_keys (is);
GNUNET_assert (NULL != keys);
spk = TALER_EXCHANGE_get_signing_key_info (keys,
exchange_pub);

View File

@ -253,12 +253,8 @@ batch_withdraw_run (void *cls,
const struct TALER_TESTING_Command *create_reserve;
const struct TALER_EXCHANGE_DenomPublicKey *dpk;
struct TALER_EXCHANGE_WithdrawCoinInput wcis[ws->num_coins];
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
(void) cmd;
if (NULL == exchange)
return;
ws->is = is;
create_reserve
= TALER_TESTING_interpreter_lookup_command (
@ -281,7 +277,7 @@ batch_withdraw_run (void *cls,
}
if (NULL == ws->exchange_url)
ws->exchange_url
= GNUNET_strdup (TALER_EXCHANGE_get_base_url (exchange));
= GNUNET_strdup (TALER_TESTING_get_exchange_url (is));
ws->reserve_priv = *rp;
GNUNET_CRYPTO_eddsa_key_get_public (&ws->reserve_priv.eddsa_priv,
&ws->reserve_pub.eddsa_pub);
@ -295,7 +291,7 @@ batch_withdraw_run (void *cls,
struct TALER_EXCHANGE_WithdrawCoinInput *wci = &wcis[i];
TALER_planchet_master_setup_random (&cs->ps);
dpk = TALER_TESTING_find_pk (TALER_EXCHANGE_get_keys (exchange),
dpk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (is),
&cs->amount,
ws->age > 0);
if (NULL == dpk)

View File

@ -27,6 +27,8 @@
#include <gnunet/gnunet_curl_lib.h>
#include "taler_testing_lib.h"
// FIXME: duplicated with testing_api_cmd_connect_with_state
// FIXME: this is now duplicated with testing_api_cmd_get_exchange!
/**
* State for a "check keys" CMD.
@ -34,14 +36,9 @@
struct CheckKeysState
{
/**
* If this value is true, then the "cherry picking" facility is turned off;
* whole /keys is downloaded.
*/
bool pull_all_keys;
/**
* Label of a command to use to derive the "last_denom_issue" date to use.
* FIXME: actually use this!
*/
const char *last_denom_date_ref;
@ -50,6 +47,11 @@ struct CheckKeysState
*/
struct TALER_TESTING_Interpreter *is;
/**
* Our get keys operation.
*/
struct TALER_EXCHANGE_GetKeysHandle *gkh;
/**
* Last denomination date we received when doing this request.
*/
@ -66,7 +68,8 @@ struct CheckKeysState
*/
static void
keys_cb (void *cls,
const struct TALER_EXCHANGE_KeysResponse *kr)
const struct TALER_EXCHANGE_KeysResponse *kr,
struct TALER_EXCHANGE_Keys *keys)
{
struct CheckKeysState *cks = cls;
@ -77,6 +80,8 @@ keys_cb (void *cls,
return;
}
cks->my_denom_date = kr->details.ok.keys->last_denom_issue_date;
/* FIXME: expose keys (and exchange_url) via trait! */
TALER_EXCHANGE_keys_decref (keys);
TALER_TESTING_interpreter_next (cks->is);
}
@ -94,64 +99,19 @@ check_keys_run (void *cls,
struct TALER_TESTING_Interpreter *is)
{
struct CheckKeysState *cks = cls;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
struct GNUNET_TIME_Timestamp rdate;
const char *exchange_url
= TALER_TESTING_get_exchange_url (is);
(void) cmd;
cks->is = is;
if (NULL == exchange)
return;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Triggering GET /keys, cmd `%s'\n",
cmd->label);
if (NULL != cks->last_denom_date_ref)
{
if (0 == strcmp ("zero",
cks->last_denom_date_ref))
{
TALER_LOG_DEBUG ("Forcing last_denom_date URL argument set to zero\n");
TALER_EXCHANGE_set_last_denom (exchange,
GNUNET_TIME_UNIT_ZERO_TS);
}
else
{
const struct GNUNET_TIME_Timestamp *last_denom_date;
const struct TALER_TESTING_Command *ref;
ref = TALER_TESTING_interpreter_lookup_command (is,
cks->last_denom_date_ref);
if (NULL == ref)
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
if (GNUNET_OK !=
TALER_TESTING_get_trait_timestamp (ref,
0,
&last_denom_date))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
TALER_LOG_DEBUG ("Forcing last_denom_date URL argument\n");
TALER_EXCHANGE_set_last_denom (exchange,
*last_denom_date);
}
}
rdate = TALER_EXCHANGE_check_keys_current (
exchange,
cks->pull_all_keys
? TALER_EXCHANGE_CKF_FORCE_ALL_NOW
: TALER_EXCHANGE_CKF_FORCE_DOWNLOAD,
cks->gkh = TALER_EXCHANGE_get_keys (
TALER_TESTING_interpreter_get_context (is),
exchange_url,
NULL, /* FIXME: get form last_denom_date_ref! */
&keys_cb,
cks);
/* Redownload /keys. */
GNUNET_break (GNUNET_TIME_absolute_is_zero (rdate.abs_time));
}
@ -168,6 +128,11 @@ check_keys_cleanup (void *cls,
struct CheckKeysState *cks = cls;
(void) cmd;
if (NULL != cks->gkh)
{
TALER_EXCHANGE_get_keys_cancel (cks->gkh);
cks->gkh = NULL;
}
GNUNET_free (cks);
}
@ -204,10 +169,21 @@ check_keys_traits (void *cls,
struct TALER_TESTING_Command
TALER_TESTING_cmd_check_keys (const char *label)
{
return TALER_TESTING_cmd_check_keys_with_last_denom (label,
NULL);
}
struct TALER_TESTING_Command
TALER_TESTING_cmd_check_keys_with_last_denom (
const char *label,
const char *last_denom_date_ref)
{
struct CheckKeysState *cks;
cks = GNUNET_new (struct CheckKeysState);
cks->last_denom_date_ref = last_denom_date_ref;
{
struct TALER_TESTING_Command cmd = {
.cls = cks,
@ -222,30 +198,4 @@ TALER_TESTING_cmd_check_keys (const char *label)
}
struct TALER_TESTING_Command
TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label)
{
struct TALER_TESTING_Command cmd
= TALER_TESTING_cmd_check_keys (label);
struct CheckKeysState *cks = cmd.cls;
cks->pull_all_keys = true;
return cmd;
}
struct TALER_TESTING_Command
TALER_TESTING_cmd_check_keys_with_last_denom (
const char *label,
const char *last_denom_date_ref)
{
struct TALER_TESTING_Command cmd
= TALER_TESTING_cmd_check_keys (label);
struct CheckKeysState *cks = cmd.cls;
cks->last_denom_date_ref = last_denom_date_ref;
return cmd;
}
/* end of testing_api_cmd_check_keys.c */

View File

@ -26,6 +26,9 @@
#include "taler_testing_lib.h"
// FIXME: this is now duplicated with testing_api_cmd_check_keys!
// FIXME: this is now duplicated with testing_api_cmd_get_exchange!
/**
* Internal state for a connect-with-state CMD.
*/
@ -46,13 +49,19 @@ struct ConnectWithStateState
/**
* New exchange handle.
*/
struct TALER_EXCHANGE_Handle *exchange;
struct TALER_EXCHANGE_GetKeysHandle *exchange;
/**
* Keys handle.
*/
struct TALER_EXCHANGE_Keys *keys;
};
static void
cert_cb (void *cls,
const struct TALER_EXCHANGE_KeysResponse *kr)
const struct TALER_EXCHANGE_KeysResponse *kr,
struct TALER_EXCHANGE_Keys *keys)
{
struct ConnectWithStateState *cwss = cls;
struct TALER_TESTING_Interpreter *is = cwss->is;
@ -72,6 +81,7 @@ cert_cb (void *cls,
TALER_TESTING_interpreter_fail (is);
return;
}
cwss->keys = keys;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Got %d DK from /keys\n",
kr->details.ok.keys->num_denom_keys);
@ -113,14 +123,12 @@ connect_with_state_run (void *cls,
TALER_TESTING_get_trait_exchange_url (state_cmd,
&exchange_url));
cwss->exchange
= TALER_EXCHANGE_connect (
= TALER_EXCHANGE_get_keys (
TALER_TESTING_interpreter_get_context (is),
exchange_url,
TALER_EXCHANGE_keys_from_json (serialized_keys),
&cert_cb,
cwss,
TALER_EXCHANGE_OPTION_DATA,
serialized_keys,
TALER_EXCHANGE_OPTION_END);
cwss);
}
@ -141,7 +149,8 @@ connect_with_state_traits (void *cls,
{
struct ConnectWithStateState *cwss = cls;
struct TALER_TESTING_Trait traits[] = {
TALER_TESTING_make_trait_exchange (cwss->exchange),
TALER_TESTING_make_trait_keys (cwss->keys),
// FIXME: also expose exchange_url as trait
TALER_TESTING_trait_end ()
};
@ -165,6 +174,13 @@ connect_with_state_cleanup (void *cls,
{
struct ConnectWithStateState *cwss = cls;
TALER_EXCHANGE_keys_decref (cwss->keys);
cwss->keys = NULL;
if (NULL != cwss->exchange)
{
TALER_EXCHANGE_get_keys_cancel (cwss->exchange);
cwss->exchange = NULL;
}
GNUNET_free (cwss);
}

View File

@ -46,7 +46,12 @@ struct GetExchangeState
/**
* Exchange handle we produced.
*/
struct TALER_EXCHANGE_Handle *exchange;
struct TALER_EXCHANGE_GetKeysHandle *exchange;
/**
* Keys of the exchange.
*/
struct TALER_EXCHANGE_Keys *keys;
/**
* URL of the exchange.
@ -67,12 +72,15 @@ struct GetExchangeState
static void
cert_cb (void *cls,
const struct TALER_EXCHANGE_KeysResponse *kr)
const struct TALER_EXCHANGE_KeysResponse *kr,
struct TALER_EXCHANGE_Keys *keys)
{
struct GetExchangeState *ges = cls;
const struct TALER_EXCHANGE_HttpResponse *hr = &kr->hr;
struct TALER_TESTING_Interpreter *is = ges->is;
ges->exchange = NULL;
ges->keys = keys;
switch (hr->http_status)
{
case MHD_HTTP_OK:
@ -85,8 +93,9 @@ cert_cb (void *cls,
return;
default:
GNUNET_break (0);
TALER_EXCHANGE_disconnect (ges->exchange);
ges->exchange = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"/keys responded with HTTP status %u\n",
hr->http_status);
if (ges->wait_for_keys)
{
ges->wait_for_keys = false;
@ -133,11 +142,11 @@ get_exchange_run (void *cls,
}
ges->is = is;
ges->exchange
= TALER_EXCHANGE_connect (TALER_TESTING_interpreter_get_context (is),
ges->exchange_url,
&cert_cb,
ges,
TALER_EXCHANGE_OPTION_END);
= TALER_EXCHANGE_get_keys (TALER_TESTING_interpreter_get_context (is),
ges->exchange_url,
NULL,
&cert_cb,
ges);
if (NULL == ges->exchange)
{
GNUNET_break (0);
@ -163,9 +172,11 @@ get_exchange_cleanup (void *cls,
if (NULL != ges->exchange)
{
TALER_EXCHANGE_disconnect (ges->exchange);
TALER_EXCHANGE_get_keys_cancel (ges->exchange);
ges->exchange = NULL;
}
TALER_EXCHANGE_keys_decref (ges->keys);
ges->keys = NULL;
GNUNET_free (ges->master_priv_file);
GNUNET_free (ges->exchange_url);
GNUNET_free (ges);
@ -189,16 +200,13 @@ get_exchange_traits (void *cls,
{
struct GetExchangeState *ges = cls;
unsigned int off = (NULL == ges->master_priv_file) ? 1 : 0;
struct TALER_EXCHANGE_Keys *keys
= TALER_EXCHANGE_get_keys (ges->exchange);
if (NULL != keys)
if (NULL != ges->keys)
{
struct TALER_TESTING_Trait traits[] = {
TALER_TESTING_make_trait_master_priv (&ges->master_priv),
TALER_TESTING_make_trait_master_pub (&keys->master_pub),
TALER_TESTING_make_trait_exchange (ges->exchange),
TALER_TESTING_make_trait_keys (keys),
TALER_TESTING_make_trait_master_pub (&ges->keys->master_pub),
TALER_TESTING_make_trait_keys (ges->keys),
TALER_TESTING_make_trait_exchange_url (ges->exchange_url),
TALER_TESTING_trait_end ()
};
@ -212,7 +220,6 @@ get_exchange_traits (void *cls,
{
struct TALER_TESTING_Trait traits[] = {
TALER_TESTING_make_trait_master_priv (&ges->master_priv),
TALER_TESTING_make_trait_exchange (ges->exchange),
TALER_TESTING_make_trait_exchange_url (ges->exchange_url),
TALER_TESTING_trait_end ()
};

View File

@ -133,11 +133,8 @@ deposit_cb (void *cls,
const struct TALER_EXCHANGE_PurseDepositResponse *dr)
{
struct PurseDepositState *ds = cls;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (ds->is);
ds->dh = NULL;
GNUNET_assert (NULL != exchange);
if (ds->expected_response_code != dr->hr.http_status)
{
TALER_TESTING_unexpected_status (ds->is,
@ -197,10 +194,10 @@ deposit_cb (void *cls,
/* Deposits complete, create trait! */
ds->reserve_history.type = TALER_EXCHANGE_RTT_MERGE;
{
const struct TALER_EXCHANGE_Keys *keys;
struct TALER_EXCHANGE_Keys *keys;
const struct TALER_EXCHANGE_GlobalFee *gf;
keys = TALER_EXCHANGE_get_keys (exchange);
keys = TALER_TESTING_get_keys (ds->is);
GNUNET_assert (NULL != keys);
gf = TALER_EXCHANGE_get_global_fee (keys,
*merge_timestamp);

View File

@ -371,12 +371,8 @@ reveal_cb (void *cls,
struct RefreshRevealState *rrs = cls;
const struct TALER_EXCHANGE_HttpResponse *hr = &rr->hr;
const struct TALER_TESTING_Command *melt_cmd;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (rrs->is);
rrs->rrh = NULL;
if (NULL == exchange)
return;
if (rrs->expected_response_code != hr->http_status)
{
if (0 != rrs->do_retry)
@ -1006,12 +1002,8 @@ melt_run (void *cls,
NULL
};
const char **melt_fresh_amounts;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
rms->cmd = cmd;
if (NULL == exchange)
return;
if (NULL == (melt_fresh_amounts = rms->melt_fresh_amounts))
melt_fresh_amounts = default_melt_fresh_amounts;
rms->is = is;
@ -1115,7 +1107,7 @@ melt_run (void *cls,
TALER_TESTING_interpreter_fail (rms->is);
return;
}
fresh_pk = TALER_TESTING_find_pk (TALER_EXCHANGE_get_keys (exchange),
fresh_pk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (rms->is),
&fresh_amount,
age_restricted);
if (NULL == fresh_pk)

View File

@ -230,19 +230,15 @@ reserve_history_cb (void *cls,
struct HistoryState *ss = cls;
struct TALER_TESTING_Interpreter *is = ss->is;
struct TALER_Amount eb;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
ss->rsh = NULL;
if (NULL == exchange)
return;
if (MHD_HTTP_OK == rs->hr.http_status)
{
const struct TALER_EXCHANGE_Keys *keys;
struct TALER_EXCHANGE_Keys *keys;
const struct TALER_EXCHANGE_GlobalFee *gf;
ss->reserve_history.type = TALER_EXCHANGE_RTT_HISTORY;
keys = TALER_EXCHANGE_get_keys (exchange);
keys = TALER_TESTING_get_keys (is);
GNUNET_assert (NULL != keys);
gf = TALER_EXCHANGE_get_global_fee (keys,
rs->ts);
@ -343,11 +339,7 @@ history_run (void *cls,
{
struct HistoryState *ss = cls;
const struct TALER_TESTING_Command *create_reserve;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
if (NULL == exchange)
return;
ss->is = is;
create_reserve
= TALER_TESTING_interpreter_lookup_command (is,

View File

@ -165,11 +165,7 @@ open_run (void *cls,
struct OpenState *ss = cls;
const struct TALER_TESTING_Command *create_reserve;
struct TALER_EXCHANGE_PurseDeposit cp[GNUNET_NZL (ss->cpl)];
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
if (NULL == exchange)
return;
ss->is = is;
create_reserve
= TALER_TESTING_interpreter_lookup_command (is,

View File

@ -184,12 +184,8 @@ purse_run (void *cls,
struct ReservePurseState *ds = cls;
const struct TALER_ReservePrivateKeyP *reserve_priv;
const struct TALER_TESTING_Command *ref;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
(void) cmd;
if (NULL == exchange)
return;
ds->is = is;
ref = TALER_TESTING_interpreter_lookup_command (ds->is,
ds->reserve_ref);

View File

@ -314,11 +314,7 @@ status_run (void *cls,
{
struct StatusState *ss = cls;
const struct TALER_TESTING_Command *create_reserve;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
if (NULL == exchange)
return;
ss->is = is;
create_reserve
= TALER_TESTING_interpreter_lookup_command (is,

View File

@ -58,12 +58,12 @@ serialize_keys_run (void *cls,
struct TALER_TESTING_Interpreter *is)
{
struct SerializeKeysState *sks = cls;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
struct TALER_EXCHANGE_Keys *keys
= TALER_TESTING_get_keys (is);
if (NULL == exchange)
if (NULL == keys)
return;
sks->keys = TALER_EXCHANGE_serialize_data (exchange);
sks->keys = TALER_EXCHANGE_keys_to_json (keys);
if (NULL == sks->keys)
{
GNUNET_break (0);
@ -71,7 +71,7 @@ serialize_keys_run (void *cls,
}
sks->exchange_url
= GNUNET_strdup (
TALER_EXCHANGE_get_base_url (exchange));
TALER_TESTING_get_exchange_url (is));
TALER_TESTING_interpreter_next (is);
}

View File

@ -309,12 +309,8 @@ track_transfer_run (void *cls,
struct TrackTransferState *tts = cls;
struct TALER_WireTransferIdentifierRawP wtid;
const struct TALER_WireTransferIdentifierRawP *wtid_ptr;
struct TALER_EXCHANGE_Handle *exchange
= TALER_TESTING_get_exchange (is);
tts->cmd = cmd;
if (NULL == exchange)
return;
/* If no reference is given, we'll use a all-zeros
* WTID */
memset (&wtid,

View File

@ -347,7 +347,6 @@ withdraw_run (void *cls,
const struct TALER_ReservePrivateKeyP *rp;
const struct TALER_TESTING_Command *create_reserve;
const struct TALER_EXCHANGE_DenomPublicKey *dpk;
struct TALER_EXCHANGE_Handle *exchange;
ws->cmd = cmd;
ws->is = is;
@ -369,12 +368,9 @@ withdraw_run (void *cls,
TALER_TESTING_interpreter_fail (is);
return;
}
exchange = TALER_TESTING_get_exchange (is);
if (NULL == exchange)
return;
if (NULL == ws->exchange_url)
ws->exchange_url
= GNUNET_strdup (TALER_EXCHANGE_get_base_url (exchange));
= GNUNET_strdup (TALER_TESTING_get_exchange_url (is));
ws->reserve_priv = *rp;
GNUNET_CRYPTO_eddsa_key_get_public (&ws->reserve_priv.eddsa_priv,
&ws->reserve_pub.eddsa_pub);

View File

@ -75,33 +75,6 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
}
struct TALER_EXCHANGE_Handle *
TALER_TESTING_get_exchange (struct TALER_TESTING_Interpreter *is)
{
struct TALER_EXCHANGE_Handle *exchange;
const struct TALER_TESTING_Command *exchange_cmd;
exchange_cmd
= TALER_TESTING_interpreter_get_command (is,
"exchange");
if (NULL == exchange_cmd)
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return NULL;
}
if (GNUNET_OK !=
TALER_TESTING_get_trait_exchange (exchange_cmd,
&exchange))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return NULL;
}
return exchange;
}
const char *
TALER_TESTING_get_exchange_url (struct TALER_TESTING_Interpreter *is)
{