From 6d6f2ef35ffa2eabf9784b29c6e5c02b87ec3712 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 4 Jun 2023 01:15:37 +0200 Subject: fix another FIXME --- src/include/taler_merchant_service.h | 50 ++++++++++++++++++++----- src/lib/merchant_api_tip_pickup.c | 36 +++++++----------- src/lib/merchant_api_tip_pickup2.c | 72 +++++++++++++++++++----------------- 3 files changed, 93 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h index f936d54e..dcd936e7 100644 --- a/src/include/taler_merchant_service.h +++ b/src/include/taler_merchant_service.h @@ -4654,23 +4654,55 @@ TALER_MERCHANT_tip_pickup_cancel (struct TALER_MERCHANT_TipPickupHandle *tph); struct TALER_MERCHANT_TipPickup2Handle; -// FIXME: change signature! +/** + * Response for a POST /tips/$TIP_ID/pickup request. + */ +struct TALER_MERCHANT_TipPickup2Response +{ + /** + * HTTP response details + */ + struct TALER_MERCHANT_HttpResponse hr; + + /** + * Details depending on status. + */ + union + { + + /** + * Details if status is #MHD_HTTP_OK. + */ + struct + { + + /** + * length of the @a blind_sigs array + */ + unsigned int num_blind_sigs; + + /** + * array of blind signatures over the planchets + */ + const struct TALER_BlindedDenominationSignature *blind_sigs; + + } ok; + + } details; +}; + + /** * Callback for a POST /tips/$TIP_ID/pickup request. Returns the result of - * the operation. Note that the client MUST still do the unblinding of the @a - * blind_sigs. + * the operation. Note that the client MUST still do the unblinding. * * @param cls closure - * @param hr HTTP response details - * @param num_blind_sigs length of the @a blind_sigs array, 0 on error - * @param blind_sigs array of blind signatures over the planchets, NULL on error + * @param tpr response details */ typedef void (*TALER_MERCHANT_TipPickup2Callback) ( void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int num_blind_sigs, - const struct TALER_BlindedDenominationSignature blind_sigs[]); + const struct TALER_MERCHANT_TipPickup2Response *tpr); /** diff --git a/src/lib/merchant_api_tip_pickup.c b/src/lib/merchant_api_tip_pickup.c index 75ec2d6c..cd1f2035 100644 --- a/src/lib/merchant_api_tip_pickup.c +++ b/src/lib/merchant_api_tip_pickup.c @@ -159,23 +159,19 @@ fail_pickup (struct TALER_MERCHANT_TipPickupHandle *tp, * Note that the client MUST still do the unblinding of the @a blind_sigs. * * @param cls closure, a `struct TALER_MERCHANT_TipPickupHandle *` - * @param hr HTTP response details - * @param num_blind_sigs length of the @a reserve_sigs array, 0 on error - * @param blind_sigs array of blind signatures over the planchets, NULL on error + * @param tpr response details */ static void pickup_done_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int num_blind_sigs, - const struct TALER_BlindedDenominationSignature *blind_sigs) + const struct TALER_MERCHANT_TipPickup2Response *tpr) { struct TALER_MERCHANT_TipPickupHandle *tp = cls; struct TALER_MERCHANT_PickupDetails pd = { - .hr = *hr + .hr = tpr->hr }; tp->tpo2 = NULL; - if (NULL == blind_sigs) + if (MHD_HTTP_OK != tpr->hr.http_status) { tp->cb (tp->cb_cls, &pd); @@ -185,14 +181,17 @@ pickup_done_cb (void *cls, { enum GNUNET_GenericReturnValue ok = GNUNET_OK; - for (unsigned int i = 0; idetails.ok.num_blind_sigs; i++) { - struct TALER_EXCHANGE_PrivateCoinDetails *pcd = &tp->pcds[i]; + const struct TALER_BlindedDenominationSignature *blind_sig + = &tpr->details.ok.blind_sigs[i]; + struct TALER_EXCHANGE_PrivateCoinDetails *pcd + = &tp->pcds[i]; struct TALER_FreshCoin fc; if (GNUNET_OK != TALER_planchet_to_coin (&tp->planchets[i].pk.key, - &blind_sigs[i], + blind_sig, &pcd->bks, &pcd->coin_priv, NULL, @@ -207,22 +206,15 @@ pickup_done_cb (void *cls, } if (GNUNET_OK != ok) { - struct TALER_MERCHANT_HttpResponse hrx = { - .reply = hr->reply, - .ec = TALER_EC_MERCHANT_TIP_PICKUP_UNBLIND_FAILURE - }; - - pd.hr = hrx; - tp->cb (tp->cb_cls, - &pd); + pd.hr.ec = TALER_EC_MERCHANT_TIP_PICKUP_UNBLIND_FAILURE; } else { - pd.details.ok.num_sigs = num_blind_sigs; + pd.details.ok.num_sigs = tpr->details.ok.num_blind_sigs; pd.details.ok.pcds = tp->pcds; - tp->cb (tp->cb_cls, - &pd); } + tp->cb (tp->cb_cls, + &pd); } TALER_MERCHANT_tip_pickup_cancel (tp); } diff --git a/src/lib/merchant_api_tip_pickup2.c b/src/lib/merchant_api_tip_pickup2.c index 33457024..9cb5a496 100644 --- a/src/lib/merchant_api_tip_pickup2.c +++ b/src/lib/merchant_api_tip_pickup2.c @@ -83,23 +83,22 @@ struct TALER_MERCHANT_TipPickup2Handle * call the callback (and set it to NULL afterwards). * * @param tpo handle of the original authorization operation + * @param[in] tpr response to complete * @param json cryptographic proof returned by the exchange/merchant * @return #GNUNET_OK if response is valid */ -static int +static enum GNUNET_GenericReturnValue check_ok (struct TALER_MERCHANT_TipPickup2Handle *tpo, + struct TALER_MERCHANT_TipPickup2Response *tpr, const json_t *json) { - json_t *ja; + const json_t *ja; unsigned int ja_len; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("blind_sigs", &ja), + GNUNET_JSON_spec_array_const ("blind_sigs", + &ja), GNUNET_JSON_spec_end () }; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = MHD_HTTP_OK, - .reply = json - }; if (GNUNET_OK != GNUNET_JSON_parse (json, @@ -117,11 +116,12 @@ check_ok (struct TALER_MERCHANT_TipPickup2Handle *tpo, return GNUNET_SYSERR; } { - struct TALER_BlindedDenominationSignature mblind_sigs[ja_len]; + struct TALER_BlindedDenominationSignature mblind_sigs[GNUNET_NZL (ja_len)]; for (unsigned int i = 0; idetails.ok.num_blind_sigs = ja_len; + tpr->details.ok.blind_sigs = mblind_sigs; tpo->cb (tpo->cb_cls, - &hr, - ja_len, - mblind_sigs); + tpr); + tpo->cb = NULL; /* do not call twice */ for (unsigned int i = 0; icb = NULL; /* do not call twice */ } GNUNET_JSON_parse_free (spec); return GNUNET_OK; @@ -166,64 +168,65 @@ handle_tip_pickup_finished (void *cls, { struct TALER_MERCHANT_TipPickup2Handle *tpo = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_TipPickup2Response tpr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; tpo->job = NULL; switch (response_code) { case MHD_HTTP_OK: - if (GNUNET_OK != check_ok (tpo, - json)) + if (GNUNET_OK != + check_ok (tpo, + &tpr, + json)) { GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + tpr.hr.http_status = 0; + tpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; } break; case MHD_HTTP_BAD_REQUEST: /* Can happen if we pickup an amount that exceeds the tip... */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_break (TALER_EC_MERCHANT_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING == - hr.ec); + tpr.hr.ec); break; case MHD_HTTP_CONFLICT: /* legal, can happen if we pickup a tip twice... */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: /* legal, can happen if tip ID is unknown */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); + &tpr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) tpr.hr.ec); break; } if (NULL != tpo->cb) { tpo->cb (tpo->cb_cls, - &hr, - 0, - NULL); + &tpr); tpo->cb = NULL; } TALER_MERCHANT_tip_pickup2_cancel (tpo); @@ -250,6 +253,7 @@ TALER_MERCHANT_tip_pickup2 (struct GNUNET_CURL_Context *ctx, return NULL; } pa = json_array (); + GNUNET_assert (NULL != pa); for (unsigned int i = 0; i