summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-07-13 23:07:50 +0200
committerChristian Grothoff <christian@grothoff.org>2023-07-13 23:08:23 +0200
commit86f9c6823ec9d92dfbbbc1220655c91b129020cf (patch)
treec2a21180a3b8350ab4a98644bd359139df150c8c /src/backend/taler-merchant-httpd_post-orders-ID-pay.c
parent4e45f3a965d5454b136eaf041d5d523f614343d4 (diff)
downloadmerchant-86f9c6823ec9d92dfbbbc1220655c91b129020cf.tar.gz
merchant-86f9c6823ec9d92dfbbbc1220655c91b129020cf.tar.bz2
merchant-86f9c6823ec9d92dfbbbc1220655c91b129020cf.zip
merging /keys and /wire API in the exchange
Diffstat (limited to 'src/backend/taler-merchant-httpd_post-orders-ID-pay.c')
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c208
1 files changed, 114 insertions, 94 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index 75bc4345..d4e620bd 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -176,13 +176,6 @@ struct ExchangeGroup
struct TMH_EXCHANGES_KeysOperation *fo;
/**
- * Handle for operation to lookup /wire from
- * the exchange used for this transaction; NULL if no operation is
- * pending.
- */
- struct TMH_EXCHANGES_WireOperation *gwo;
-
- /**
* URL of the exchange that issued this coin. Aliases
* the exchange URL of one of the coins, do not free!
*/
@@ -692,8 +685,6 @@ pay_context_cleanup (void *cls)
if (NULL != eg->fo)
TMH_EXCHANGES_keys4exchange_cancel (eg->fo);
- if (NULL != eg->gwo)
- TMH_EXCHANGES_wire4exchange_cancel (eg->gwo);
GNUNET_free (eg);
}
GNUNET_free (pc->egs);
@@ -785,14 +776,17 @@ deposit_get_callback (
*
* @param cls the `struct KycContext`
* @param keys NULL if exchange was not found to be acceptable
+ * @param exchange representation of the exchange
*/
static void
process_kyc_with_exchange (
void *cls,
- struct TALER_EXCHANGE_Keys *keys)
+ struct TALER_EXCHANGE_Keys *keys,
+ struct TMH_Exchange *exchange)
{
struct KycContext *kc = cls;
+ (void) exchange;
kc->fo = NULL;
if (NULL == keys)
{
@@ -922,9 +916,11 @@ check_kyc (struct PayContext *pc,
GNUNET_CONTAINER_DLL_insert (kc_head,
kc_tail,
kc);
- kc->fo = TMH_EXCHANGES_keys4exchange (kc->exchange_url,
- &process_kyc_with_exchange,
- kc);
+ kc->fo = TMH_EXCHANGES_keys4exchange (
+ kc->exchange_url,
+ false,
+ &process_kyc_with_exchange,
+ kc);
if (NULL == kc->fo)
{
GNUNET_break (0);
@@ -1146,15 +1142,26 @@ batch_deposit_cb (
/**
+ * Force re-downloading keys for @a eg.
+ *
+ * @param[in,out] eg group to re-download keys for
+ */
+static void
+force_keys (struct ExchangeGroup *eg);
+
+
+/**
* Function called with the result of our exchange keys lookup.
*
* @param cls the `struct ExchangeGroup`
* @param keys the keys of the exchange
+ * @param exchange representation of the exchange
*/
static void
process_pay_with_keys (
void *cls,
- struct TALER_EXCHANGE_Keys *keys)
+ struct TALER_EXCHANGE_Keys *keys,
+ struct TMH_Exchange *exchange)
{
struct ExchangeGroup *eg = cls;
struct PayContext *pc = eg->pc;
@@ -1178,6 +1185,62 @@ process_pay_with_keys (
return;
}
+ if (GNUNET_OK !=
+ TMH_exchange_check_debit (exchange,
+ pc->wm))
+ {
+ if (eg->tried_force_keys)
+ {
+ GNUNET_break_op (0);
+ pc->pending_at_eg--;
+ resume_pay_with_error (
+ pc,
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED,
+ NULL);
+ return;
+ }
+ eg->tried_force_keys = true;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Forcing /keys download (once) as wire method seems unsupported for debit\n");
+ eg->fo = TMH_EXCHANGES_keys4exchange (
+ eg->exchange_url,
+ true,
+ &process_pay_with_keys,
+ eg);
+ if (NULL == eg->fo)
+ {
+ GNUNET_break (0);
+ pc->pending_at_eg--;
+ resume_pay_with_error (pc,
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED,
+ "Failed to lookup exchange by URL");
+ return;
+ }
+ return;
+ }
+
+ if (GNUNET_OK !=
+ TMH_EXCHANGES_lookup_wire_fee (exchange,
+ pc->wm->wire_method,
+ &eg->wire_fee))
+ {
+ if (eg->tried_force_keys)
+ {
+ pc->pending_at_eg--;
+ GNUNET_break_op (0);
+ resume_pay_with_error (
+ pc,
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED,
+ pc->wm->wire_method);
+ return;
+ }
+ force_keys (eg);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Got wire data for %s\n",
+ eg->exchange_url);
+
/* Initiate /batch-deposit operation for all coins of
the current exchange (!) */
group_size = 0;
@@ -1198,19 +1261,25 @@ process_pay_with_keys (
&dc->cdd.h_denom_pub);
if (NULL == denom_details)
{
- pc->pending_at_eg--;
- resume_pay_with_response (
- pc,
- MHD_HTTP_BAD_REQUEST,
- TALER_MHD_MAKE_JSON_PACK (
- TALER_JSON_pack_ec (
- TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND),
- GNUNET_JSON_pack_data_auto ("h_denom_pub",
- &dc->cdd.h_denom_pub),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_object_steal (
- "exchange_keys",
- TALER_EXCHANGE_keys_to_json (keys)))));
+ if (eg->tried_force_keys)
+ {
+ GNUNET_break_op (0);
+ pc->pending_at_eg--;
+ resume_pay_with_response (
+ pc,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_MHD_MAKE_JSON_PACK (
+ TALER_JSON_pack_ec (
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND),
+ GNUNET_JSON_pack_data_auto ("h_denom_pub",
+ &dc->cdd.h_denom_pub),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_object_steal (
+ "exchange_keys",
+ TALER_EXCHANGE_keys_to_json (keys)))));
+ return;
+ }
+ force_keys (eg);
return;
}
dc->deposit_fee = denom_details->fees.deposit;
@@ -1270,6 +1339,7 @@ process_pay_with_keys (
AGE_FAIL:
if (0 < code)
{
+ GNUNET_break_op (0);
pc->pending_at_eg--;
GNUNET_free (dc->age_commitment.keys);
resume_pay_with_response (
@@ -1383,73 +1453,21 @@ AGE_FAIL:
}
-/**
- * Function called with the result of our exchange lookup.
- *
- * @param cls the `struct ExchangeGroup`
- * @param keys the keys of the exchange
- */
static void
-process_pay_with_wire (
- void *cls,
- const struct TMH_ExchangeWireDetails *wire)
+force_keys (struct ExchangeGroup *eg)
{
- struct ExchangeGroup *eg = cls;
- struct PayContext *pc = eg->pc;
- struct TMH_HandlerContext *hc = pc->hc;
- enum GNUNET_GenericReturnValue ret;
-
- eg->gwo = NULL;
- GNUNET_SCHEDULER_begin_async_scope (&hc->async_scope_id);
- if (NULL == wire)
- {
- GNUNET_break_op (0);
- pc->pending_at_eg--;
- /* FIXME: define more specific error code... */
- resume_pay_with_error (
- pc,
- TALER_EC_MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE,
- NULL);
- return;
- }
- if (GNUNET_OK !=
- TMH_exchange_check_debit (wire,
- pc->wm))
- {
- GNUNET_break_op (0);
- pc->pending_at_eg--;
- resume_pay_with_error (
- pc,
- TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED,
- NULL);
- return;
- }
- ret = TMH_EXCHANGES_lookup_wire_fee (wire,
- pc->wm->wire_method,
- &eg->wire_fee);
- if (GNUNET_OK != ret)
- {
- enum TALER_ErrorCode ec;
-
- ec = (GNUNET_NO == ret)
- ? TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED
- : TALER_EC_MERCHANT_GENERIC_EXCHANGE_WIRE_REQUEST_FAILED;
- pc->pending_at_eg--;
- GNUNET_break_op (0);
- resume_pay_with_error (
- pc,
- ec,
- pc->wm->wire_method);
- return;
- }
+ eg->tried_force_keys = true;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Got /wire for %s, now going for /keys\n",
- eg->exchange_url);
- eg->fo = TMH_EXCHANGES_keys4exchange (eg->exchange_url,
- &process_pay_with_keys,
- eg);
+ "Forcing /keys download (once) as wire fees are unknown\n");
+ eg->fo = TMH_EXCHANGES_keys4exchange (
+ eg->exchange_url,
+ true,
+ &process_pay_with_keys,
+ eg);
if (NULL == eg->fo)
{
+ struct PayContext *pc = eg->pc;
+
GNUNET_break (0);
pc->pending_at_eg--;
resume_pay_with_error (pc,
@@ -1489,12 +1507,14 @@ start_batch_deposits (struct PayContext *pc)
if (! have_coins)
continue; /* no coins left to deposit at this exchange */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Getting /wire details for %s\n",
+ "Getting /keys for %s\n",
eg->exchange_url);
- eg->gwo = TMH_EXCHANGES_wire4exchange (eg->exchange_url,
- &process_pay_with_wire,
- eg);
- if (NULL == eg->gwo)
+ eg->fo = TMH_EXCHANGES_keys4exchange (
+ eg->exchange_url,
+ false,
+ &process_pay_with_keys,
+ eg);
+ if (NULL == eg->fo)
{
GNUNET_break (0);
resume_pay_with_error (pc,