diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-07-13 23:07:50 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-07-13 23:08:23 +0200 |
commit | 86f9c6823ec9d92dfbbbc1220655c91b129020cf (patch) | |
tree | c2a21180a3b8350ab4a98644bd359139df150c8c /src/backend/taler-merchant-httpd_post-orders-ID-pay.c | |
parent | 4e45f3a965d5454b136eaf041d5d523f614343d4 (diff) | |
download | merchant-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.c | 208 |
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, |