Compare commits
No commits in common. "47620fa81b74a090767443445048ec9e3c15456e" and "f969bd3c5b47e3b48a6450908a2abf7de50b0998" have entirely different histories.
47620fa81b
...
f969bd3c5b
@ -961,11 +961,10 @@ struct TALER_EXCHANGE_WireAccount
|
|||||||
* @return #GNUNET_OK if parsing @a accounts succeeded
|
* @return #GNUNET_OK if parsing @a accounts succeeded
|
||||||
*/
|
*/
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_EXCHANGE_parse_accounts (
|
TALER_EXCHANGE_parse_accounts (const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
const struct TALER_MasterPublicKeyP *master_pub,
|
|
||||||
const json_t *accounts,
|
const json_t *accounts,
|
||||||
unsigned int was_length,
|
struct TALER_EXCHANGE_WireAccount was[],
|
||||||
struct TALER_EXCHANGE_WireAccount was[static was_length]);
|
unsigned int was_length);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -975,9 +974,8 @@ TALER_EXCHANGE_parse_accounts (
|
|||||||
* @param was_len length of the @a was array
|
* @param was_len length of the @a was array
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_free_accounts (
|
TALER_EXCHANGE_free_accounts (struct TALER_EXCHANGE_WireAccount *was,
|
||||||
unsigned int was_len,
|
unsigned int was_len);
|
||||||
struct TALER_EXCHANGE_WireAccount was[static was_len]);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1064,18 +1062,14 @@ struct TALER_EXCHANGE_WireHandle;
|
|||||||
* response are all valid). If the exchange's reply is not
|
* response are all valid). If the exchange's reply is not
|
||||||
* well-formed, we return an HTTP status code of zero to @a cb.
|
* well-formed, we return an HTTP status code of zero to @a cb.
|
||||||
*
|
*
|
||||||
* @param ctx curl context
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
* @param url exchange base URL
|
|
||||||
* @param keys the keys of the exchange
|
|
||||||
* @param wire_cb the callback to call when a reply for this request is available
|
* @param wire_cb the callback to call when a reply for this request is available
|
||||||
* @param wire_cb_cls closure for the above callback
|
* @param wire_cb_cls closure for the above callback
|
||||||
* @return a handle for this request
|
* @return a handle for this request
|
||||||
*/
|
*/
|
||||||
struct TALER_EXCHANGE_WireHandle *
|
struct TALER_EXCHANGE_WireHandle *
|
||||||
TALER_EXCHANGE_wire (
|
TALER_EXCHANGE_wire (
|
||||||
struct GNUNET_CURL_Context *ctx,
|
struct TALER_EXCHANGE_Handle *exchange,
|
||||||
const char *url,
|
|
||||||
struct TALER_EXCHANGE_Keys *keys,
|
|
||||||
TALER_EXCHANGE_WireCallback wire_cb,
|
TALER_EXCHANGE_WireCallback wire_cb,
|
||||||
void *wire_cb_cls);
|
void *wire_cb_cls);
|
||||||
|
|
||||||
@ -1304,7 +1298,7 @@ TALER_EXCHANGE_batch_deposit (
|
|||||||
struct TALER_EXCHANGE_Keys *keys,
|
struct TALER_EXCHANGE_Keys *keys,
|
||||||
const struct TALER_EXCHANGE_DepositContractDetail *dcd,
|
const struct TALER_EXCHANGE_DepositContractDetail *dcd,
|
||||||
unsigned int num_cdds,
|
unsigned int num_cdds,
|
||||||
const struct TALER_EXCHANGE_CoinDepositDetail cdds[static num_cdds],
|
const struct TALER_EXCHANGE_CoinDepositDetail *cdds,
|
||||||
TALER_EXCHANGE_BatchDepositResultCallback cb,
|
TALER_EXCHANGE_BatchDepositResultCallback cb,
|
||||||
void *cb_cls,
|
void *cb_cls,
|
||||||
enum TALER_ErrorCode *ec);
|
enum TALER_ErrorCode *ec);
|
||||||
@ -1314,7 +1308,7 @@ TALER_EXCHANGE_batch_deposit (
|
|||||||
* Change the chance that our deposit confirmation will be given to the
|
* Change the chance that our deposit confirmation will be given to the
|
||||||
* auditor to 100%.
|
* auditor to 100%.
|
||||||
*
|
*
|
||||||
* @param[in,out] deposit the batch deposit permission request handle
|
* @param deposit the batch deposit permission request handle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_batch_deposit_force_dc (
|
TALER_EXCHANGE_batch_deposit_force_dc (
|
||||||
@ -1325,7 +1319,7 @@ TALER_EXCHANGE_batch_deposit_force_dc (
|
|||||||
* Cancel a batch deposit permission request. This function cannot be used
|
* Cancel a batch deposit permission request. This function cannot be used
|
||||||
* on a request handle if a response is already served for it.
|
* on a request handle if a response is already served for it.
|
||||||
*
|
*
|
||||||
* @param[in] deposit the deposit permission request handle
|
* @param deposit the deposit permission request handle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_batch_deposit_cancel (
|
TALER_EXCHANGE_batch_deposit_cancel (
|
||||||
@ -1545,7 +1539,7 @@ TALER_EXCHANGE_csr_melt (
|
|||||||
const char *url,
|
const char *url,
|
||||||
const struct TALER_RefreshMasterSecretP *rms,
|
const struct TALER_RefreshMasterSecretP *rms,
|
||||||
unsigned int nks_len,
|
unsigned int nks_len,
|
||||||
struct TALER_EXCHANGE_NonceKey nks[static nks_len],
|
struct TALER_EXCHANGE_NonceKey *nks,
|
||||||
TALER_EXCHANGE_CsRMeltCallback res_cb,
|
TALER_EXCHANGE_CsRMeltCallback res_cb,
|
||||||
void *res_cb_cls);
|
void *res_cb_cls);
|
||||||
|
|
||||||
@ -2592,8 +2586,8 @@ typedef void
|
|||||||
* @param exchange_url The base-URL of the exchange
|
* @param exchange_url The base-URL of the exchange
|
||||||
* @param keys The /keys material from the exchange
|
* @param keys The /keys material from the exchange
|
||||||
* @param reserve_priv private key of the reserve to withdraw from
|
* @param reserve_priv private key of the reserve to withdraw from
|
||||||
* @param wci_length number of entries in @a wcis
|
|
||||||
* @param wcis inputs that determine the planchets
|
* @param wcis inputs that determine the planchets
|
||||||
|
* @param wci_length number of entries in @a wcis
|
||||||
* @param res_cb the callback to call when the final result for this request is available
|
* @param res_cb the callback to call when the final result for this request is available
|
||||||
* @param res_cb_cls closure for @a res_cb
|
* @param res_cb_cls closure for @a res_cb
|
||||||
* @return NULL
|
* @return NULL
|
||||||
@ -2606,8 +2600,8 @@ TALER_EXCHANGE_batch_withdraw (
|
|||||||
const char *exchange_url,
|
const char *exchange_url,
|
||||||
const struct TALER_EXCHANGE_Keys *keys,
|
const struct TALER_EXCHANGE_Keys *keys,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
const struct TALER_EXCHANGE_WithdrawCoinInput *wcis,
|
||||||
unsigned int wci_length,
|
unsigned int wci_length,
|
||||||
const struct TALER_EXCHANGE_WithdrawCoinInput wcis[static wci_length],
|
|
||||||
TALER_EXCHANGE_BatchWithdrawCallback res_cb,
|
TALER_EXCHANGE_BatchWithdrawCallback res_cb,
|
||||||
void *res_cb_cls);
|
void *res_cb_cls);
|
||||||
|
|
||||||
@ -2804,8 +2798,8 @@ TALER_EXCHANGE_batch_withdraw2 (
|
|||||||
const char *exchange_url,
|
const char *exchange_url,
|
||||||
const struct TALER_EXCHANGE_Keys *keys,
|
const struct TALER_EXCHANGE_Keys *keys,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
const struct TALER_PlanchetDetail *pds,
|
||||||
unsigned int pds_length,
|
unsigned int pds_length,
|
||||||
const struct TALER_PlanchetDetail pds[static pds_length],
|
|
||||||
TALER_EXCHANGE_BatchWithdraw2Callback res_cb,
|
TALER_EXCHANGE_BatchWithdraw2Callback res_cb,
|
||||||
void *res_cb_cls);
|
void *res_cb_cls);
|
||||||
|
|
||||||
@ -2903,8 +2897,8 @@ typedef void
|
|||||||
* @param exchange_url The base url of the exchange
|
* @param exchange_url The base url of the exchange
|
||||||
* @parm keys The denomination keys from the exchange
|
* @parm keys The denomination keys from the exchange
|
||||||
* @param reserve_priv The pivate key to the reserve
|
* @param reserve_priv The pivate key to the reserve
|
||||||
* @param num_coins The number of elements in @e coin_inputs
|
|
||||||
* @param coin_inputs The input for the coins to withdraw
|
* @param coin_inputs The input for the coins to withdraw
|
||||||
|
* @param num_coins The number of elements in @e coin_inputs
|
||||||
* @param max_age The maximum age we commit to.
|
* @param max_age The maximum age we commit to.
|
||||||
* @param res_cb A callback for the result, maybe NULL
|
* @param res_cb A callback for the result, maybe NULL
|
||||||
* @param res_cb_cls A closure for @e res_cb, maybe NULL
|
* @param res_cb_cls A closure for @e res_cb, maybe NULL
|
||||||
@ -2917,9 +2911,8 @@ TALER_EXCHANGE_age_withdraw (
|
|||||||
const char *exchange_url,
|
const char *exchange_url,
|
||||||
struct TALER_EXCHANGE_Keys *keys,
|
struct TALER_EXCHANGE_Keys *keys,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
const struct TALER_EXCHANGE_AgeWithdrawCoinInput *coin_inputs,
|
||||||
size_t num_coins,
|
size_t num_coins,
|
||||||
const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[
|
|
||||||
const static num_coins],
|
|
||||||
uint8_t max_age,
|
uint8_t max_age,
|
||||||
TALER_EXCHANGE_AgeWithdrawCallback res_cb,
|
TALER_EXCHANGE_AgeWithdrawCallback res_cb,
|
||||||
void *res_cb_cls);
|
void *res_cb_cls);
|
||||||
@ -3240,7 +3233,7 @@ TALER_EXCHANGE_refreshes_reveal (
|
|||||||
const struct TALER_RefreshMasterSecretP *rms,
|
const struct TALER_RefreshMasterSecretP *rms,
|
||||||
const struct TALER_EXCHANGE_RefreshData *rd,
|
const struct TALER_EXCHANGE_RefreshData *rd,
|
||||||
unsigned int num_coins,
|
unsigned int num_coins,
|
||||||
const struct TALER_ExchangeWithdrawValues alg_values[static num_coins],
|
const struct TALER_ExchangeWithdrawValues *alg_values,
|
||||||
uint32_t noreveal_index,
|
uint32_t noreveal_index,
|
||||||
TALER_EXCHANGE_RefreshesRevealCallback reveal_cb,
|
TALER_EXCHANGE_RefreshesRevealCallback reveal_cb,
|
||||||
void *reveal_cb_cls);
|
void *reveal_cb_cls);
|
||||||
@ -3711,19 +3704,19 @@ TALER_EXCHANGE_parse_reserve_history (
|
|||||||
struct TALER_Amount *total_in,
|
struct TALER_Amount *total_in,
|
||||||
struct TALER_Amount *total_out,
|
struct TALER_Amount *total_out,
|
||||||
unsigned int history_length,
|
unsigned int history_length,
|
||||||
struct TALER_EXCHANGE_ReserveHistoryEntry rhistory[static history_length]);
|
struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free memory (potentially) allocated by #TALER_EXCHANGE_parse_reserve_history().
|
* Free memory (potentially) allocated by #TALER_EXCHANGE_parse_reserve_history().
|
||||||
*
|
*
|
||||||
|
* @param rhistory result to free
|
||||||
* @param len number of entries in @a rhistory
|
* @param len number of entries in @a rhistory
|
||||||
* @param[in] rhistory result to free
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_free_reserve_history (
|
TALER_EXCHANGE_free_reserve_history (
|
||||||
unsigned int len,
|
struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory,
|
||||||
struct TALER_EXCHANGE_ReserveHistoryEntry rhistory[static len]);
|
unsigned int len);
|
||||||
|
|
||||||
|
|
||||||
/* ********************* /recoup *********************** */
|
/* ********************* /recoup *********************** */
|
||||||
@ -4037,9 +4030,7 @@ typedef void
|
|||||||
* Run interaction with exchange to check KYC status
|
* Run interaction with exchange to check KYC status
|
||||||
* of a merchant.
|
* of a merchant.
|
||||||
*
|
*
|
||||||
* @param ctx CURL context
|
* @param eh exchange handle to use
|
||||||
* @param url exchange base URL
|
|
||||||
* @param keys keys of the exchange
|
|
||||||
* @param requirement_row number identifying the KYC requirement
|
* @param requirement_row number identifying the KYC requirement
|
||||||
* @param h_payto hash of the payto:// URI at @a payment_target
|
* @param h_payto hash of the payto:// URI at @a payment_target
|
||||||
* @param ut type of the entity performing the KYC check
|
* @param ut type of the entity performing the KYC check
|
||||||
@ -4049,10 +4040,7 @@ typedef void
|
|||||||
* @return NULL on error
|
* @return NULL on error
|
||||||
*/
|
*/
|
||||||
struct TALER_EXCHANGE_KycCheckHandle *
|
struct TALER_EXCHANGE_KycCheckHandle *
|
||||||
TALER_EXCHANGE_kyc_check (
|
TALER_EXCHANGE_kyc_check (struct TALER_EXCHANGE_Handle *eh,
|
||||||
struct GNUNET_CURL_Context *ctx,
|
|
||||||
const char *url,
|
|
||||||
struct TALER_EXCHANGE_Keys *keys,
|
|
||||||
uint64_t requirement_row,
|
uint64_t requirement_row,
|
||||||
const struct TALER_PaytoHashP *h_payto,
|
const struct TALER_PaytoHashP *h_payto,
|
||||||
enum TALER_KYCLOGIC_KycUserType ut,
|
enum TALER_KYCLOGIC_KycUserType ut,
|
||||||
@ -6141,7 +6129,7 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
|||||||
const struct TALER_ContractDiffiePrivateP *contract_priv,
|
const struct TALER_ContractDiffiePrivateP *contract_priv,
|
||||||
const json_t *contract_terms,
|
const json_t *contract_terms,
|
||||||
unsigned int num_deposits,
|
unsigned int num_deposits,
|
||||||
const struct TALER_EXCHANGE_PurseDeposit deposits[static num_deposits],
|
const struct TALER_EXCHANGE_PurseDeposit *deposits,
|
||||||
bool upload_contract,
|
bool upload_contract,
|
||||||
TALER_EXCHANGE_PurseCreateDepositCallback cb,
|
TALER_EXCHANGE_PurseCreateDepositCallback cb,
|
||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
@ -6543,7 +6531,7 @@ TALER_EXCHANGE_purse_deposit (
|
|||||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||||
uint8_t min_age,
|
uint8_t min_age,
|
||||||
unsigned int num_deposits,
|
unsigned int num_deposits,
|
||||||
const struct TALER_EXCHANGE_PurseDeposit deposits[static num_deposits],
|
const struct TALER_EXCHANGE_PurseDeposit *deposits,
|
||||||
TALER_EXCHANGE_PurseDepositCallback cb,
|
TALER_EXCHANGE_PurseDepositCallback cb,
|
||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
|
|
||||||
@ -6684,8 +6672,7 @@ TALER_EXCHANGE_reserves_open (
|
|||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
const struct TALER_Amount *reserve_contribution,
|
const struct TALER_Amount *reserve_contribution,
|
||||||
unsigned int coin_payments_length,
|
unsigned int coin_payments_length,
|
||||||
const struct TALER_EXCHANGE_PurseDeposit coin_payments[
|
const struct TALER_EXCHANGE_PurseDeposit *coin_payments,
|
||||||
static coin_payments_length],
|
|
||||||
struct GNUNET_TIME_Timestamp expiration_time,
|
struct GNUNET_TIME_Timestamp expiration_time,
|
||||||
uint32_t min_purses,
|
uint32_t min_purses,
|
||||||
TALER_EXCHANGE_ReservesOpenCallback cb,
|
TALER_EXCHANGE_ReservesOpenCallback cb,
|
||||||
@ -6696,7 +6683,7 @@ TALER_EXCHANGE_reserves_open (
|
|||||||
* Cancel a reserve status request. This function cannot be used
|
* Cancel a reserve status request. This function cannot be used
|
||||||
* on a request handle if a response is already served for it.
|
* on a request handle if a response is already served for it.
|
||||||
*
|
*
|
||||||
* @param[in] roh the reserve open request handle
|
* @param roh the reserve open request handle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_reserves_open_cancel (
|
TALER_EXCHANGE_reserves_open_cancel (
|
||||||
@ -6890,7 +6877,7 @@ TALER_EXCHANGE_reserves_attest (
|
|||||||
const char *url,
|
const char *url,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
unsigned int attributes_length,
|
unsigned int attributes_length,
|
||||||
const char *attributes[const static attributes_length],
|
const char *const*attributes,
|
||||||
TALER_EXCHANGE_ReservesPostAttestCallback cb,
|
TALER_EXCHANGE_ReservesPostAttestCallback cb,
|
||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
|
|
||||||
|
@ -356,12 +356,12 @@ reserve_age_withdraw_payment_required (
|
|||||||
rhistory))
|
rhistory))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that funds were really insufficient */
|
/* Check that funds were really insufficient */
|
||||||
@ -769,37 +769,33 @@ csr_withdraw_done (
|
|||||||
* csr-parameter via /csr-withdraw.
|
* csr-parameter via /csr-withdraw.
|
||||||
*
|
*
|
||||||
* @param awh The handler to the age-withdraw
|
* @param awh The handler to the age-withdraw
|
||||||
* @param num_coins The number of coins in @e coin_inputs
|
|
||||||
* @param coin_inputs The input for the individial coin(-candidates)
|
* @param coin_inputs The input for the individial coin(-candidates)
|
||||||
|
* @param num_coins The number of coins in @e coin_inputs
|
||||||
|
*
|
||||||
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
|
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
prepare_coins (
|
prepare_coins (
|
||||||
struct TALER_EXCHANGE_AgeWithdrawHandle *awh,
|
struct TALER_EXCHANGE_AgeWithdrawHandle *awh,
|
||||||
size_t num_coins,
|
const struct TALER_EXCHANGE_AgeWithdrawCoinInput *coin_inputs,
|
||||||
const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[
|
size_t num_coins)
|
||||||
static num_coins])
|
|
||||||
{
|
{
|
||||||
#define FAIL_IF(cond) \
|
|
||||||
do { \
|
|
||||||
if ((cond)) \
|
|
||||||
{ \
|
|
||||||
GNUNET_break (! (cond)); \
|
|
||||||
goto ERROR; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
GNUNET_assert (0 < num_coins);
|
if (GNUNET_OK != TALER_amount_set_zero (
|
||||||
awh->age_mask = coin_inputs[0].denom_pub->key.age_mask;
|
awh->keys->currency,
|
||||||
|
&awh->amount_with_fee))
|
||||||
FAIL_IF (GNUNET_OK !=
|
{
|
||||||
TALER_amount_set_zero (awh->keys->currency,
|
GNUNET_break (0);
|
||||||
&awh->amount_with_fee));
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
awh->coin_data = GNUNET_new_array (awh->num_coins,
|
awh->coin_data = GNUNET_new_array (awh->num_coins,
|
||||||
struct CoinData);
|
struct CoinData);
|
||||||
|
|
||||||
|
GNUNET_assert (0 < num_coins);
|
||||||
|
awh->age_mask = coin_inputs[0].denom_pub->key.age_mask;
|
||||||
|
|
||||||
for (size_t i = 0; i < num_coins; i++)
|
for (size_t i = 0; i < num_coins; i++)
|
||||||
{
|
{
|
||||||
struct CoinData *cd = &awh->coin_data[i];
|
struct CoinData *cd = &awh->coin_data[i];
|
||||||
@ -807,7 +803,12 @@ prepare_coins (
|
|||||||
cd->denom_pub = *input->denom_pub;
|
cd->denom_pub = *input->denom_pub;
|
||||||
|
|
||||||
/* The mask must be the same for all coins */
|
/* The mask must be the same for all coins */
|
||||||
FAIL_IF (awh->age_mask.bits != input->denom_pub->key.age_mask.bits);
|
if (awh->age_mask.bits != input->denom_pub->key.age_mask.bits)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
TALER_EXCHANGE_age_withdraw_cancel (awh);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
TALER_denom_pub_deep_copy (&cd->denom_pub.key,
|
TALER_denom_pub_deep_copy (&cd->denom_pub.key,
|
||||||
&input->denom_pub->key);
|
&input->denom_pub->key);
|
||||||
@ -816,15 +817,26 @@ prepare_coins (
|
|||||||
{
|
{
|
||||||
struct TALER_Amount coin_total;
|
struct TALER_Amount coin_total;
|
||||||
|
|
||||||
FAIL_IF (0 >
|
if (0 >
|
||||||
TALER_amount_add (&coin_total,
|
TALER_amount_add (&coin_total,
|
||||||
&cd->denom_pub.fees.withdraw,
|
&cd->denom_pub.fees.withdraw,
|
||||||
&cd->denom_pub.value));
|
&cd->denom_pub.value))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
TALER_EXCHANGE_age_withdraw_cancel (awh);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
FAIL_IF (0 >
|
if (0 >
|
||||||
TALER_amount_add (&awh->amount_with_fee,
|
TALER_amount_add (&awh->amount_with_fee,
|
||||||
&awh->amount_with_fee,
|
&awh->amount_with_fee,
|
||||||
&coin_total));
|
&coin_total))
|
||||||
|
{
|
||||||
|
/* Overflow here? Very strange, our CPU must be fried... */
|
||||||
|
GNUNET_break (0);
|
||||||
|
TALER_EXCHANGE_age_withdraw_cancel (awh);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t k = 0; k < TALER_CNC_KAPPA; k++)
|
for (uint8_t k = 0; k < TALER_CNC_KAPPA; k++)
|
||||||
@ -835,13 +847,12 @@ prepare_coins (
|
|||||||
|
|
||||||
/* Derive the age restriction from the given secret and
|
/* Derive the age restriction from the given secret and
|
||||||
* the maximum age */
|
* the maximum age */
|
||||||
FAIL_IF (GNUNET_OK !=
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_age_restriction_from_secret (
|
TALER_age_restriction_from_secret (
|
||||||
&can->secret,
|
&can->secret,
|
||||||
&input->denom_pub->key.age_mask,
|
&input->denom_pub->key.age_mask,
|
||||||
awh->max_age,
|
awh->max_age,
|
||||||
&can->age_commitment_proof));
|
&can->age_commitment_proof));
|
||||||
|
|
||||||
TALER_age_commitment_hash (&can->age_commitment_proof.commitment,
|
TALER_age_commitment_hash (&can->age_commitment_proof.commitment,
|
||||||
&can->h_age_commitment);
|
&can->h_age_commitment);
|
||||||
|
|
||||||
@ -856,18 +867,28 @@ prepare_coins (
|
|||||||
TALER_planchet_blinding_secret_create (&can->secret,
|
TALER_planchet_blinding_secret_create (&can->secret,
|
||||||
&can->alg_values,
|
&can->alg_values,
|
||||||
&can->blinding_key);
|
&can->blinding_key);
|
||||||
FAIL_IF (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_planchet_prepare (&cd->denom_pub.key,
|
TALER_planchet_prepare (&cd->denom_pub.key,
|
||||||
&can->alg_values,
|
&can->alg_values,
|
||||||
&can->blinding_key,
|
&can->blinding_key,
|
||||||
&can->coin_priv,
|
&can->coin_priv,
|
||||||
&can->h_age_commitment,
|
&can->h_age_commitment,
|
||||||
&can->h_coin_pub,
|
&can->h_coin_pub,
|
||||||
&can->planchet_detail));
|
&can->planchet_detail))
|
||||||
FAIL_IF (GNUNET_OK !=
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
TALER_EXCHANGE_age_withdraw_cancel (awh);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_OK !=
|
||||||
TALER_coin_ev_hash (&can->planchet_detail.blinded_planchet,
|
TALER_coin_ev_hash (&can->planchet_detail.blinded_planchet,
|
||||||
&can->planchet_detail.denom_pub_hash,
|
&can->planchet_detail.denom_pub_hash,
|
||||||
&can->blinded_coin_h));
|
&can->blinded_coin_h))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
TALER_EXCHANGE_age_withdraw_cancel (awh);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
@ -890,8 +911,9 @@ prepare_coins (
|
|||||||
of the blinded_planchet here; the other part
|
of the blinded_planchet here; the other part
|
||||||
will be done after the /csr-withdraw request! */
|
will be done after the /csr-withdraw request! */
|
||||||
can->planchet_detail.blinded_planchet.cipher = TALER_DENOMINATION_CS;
|
can->planchet_detail.blinded_planchet.cipher = TALER_DENOMINATION_CS;
|
||||||
can->csr_withdraw_handle =
|
can->csr_withdraw_handle = NULL;
|
||||||
TALER_EXCHANGE_csr_withdraw (awh->curl_ctx,
|
TALER_EXCHANGE_csr_withdraw (
|
||||||
|
awh->curl_ctx,
|
||||||
awh->exchange_url,
|
awh->exchange_url,
|
||||||
&cd->denom_pub,
|
&cd->denom_pub,
|
||||||
&can->planchet_detail
|
&can->planchet_detail
|
||||||
@ -901,22 +923,24 @@ prepare_coins (
|
|||||||
.nonce,
|
.nonce,
|
||||||
&csr_withdraw_done,
|
&csr_withdraw_done,
|
||||||
&can);
|
&can);
|
||||||
FAIL_IF (NULL == can->csr_withdraw_handle);
|
if (NULL == can->csr_withdraw_handle)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
TALER_EXCHANGE_age_withdraw_cancel (awh);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
awh->csr_pending++;
|
awh->csr_pending++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
FAIL_IF (1);
|
GNUNET_break (0);
|
||||||
|
TALER_EXCHANGE_age_withdraw_cancel (awh);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
|
|
||||||
ERROR:
|
|
||||||
TALER_EXCHANGE_age_withdraw_cancel (awh);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
#undef FAIL_IF
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TALER_EXCHANGE_AgeWithdrawHandle *
|
struct TALER_EXCHANGE_AgeWithdrawHandle *
|
||||||
@ -925,9 +949,8 @@ TALER_EXCHANGE_age_withdraw (
|
|||||||
const char *exchange_url,
|
const char *exchange_url,
|
||||||
struct TALER_EXCHANGE_Keys *keys,
|
struct TALER_EXCHANGE_Keys *keys,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
const struct TALER_EXCHANGE_AgeWithdrawCoinInput *coin_inputs,
|
||||||
size_t num_coins,
|
size_t num_coins,
|
||||||
const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[const static
|
|
||||||
num_coins],
|
|
||||||
uint8_t max_age,
|
uint8_t max_age,
|
||||||
TALER_EXCHANGE_AgeWithdrawCallback res_cb,
|
TALER_EXCHANGE_AgeWithdrawCallback res_cb,
|
||||||
void *res_cb_cls)
|
void *res_cb_cls)
|
||||||
@ -953,8 +976,8 @@ TALER_EXCHANGE_age_withdraw (
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (GNUNET_OK != prepare_coins (awh,
|
if (GNUNET_OK != prepare_coins (awh,
|
||||||
num_coins,
|
coin_inputs,
|
||||||
coin_inputs))
|
num_coins))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* If there were no CS denominations, we can now perform the actual
|
/* If there were no CS denominations, we can now perform the actual
|
||||||
|
@ -559,7 +559,7 @@ TALER_EXCHANGE_batch_deposit (
|
|||||||
struct TALER_EXCHANGE_Keys *keys,
|
struct TALER_EXCHANGE_Keys *keys,
|
||||||
const struct TALER_EXCHANGE_DepositContractDetail *dcd,
|
const struct TALER_EXCHANGE_DepositContractDetail *dcd,
|
||||||
unsigned int num_cdds,
|
unsigned int num_cdds,
|
||||||
const struct TALER_EXCHANGE_CoinDepositDetail cdds[static num_cdds],
|
const struct TALER_EXCHANGE_CoinDepositDetail *cdds,
|
||||||
TALER_EXCHANGE_BatchDepositResultCallback cb,
|
TALER_EXCHANGE_BatchDepositResultCallback cb,
|
||||||
void *cb_cls,
|
void *cb_cls,
|
||||||
enum TALER_ErrorCode *ec)
|
enum TALER_ErrorCode *ec)
|
||||||
|
@ -270,8 +270,8 @@ phase_two (struct TALER_EXCHANGE_BatchWithdrawHandle *wh)
|
|||||||
wh->exchange_url,
|
wh->exchange_url,
|
||||||
wh->keys,
|
wh->keys,
|
||||||
wh->reserve_priv,
|
wh->reserve_priv,
|
||||||
wh->num_coins,
|
|
||||||
pds,
|
pds,
|
||||||
|
wh->num_coins,
|
||||||
&handle_reserve_batch_withdraw_finished,
|
&handle_reserve_batch_withdraw_finished,
|
||||||
wh);
|
wh);
|
||||||
}
|
}
|
||||||
@ -339,8 +339,8 @@ TALER_EXCHANGE_batch_withdraw (
|
|||||||
const char *exchange_url,
|
const char *exchange_url,
|
||||||
const struct TALER_EXCHANGE_Keys *keys,
|
const struct TALER_EXCHANGE_Keys *keys,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
const struct TALER_EXCHANGE_WithdrawCoinInput *wcis,
|
||||||
unsigned int wci_length,
|
unsigned int wci_length,
|
||||||
const struct TALER_EXCHANGE_WithdrawCoinInput wcis[static wci_length],
|
|
||||||
TALER_EXCHANGE_BatchWithdrawCallback res_cb,
|
TALER_EXCHANGE_BatchWithdrawCallback res_cb,
|
||||||
void *res_cb_cls)
|
void *res_cb_cls)
|
||||||
{
|
{
|
||||||
|
@ -229,12 +229,12 @@ reserve_batch_withdraw_payment_required (
|
|||||||
rhistory))
|
rhistory))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that funds were really insufficient */
|
/* Check that funds were really insufficient */
|
||||||
@ -391,8 +391,8 @@ TALER_EXCHANGE_batch_withdraw2 (
|
|||||||
const char *exchange_url,
|
const char *exchange_url,
|
||||||
const struct TALER_EXCHANGE_Keys *keys,
|
const struct TALER_EXCHANGE_Keys *keys,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
const struct TALER_PlanchetDetail *pds,
|
||||||
unsigned int pds_length,
|
unsigned int pds_length,
|
||||||
const struct TALER_PlanchetDetail pds[static pds_length],
|
|
||||||
TALER_EXCHANGE_BatchWithdraw2Callback res_cb,
|
TALER_EXCHANGE_BatchWithdraw2Callback res_cb,
|
||||||
void *res_cb_cls)
|
void *res_cb_cls)
|
||||||
{
|
{
|
||||||
|
@ -654,7 +654,7 @@ TALER_EXCHANGE_parse_reserve_history (
|
|||||||
struct TALER_Amount *total_in,
|
struct TALER_Amount *total_in,
|
||||||
struct TALER_Amount *total_out,
|
struct TALER_Amount *total_out,
|
||||||
unsigned int history_length,
|
unsigned int history_length,
|
||||||
struct TALER_EXCHANGE_ReserveHistoryEntry rhistory[static history_length])
|
struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory)
|
||||||
{
|
{
|
||||||
const struct
|
const struct
|
||||||
{
|
{
|
||||||
@ -753,8 +753,8 @@ TALER_EXCHANGE_parse_reserve_history (
|
|||||||
|
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_free_reserve_history (
|
TALER_EXCHANGE_free_reserve_history (
|
||||||
unsigned int len,
|
struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory,
|
||||||
struct TALER_EXCHANGE_ReserveHistoryEntry rhistory[static len])
|
unsigned int len)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i<len; i++)
|
for (unsigned int i = 0; i<len; i++)
|
||||||
{
|
{
|
||||||
@ -2281,11 +2281,10 @@ fail:
|
|||||||
|
|
||||||
|
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_EXCHANGE_parse_accounts (
|
TALER_EXCHANGE_parse_accounts (const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
const struct TALER_MasterPublicKeyP *master_pub,
|
|
||||||
const json_t *accounts,
|
const json_t *accounts,
|
||||||
unsigned int was_length,
|
struct TALER_EXCHANGE_WireAccount was[],
|
||||||
struct TALER_EXCHANGE_WireAccount was[static was_length])
|
unsigned int was_length)
|
||||||
{
|
{
|
||||||
memset (was,
|
memset (was,
|
||||||
0,
|
0,
|
||||||
@ -2371,9 +2370,8 @@ TALER_EXCHANGE_parse_accounts (
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_free_accounts (
|
TALER_EXCHANGE_free_accounts (struct TALER_EXCHANGE_WireAccount *was,
|
||||||
unsigned int was_len,
|
unsigned int was_len)
|
||||||
struct TALER_EXCHANGE_WireAccount was[static was_len])
|
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i<was_len; i++)
|
for (unsigned int i = 0; i<was_len; i++)
|
||||||
{
|
{
|
||||||
|
@ -221,7 +221,7 @@ TALER_EXCHANGE_csr_melt (
|
|||||||
const char *url,
|
const char *url,
|
||||||
const struct TALER_RefreshMasterSecretP *rms,
|
const struct TALER_RefreshMasterSecretP *rms,
|
||||||
unsigned int nks_len,
|
unsigned int nks_len,
|
||||||
struct TALER_EXCHANGE_NonceKey nks[static nks_len],
|
struct TALER_EXCHANGE_NonceKey *nks,
|
||||||
TALER_EXCHANGE_CsRMeltCallback res_cb,
|
TALER_EXCHANGE_CsRMeltCallback res_cb,
|
||||||
void *res_cb_cls)
|
void *res_cb_cls)
|
||||||
{
|
{
|
||||||
|
@ -36,16 +36,16 @@
|
|||||||
struct TALER_EXCHANGE_KycCheckHandle
|
struct TALER_EXCHANGE_KycCheckHandle
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection to exchange this request handle will use
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGE_Handle *exchange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The url for this request.
|
* The url for this request.
|
||||||
*/
|
*/
|
||||||
char *url;
|
char *url;
|
||||||
|
|
||||||
/**
|
|
||||||
* Keys of the exchange.
|
|
||||||
*/
|
|
||||||
struct TALER_EXCHANGE_Keys *keys;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle for the request.
|
* Handle for the request.
|
||||||
*/
|
*/
|
||||||
@ -111,6 +111,7 @@ handle_kyc_check_finished (void *cls,
|
|||||||
&status),
|
&status),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
const struct TALER_EXCHANGE_Keys *key_state;
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (j,
|
GNUNET_JSON_parse (j,
|
||||||
@ -125,8 +126,9 @@ handle_kyc_check_finished (void *cls,
|
|||||||
ks.details.ok.kyc_details = kyc_details;
|
ks.details.ok.kyc_details = kyc_details;
|
||||||
ks.details.ok.aml_status
|
ks.details.ok.aml_status
|
||||||
= (enum TALER_AmlDecisionState) status;
|
= (enum TALER_AmlDecisionState) status;
|
||||||
|
key_state = TALER_EXCHANGE_get_keys (kch->exchange);
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_EXCHANGE_test_signing_key (kch->keys,
|
TALER_EXCHANGE_test_signing_key (key_state,
|
||||||
&ks.details.ok.exchange_pub))
|
&ks.details.ok.exchange_pub))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
@ -247,10 +249,7 @@ handle_kyc_check_finished (void *cls,
|
|||||||
|
|
||||||
|
|
||||||
struct TALER_EXCHANGE_KycCheckHandle *
|
struct TALER_EXCHANGE_KycCheckHandle *
|
||||||
TALER_EXCHANGE_kyc_check (
|
TALER_EXCHANGE_kyc_check (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
struct GNUNET_CURL_Context *ctx,
|
|
||||||
const char *url,
|
|
||||||
struct TALER_EXCHANGE_Keys *keys,
|
|
||||||
uint64_t requirement_row,
|
uint64_t requirement_row,
|
||||||
const struct TALER_PaytoHashP *h_payto,
|
const struct TALER_PaytoHashP *h_payto,
|
||||||
enum TALER_KYCLOGIC_KycUserType ut,
|
enum TALER_KYCLOGIC_KycUserType ut,
|
||||||
@ -260,8 +259,15 @@ TALER_EXCHANGE_kyc_check (
|
|||||||
{
|
{
|
||||||
struct TALER_EXCHANGE_KycCheckHandle *kch;
|
struct TALER_EXCHANGE_KycCheckHandle *kch;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
|
struct GNUNET_CURL_Context *ctx;
|
||||||
char *arg_str;
|
char *arg_str;
|
||||||
|
|
||||||
|
if (GNUNET_YES !=
|
||||||
|
TEAH_handle_is_ready (exchange))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
char payto_str[sizeof (*h_payto) * 2];
|
char payto_str[sizeof (*h_payto) * 2];
|
||||||
char *end;
|
char *end;
|
||||||
@ -276,19 +282,19 @@ TALER_EXCHANGE_kyc_check (
|
|||||||
timeout_ms = timeout.rel_value_us
|
timeout_ms = timeout.rel_value_us
|
||||||
/ GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
|
/ GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
|
||||||
GNUNET_asprintf (&arg_str,
|
GNUNET_asprintf (&arg_str,
|
||||||
"kyc-check/%llu/%s/%s?timeout_ms=%llu",
|
"/kyc-check/%llu/%s/%s?timeout_ms=%llu",
|
||||||
(unsigned long long) requirement_row,
|
(unsigned long long) requirement_row,
|
||||||
payto_str,
|
payto_str,
|
||||||
TALER_KYCLOGIC_kyc_user_type2s (ut),
|
TALER_KYCLOGIC_kyc_user_type2s (ut),
|
||||||
timeout_ms);
|
timeout_ms);
|
||||||
}
|
}
|
||||||
kch = GNUNET_new (struct TALER_EXCHANGE_KycCheckHandle);
|
kch = GNUNET_new (struct TALER_EXCHANGE_KycCheckHandle);
|
||||||
|
kch->exchange = exchange;
|
||||||
kch->h_payto = *h_payto;
|
kch->h_payto = *h_payto;
|
||||||
kch->cb = cb;
|
kch->cb = cb;
|
||||||
kch->cb_cls = cb_cls;
|
kch->cb_cls = cb_cls;
|
||||||
kch->url = TALER_url_join (url,
|
kch->url = TEAH_path_to_url (exchange,
|
||||||
arg_str,
|
arg_str);
|
||||||
NULL);
|
|
||||||
GNUNET_free (arg_str);
|
GNUNET_free (arg_str);
|
||||||
if (NULL == kch->url)
|
if (NULL == kch->url)
|
||||||
{
|
{
|
||||||
@ -303,7 +309,7 @@ TALER_EXCHANGE_kyc_check (
|
|||||||
GNUNET_free (kch);
|
GNUNET_free (kch);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
kch->keys = TALER_EXCHANGE_keys_incref (keys);
|
ctx = TEAH_handle_to_context (exchange);
|
||||||
kch->job = GNUNET_CURL_job_add_with_ct_json (ctx,
|
kch->job = GNUNET_CURL_job_add_with_ct_json (ctx,
|
||||||
eh,
|
eh,
|
||||||
&handle_kyc_check_finished,
|
&handle_kyc_check_finished,
|
||||||
@ -320,7 +326,6 @@ TALER_EXCHANGE_kyc_check_cancel (struct TALER_EXCHANGE_KycCheckHandle *kch)
|
|||||||
GNUNET_CURL_job_cancel (kch->job);
|
GNUNET_CURL_job_cancel (kch->job);
|
||||||
kch->job = NULL;
|
kch->job = NULL;
|
||||||
}
|
}
|
||||||
TALER_EXCHANGE_keys_decref (kch->keys);
|
|
||||||
GNUNET_free (kch->url);
|
GNUNET_free (kch->url);
|
||||||
GNUNET_free (kch);
|
GNUNET_free (kch);
|
||||||
}
|
}
|
||||||
|
@ -506,7 +506,7 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
|||||||
const struct TALER_ContractDiffiePrivateP *contract_priv,
|
const struct TALER_ContractDiffiePrivateP *contract_priv,
|
||||||
const json_t *contract_terms,
|
const json_t *contract_terms,
|
||||||
unsigned int num_deposits,
|
unsigned int num_deposits,
|
||||||
const struct TALER_EXCHANGE_PurseDeposit deposits[static num_deposits],
|
const struct TALER_EXCHANGE_PurseDeposit *deposits,
|
||||||
bool upload_contract,
|
bool upload_contract,
|
||||||
TALER_EXCHANGE_PurseCreateDepositCallback cb,
|
TALER_EXCHANGE_PurseCreateDepositCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
|
@ -453,7 +453,7 @@ TALER_EXCHANGE_purse_deposit (
|
|||||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||||
uint8_t min_age,
|
uint8_t min_age,
|
||||||
unsigned int num_deposits,
|
unsigned int num_deposits,
|
||||||
const struct TALER_EXCHANGE_PurseDeposit deposits[static num_deposits],
|
const struct TALER_EXCHANGE_PurseDeposit *deposits,
|
||||||
TALER_EXCHANGE_PurseDepositCallback cb,
|
TALER_EXCHANGE_PurseDepositCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
|
@ -311,7 +311,7 @@ TALER_EXCHANGE_refreshes_reveal (
|
|||||||
const struct TALER_RefreshMasterSecretP *rms,
|
const struct TALER_RefreshMasterSecretP *rms,
|
||||||
const struct TALER_EXCHANGE_RefreshData *rd,
|
const struct TALER_EXCHANGE_RefreshData *rd,
|
||||||
unsigned int num_coins,
|
unsigned int num_coins,
|
||||||
const struct TALER_ExchangeWithdrawValues alg_values[static num_coins],
|
const struct TALER_ExchangeWithdrawValues *alg_values,
|
||||||
uint32_t noreveal_index,
|
uint32_t noreveal_index,
|
||||||
TALER_EXCHANGE_RefreshesRevealCallback reveal_cb,
|
TALER_EXCHANGE_RefreshesRevealCallback reveal_cb,
|
||||||
void *reveal_cb_cls)
|
void *reveal_cb_cls)
|
||||||
|
@ -229,7 +229,7 @@ TALER_EXCHANGE_reserves_attest (
|
|||||||
const char *url,
|
const char *url,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
unsigned int attributes_length,
|
unsigned int attributes_length,
|
||||||
const char *attributes[const static attributes_length],
|
const char *const*attributes,
|
||||||
TALER_EXCHANGE_ReservesPostAttestCallback cb,
|
TALER_EXCHANGE_ReservesPostAttestCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
|
@ -141,8 +141,8 @@ handle_reserves_history_ok (struct TALER_EXCHANGE_ReservesHistoryHandle *rsh,
|
|||||||
rhistory))
|
rhistory))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
if (NULL != rsh->cb)
|
if (NULL != rsh->cb)
|
||||||
@ -153,8 +153,8 @@ handle_reserves_history_ok (struct TALER_EXCHANGE_ReservesHistoryHandle *rsh,
|
|||||||
&rs);
|
&rs);
|
||||||
rsh->cb = NULL;
|
rsh->cb = NULL;
|
||||||
}
|
}
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
}
|
}
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
@ -430,8 +430,7 @@ TALER_EXCHANGE_reserves_open (
|
|||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
const struct TALER_Amount *reserve_contribution,
|
const struct TALER_Amount *reserve_contribution,
|
||||||
unsigned int coin_payments_length,
|
unsigned int coin_payments_length,
|
||||||
const struct TALER_EXCHANGE_PurseDeposit coin_payments[
|
const struct TALER_EXCHANGE_PurseDeposit *coin_payments,
|
||||||
static coin_payments_length],
|
|
||||||
struct GNUNET_TIME_Timestamp expiration_time,
|
struct GNUNET_TIME_Timestamp expiration_time,
|
||||||
uint32_t min_purses,
|
uint32_t min_purses,
|
||||||
TALER_EXCHANGE_ReservesOpenCallback cb,
|
TALER_EXCHANGE_ReservesOpenCallback cb,
|
||||||
|
@ -129,8 +129,8 @@ handle_reserves_status_ok (struct TALER_EXCHANGE_ReservesStatusHandle *rsh,
|
|||||||
rhistory))
|
rhistory))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
@ -142,8 +142,8 @@ handle_reserves_status_ok (struct TALER_EXCHANGE_ReservesStatusHandle *rsh,
|
|||||||
&rs);
|
&rs);
|
||||||
rsh->cb = NULL;
|
rsh->cb = NULL;
|
||||||
}
|
}
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
}
|
}
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,9 @@ struct TALER_EXCHANGE_WireHandle
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The keys of the exchange this request handle will use
|
* The connection to exchange this request handle will use
|
||||||
*/
|
*/
|
||||||
struct TALER_EXCHANGE_Keys *keys;
|
struct TALER_EXCHANGE_Handle *exchange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The url for this request.
|
* The url for this request.
|
||||||
@ -199,6 +199,7 @@ handle_wire_finished (void *cls,
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
wr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
wr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||||
|
wh->exchange->wire_error_count++;
|
||||||
break;
|
break;
|
||||||
case MHD_HTTP_OK:
|
case MHD_HTTP_OK:
|
||||||
{
|
{
|
||||||
@ -219,6 +220,7 @@ handle_wire_finished (void *cls,
|
|||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wh->exchange->wire_error_count = 0;
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (j,
|
GNUNET_JSON_parse (j,
|
||||||
spec,
|
spec,
|
||||||
@ -230,7 +232,11 @@ handle_wire_finished (void *cls,
|
|||||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (0 != GNUNET_memcmp (&wh->keys->master_pub,
|
{
|
||||||
|
const struct TALER_EXCHANGE_Keys *key_state;
|
||||||
|
|
||||||
|
key_state = TALER_EXCHANGE_get_keys (wh->exchange);
|
||||||
|
if (0 != GNUNET_memcmp (&key_state->master_pub,
|
||||||
&master_pub))
|
&master_pub))
|
||||||
{
|
{
|
||||||
/* bogus reply: master public key in /wire differs from that in /keys */
|
/* bogus reply: master public key in /wire differs from that in /keys */
|
||||||
@ -239,6 +245,7 @@ handle_wire_finished (void *cls,
|
|||||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wr.details.ok.accounts_len
|
wr.details.ok.accounts_len
|
||||||
= json_array_size (accounts);
|
= json_array_size (accounts);
|
||||||
@ -273,8 +280,8 @@ handle_wire_finished (void *cls,
|
|||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_EXCHANGE_parse_accounts (&master_pub,
|
TALER_EXCHANGE_parse_accounts (&master_pub,
|
||||||
accounts,
|
accounts,
|
||||||
wr.details.ok.accounts_len,
|
was,
|
||||||
was))
|
wr.details.ok.accounts_len))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
wr.hr.http_status = 0;
|
wr.hr.http_status = 0;
|
||||||
@ -286,9 +293,8 @@ handle_wire_finished (void *cls,
|
|||||||
&wr);
|
&wr);
|
||||||
wh->cb = NULL;
|
wh->cb = NULL;
|
||||||
}
|
}
|
||||||
TALER_EXCHANGE_free_accounts (
|
TALER_EXCHANGE_free_accounts (was,
|
||||||
wr.details.ok.accounts_len,
|
wr.details.ok.accounts_len);
|
||||||
was);
|
|
||||||
} /* end of 'parse accounts */
|
} /* end of 'parse accounts */
|
||||||
free_fees (fbm,
|
free_fees (fbm,
|
||||||
wr.details.ok.fees_len);
|
wr.details.ok.fees_len);
|
||||||
@ -315,6 +321,8 @@ handle_wire_finished (void *cls,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unexpected response code */
|
/* unexpected response code */
|
||||||
|
if (MHD_HTTP_GATEWAY_TIMEOUT == response_code)
|
||||||
|
wh->exchange->wire_error_count++;
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
wr.hr.ec = TALER_JSON_get_error_code (j);
|
wr.hr.ec = TALER_JSON_get_error_code (j);
|
||||||
wr.hr.hint = TALER_JSON_get_error_hint (j);
|
wr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||||
@ -331,23 +339,61 @@ handle_wire_finished (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the network timeout for the next request to /wire.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange handle
|
||||||
|
* @returns the timeout in seconds (for use by CURL)
|
||||||
|
*/
|
||||||
|
static long
|
||||||
|
get_wire_timeout_seconds (struct TALER_EXCHANGE_Handle *exchange)
|
||||||
|
{
|
||||||
|
return GNUNET_MIN (60,
|
||||||
|
5 + (1L << exchange->wire_error_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain information about a exchange's wire instructions.
|
||||||
|
* A exchange may provide wire instructions for creating
|
||||||
|
* a reserve. The wire instructions also indicate
|
||||||
|
* which wire formats merchants may use with the exchange.
|
||||||
|
* This API is typically used by a wallet for wiring
|
||||||
|
* funds, and possibly by a merchant to determine
|
||||||
|
* supported wire formats.
|
||||||
|
*
|
||||||
|
* Note that while we return the (main) response verbatim to the
|
||||||
|
* caller for further processing, we do already verify that the
|
||||||
|
* response is well-formed (i.e. that signatures included in the
|
||||||
|
* response are all valid). If the exchange's reply is not well-formed,
|
||||||
|
* we return an HTTP status code of zero to @a cb.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
|
* @param wire_cb the callback to call when a reply for this request is available
|
||||||
|
* @param wire_cb_cls closure for the above callback
|
||||||
|
* @return a handle for this request
|
||||||
|
*/
|
||||||
struct TALER_EXCHANGE_WireHandle *
|
struct TALER_EXCHANGE_WireHandle *
|
||||||
TALER_EXCHANGE_wire (
|
TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
struct GNUNET_CURL_Context *ctx,
|
|
||||||
const char *url,
|
|
||||||
struct TALER_EXCHANGE_Keys *keys,
|
|
||||||
TALER_EXCHANGE_WireCallback wire_cb,
|
TALER_EXCHANGE_WireCallback wire_cb,
|
||||||
void *wire_cb_cls)
|
void *wire_cb_cls)
|
||||||
{
|
{
|
||||||
struct TALER_EXCHANGE_WireHandle *wh;
|
struct TALER_EXCHANGE_WireHandle *wh;
|
||||||
|
struct GNUNET_CURL_Context *ctx;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
|
|
||||||
|
if (GNUNET_YES !=
|
||||||
|
TEAH_handle_is_ready (exchange))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
wh = GNUNET_new (struct TALER_EXCHANGE_WireHandle);
|
wh = GNUNET_new (struct TALER_EXCHANGE_WireHandle);
|
||||||
|
wh->exchange = exchange;
|
||||||
wh->cb = wire_cb;
|
wh->cb = wire_cb;
|
||||||
wh->cb_cls = wire_cb_cls;
|
wh->cb_cls = wire_cb_cls;
|
||||||
wh->url = TALER_url_join (url,
|
wh->url = TEAH_path_to_url (exchange,
|
||||||
"wire",
|
"/wire");
|
||||||
NULL);
|
|
||||||
if (NULL == wh->url)
|
if (NULL == wh->url)
|
||||||
{
|
{
|
||||||
GNUNET_free (wh);
|
GNUNET_free (wh);
|
||||||
@ -364,8 +410,8 @@ TALER_EXCHANGE_wire (
|
|||||||
GNUNET_break (CURLE_OK ==
|
GNUNET_break (CURLE_OK ==
|
||||||
curl_easy_setopt (eh,
|
curl_easy_setopt (eh,
|
||||||
CURLOPT_TIMEOUT,
|
CURLOPT_TIMEOUT,
|
||||||
60 /* seconds */));
|
get_wire_timeout_seconds (wh->exchange)));
|
||||||
wh->keys = TALER_EXCHANGE_keys_incref (keys);
|
ctx = TEAH_handle_to_context (exchange);
|
||||||
wh->job = GNUNET_CURL_job_add_with_ct_json (ctx,
|
wh->job = GNUNET_CURL_job_add_with_ct_json (ctx,
|
||||||
eh,
|
eh,
|
||||||
&handle_wire_finished,
|
&handle_wire_finished,
|
||||||
@ -374,9 +420,14 @@ TALER_EXCHANGE_wire (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a wire information request. This function cannot be used
|
||||||
|
* on a request handle if a response is already served for it.
|
||||||
|
*
|
||||||
|
* @param wh the wire information request handle
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_wire_cancel (
|
TALER_EXCHANGE_wire_cancel (struct TALER_EXCHANGE_WireHandle *wh)
|
||||||
struct TALER_EXCHANGE_WireHandle *wh)
|
|
||||||
{
|
{
|
||||||
if (NULL != wh->job)
|
if (NULL != wh->job)
|
||||||
{
|
{
|
||||||
@ -384,7 +435,6 @@ TALER_EXCHANGE_wire_cancel (
|
|||||||
wh->job = NULL;
|
wh->job = NULL;
|
||||||
}
|
}
|
||||||
GNUNET_free (wh->url);
|
GNUNET_free (wh->url);
|
||||||
TALER_EXCHANGE_keys_decref (wh->keys);
|
|
||||||
GNUNET_free (wh);
|
GNUNET_free (wh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,12 +202,12 @@ reserve_withdraw_payment_required (
|
|||||||
rhistory))
|
rhistory))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
TALER_EXCHANGE_free_reserve_history (len,
|
TALER_EXCHANGE_free_reserve_history (rhistory,
|
||||||
rhistory);
|
len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that funds were really insufficient */
|
/* Check that funds were really insufficient */
|
||||||
|
@ -326,8 +326,8 @@ batch_withdraw_run (void *cls,
|
|||||||
TALER_TESTING_get_exchange_url (is),
|
TALER_TESTING_get_exchange_url (is),
|
||||||
TALER_TESTING_get_keys (is),
|
TALER_TESTING_get_keys (is),
|
||||||
rp,
|
rp,
|
||||||
ws->num_coins,
|
|
||||||
wcis,
|
wcis,
|
||||||
|
ws->num_coins,
|
||||||
&reserve_batch_withdraw_cb,
|
&reserve_batch_withdraw_cb,
|
||||||
ws);
|
ws);
|
||||||
if (NULL == ws->wsh)
|
if (NULL == ws->wsh)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2021-2023 Taler Systems SA
|
Copyright (C) 2021 Taler Systems SA
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify
|
TALER is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as
|
it under the terms of the GNU General Public License as
|
||||||
@ -114,12 +114,16 @@ check_kyc_run (void *cls,
|
|||||||
const struct TALER_TESTING_Command *res_cmd;
|
const struct TALER_TESTING_Command *res_cmd;
|
||||||
const uint64_t *requirement_row;
|
const uint64_t *requirement_row;
|
||||||
const struct TALER_PaytoHashP *h_payto;
|
const struct TALER_PaytoHashP *h_payto;
|
||||||
|
struct TALER_EXCHANGE_Handle *exchange
|
||||||
|
= TALER_TESTING_get_exchange (is);
|
||||||
|
|
||||||
(void) cmd;
|
(void) cmd;
|
||||||
|
if (NULL == exchange)
|
||||||
|
return;
|
||||||
kcg->is = is;
|
kcg->is = is;
|
||||||
res_cmd = TALER_TESTING_interpreter_lookup_command (
|
res_cmd = TALER_TESTING_interpreter_lookup_command (kcg->is,
|
||||||
kcg->is,
|
kcg->
|
||||||
kcg->payment_target_reference);
|
payment_target_reference);
|
||||||
if (NULL == res_cmd)
|
if (NULL == res_cmd)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -148,10 +152,7 @@ check_kyc_run (void *cls,
|
|||||||
TALER_TESTING_interpreter_fail (kcg->is);
|
TALER_TESTING_interpreter_fail (kcg->is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
kcg->kwh = TALER_EXCHANGE_kyc_check (
|
kcg->kwh = TALER_EXCHANGE_kyc_check (exchange,
|
||||||
TALER_TESTING_interpreter_get_context (is),
|
|
||||||
TALER_TESTING_get_exchange_url (is),
|
|
||||||
TALER_TESTING_get_keys (is),
|
|
||||||
*requirement_row,
|
*requirement_row,
|
||||||
h_payto,
|
h_payto,
|
||||||
TALER_KYCLOGIC_KYC_UT_INDIVIDUAL,
|
TALER_KYCLOGIC_KYC_UT_INDIVIDUAL,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2018, 2023 Taler Systems SA
|
Copyright (C) 2018 Taler Systems SA
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it
|
TALER is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published by
|
under the terms of the GNU General Public License as published by
|
||||||
@ -191,13 +191,14 @@ wire_run (void *cls,
|
|||||||
struct TALER_TESTING_Interpreter *is)
|
struct TALER_TESTING_Interpreter *is)
|
||||||
{
|
{
|
||||||
struct WireState *ws = cls;
|
struct WireState *ws = cls;
|
||||||
|
struct TALER_EXCHANGE_Handle *exchange
|
||||||
|
= TALER_TESTING_get_exchange (is);
|
||||||
|
|
||||||
ws->cmd = cmd;
|
ws->cmd = cmd;
|
||||||
|
if (NULL == exchange)
|
||||||
|
return;
|
||||||
ws->is = is;
|
ws->is = is;
|
||||||
ws->wh = TALER_EXCHANGE_wire (
|
ws->wh = TALER_EXCHANGE_wire (exchange,
|
||||||
TALER_TESTING_interpreter_get_context (is),
|
|
||||||
TALER_TESTING_get_exchange_url (is),
|
|
||||||
TALER_TESTING_get_keys (is),
|
|
||||||
&wire_cb,
|
&wire_cb,
|
||||||
ws);
|
ws);
|
||||||
}
|
}
|
||||||
@ -227,6 +228,17 @@ wire_cleanup (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a "wire" command.
|
||||||
|
*
|
||||||
|
* @param label the command label.
|
||||||
|
* @param expected_method which wire-transfer method is expected
|
||||||
|
* to be offered by the exchange.
|
||||||
|
* @param expected_fee the fee the exchange should charge.
|
||||||
|
* @param expected_response_code the HTTP response the exchange
|
||||||
|
* should return.
|
||||||
|
* @return the command.
|
||||||
|
*/
|
||||||
struct TALER_TESTING_Command
|
struct TALER_TESTING_Command
|
||||||
TALER_TESTING_cmd_wire (const char *label,
|
TALER_TESTING_cmd_wire (const char *label,
|
||||||
const char *expected_method,
|
const char *expected_method,
|
||||||
|
Loading…
Reference in New Issue
Block a user