diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-07-02 17:28:35 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-07-02 17:28:35 +0200 |
commit | 4e73e59e1cc8d0934c651bba7c2b99f8ac5dc92b (patch) | |
tree | 11de318985c82f4e3b1fc69153613666557156d6 /src | |
parent | 3408486b5ba1752e589bec2ba592dcdb638c8be9 (diff) |
-refactoring towards batch deposits
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-pay.c | 179 |
1 files changed, 94 insertions, 85 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 690a1921..82419668 100644 --- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c +++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c @@ -58,6 +58,7 @@ */ struct PayContext; + /** * Information kept during a pay request for each coin. */ @@ -81,15 +82,9 @@ struct DepositConfirmation char *exchange_url; /** - * Hash of the denomination of this coin. + * Details about the coin being deposited. */ - struct TALER_DenominationHashP h_denom; - - /** - * Amount this coin contributes to the total purchase price. - * This amount includes the deposit fee. - */ - struct TALER_Amount amount_with_fee; + struct TALER_EXCHANGE_CoinDepositDetail cdd; /** * Fee charged by the exchange for the deposit operation of this coin. @@ -107,21 +102,6 @@ struct DepositConfirmation struct TALER_Amount wire_fee; /** - * Public key of the coin. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Signature using the @e denom key over the @e coin_pub. - */ - struct TALER_DenominationSignature ub_sig; - - /** - * Signature of the coin's private key over the contract. - */ - struct TALER_CoinSpendSignatureP coin_sig; - - /** * If a minimum age was required (i. e. pc->minimum_age is large enough), * this is the signature of the minimum age (as a single uint8_t), using the * private key to the corresponding age group. Might be all zeroes for no @@ -129,9 +109,6 @@ struct DepositConfirmation */ struct TALER_AgeAttestation minimum_age_sig; - /* true, if no field "minimum_age_sig" was found in the JSON blob */ - bool no_minimum_age_sig; - /** * If a minimum age was required (i. e. pc->minimum_age is large enough), * this is the age commitment (i. e. age mask and vector of EdDSA public @@ -141,20 +118,6 @@ struct DepositConfirmation */ struct TALER_AgeCommitment age_commitment; - /* true, if no field "age_commitment" was found in the JSON blob */ - bool no_age_commitment; - - /** - * In the case that somebody pays with a coin that is age restricted, but the - * the contract did not ask for a minimum age, the merchant still needs the - * hash of the age commitment in order to a) verify the coin and b) deposit - * it. - */ - struct TALER_AgeCommitmentHash h_age_commitment; - - /* true, if no field "h_age_commitment" was found in the JSON blob */ - bool no_h_age_commitment; - /** * Age mask in the denomination that defines the age groups. Only * applicable, if minimum age was required. @@ -168,6 +131,21 @@ struct DepositConfirmation unsigned int index; /** + * true, if no field "age_commitment" was found in the JSON blob + */ + bool no_age_commitment; + + /** + * True, if no field "minimum_age_sig" was found in the JSON blob + */ + bool no_minimum_age_sig; + + /** + * true, if no field "h_age_commitment" was found in the JSON blob + */ + bool no_h_age_commitment; + + /** * true if we found this coin in the database. */ bool found_in_db; @@ -181,6 +159,33 @@ struct DepositConfirmation /** + * Information kept during a pay request for each exchange. + */ +struct ExchangeGroup +{ + + /** + * Handle to the batch deposit operation we are performing for this + * exchange, NULL after the operation is done. + */ + struct TALER_EXCHANGE_BatchDepositHandle *bdh; + + /** + * Handle for operation to lookup /keys (and auditors) from + * the exchange used for this transaction; NULL if no operation is + * pending. + */ + struct TMH_EXCHANGES_FindOperation *fo; + + /** + * URL of the exchange that issued this coin. + */ + char *exchange_url; + +}; + + +/** * Information we keep for an individual call to the /pay handler. */ struct PayContext @@ -197,6 +202,12 @@ struct PayContext struct PayContext *prev; /** + * Array with @e num_exchange exchanges we are depositing + * coins into. + */ + struct ExchangeGroup *eg; + + /** * Array with @e coins_cnt coins we are despositing. */ struct DepositConfirmation *dc; @@ -307,11 +318,6 @@ struct PayContext struct TALER_Amount max_wire_fee; /** - * Minimum age required for this purchase. - */ - unsigned int minimum_age; - - /** * Amount from @e root. This is the amount the merchant expects * to make, minus @e max_fee. */ @@ -368,12 +374,23 @@ struct PayContext uint32_t wire_fee_amortization; /** + * Minimum age required for this purchase. + */ + unsigned int minimum_age; + + /** * Number of coins this payment is made of. Length * of the @e dc array. */ unsigned int coins_cnt; /** + * Number of exchanges involved in the payment. Length + * of the @e eg array. + */ + unsigned int num_exchanges; + + /** * How often have we retried the 'main' transaction? */ unsigned int retry_counter; @@ -678,7 +695,7 @@ pay_context_cleanup (void *cls) { struct DepositConfirmation *dc = &pc->dc[i]; - TALER_denom_sig_free (&dc->ub_sig); + TALER_denom_sig_free (&dc->cdd.denom_sig); GNUNET_free (dc->exchange_url); } GNUNET_free (pc->dc); @@ -904,7 +921,7 @@ check_kyc (struct PayContext *pc, kc->wm = pc->wm; kc->exchange_url = GNUNET_strdup (dc->exchange_url); kc->h_contract_terms = pc->h_contract_terms; - kc->coin_pub = dc->coin_pub; + kc->coin_pub = dc->cdd.coin_pub; GNUNET_CONTAINER_DLL_insert (kc_head, kc_tail, kc); @@ -965,9 +982,9 @@ deposit_cb (void *cls, pc->hc->instance->settings.id, dr->details.success.deposit_timestamp, &pc->h_contract_terms, - &dc->coin_pub, + &dc->cdd.coin_pub, dc->exchange_url, - &dc->amount_with_fee, + &dc->cdd.amount, &dc->deposit_fee, &dc->refund_fee, &dc->wire_fee, @@ -1045,7 +1062,7 @@ deposit_cb (void *cls, TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS), TMH_pack_exchange_reply (&dr->hr), GNUNET_JSON_pack_data_auto ("coin_pub", - &dc->coin_pub))); + &dc->cdd.coin_pub))); return; } resume_pay_with_response ( @@ -1056,7 +1073,7 @@ deposit_cb (void *cls, TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS), TMH_pack_exchange_reply (&dr->hr), GNUNET_JSON_pack_data_auto ("coin_pub", - &dc->coin_pub))); + &dc->cdd.coin_pub))); return; } /* end switch */ } @@ -1143,7 +1160,7 @@ process_pay_with_exchange ( continue; denom_details = TALER_EXCHANGE_get_denomination_key_by_hash (keys, - &dc->h_denom); + &dc->cdd.h_denom_pub); if (NULL == denom_details) { if (! pc->tried_force_keys) @@ -1167,7 +1184,7 @@ process_pay_with_exchange ( TALER_JSON_pack_ec ( TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND), GNUNET_JSON_pack_data_auto ("h_denom_pub", - &dc->h_denom), + &dc->cdd.h_denom_pub), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ( "exchange_keys", @@ -1259,7 +1276,7 @@ AGE_FAIL: /* Age restriction successfully verified! * Calculate the hash of the age commitment. */ TALER_age_commitment_hash (&dc->age_commitment, - &dc->h_age_commitment); + &dc->cdd.h_age_commitment); GNUNET_free (dc->age_commitment.keys); } else if (is_age_restricted_denom) @@ -1289,14 +1306,6 @@ AGE_FAIL: GNUNET_assert (NULL != pc->wm); TMH_db->preflight (TMH_db->cls); { - struct TALER_EXCHANGE_CoinDepositDetail cdd = { - .amount = dc->amount_with_fee, - .coin_pub = dc->coin_pub, - .coin_sig = dc->coin_sig, - .denom_sig = dc->ub_sig, - .h_denom_pub = denom_details->h_key, - .h_age_commitment = dc->h_age_commitment - }; struct TALER_EXCHANGE_DepositContractDetail dcd = { .wire_deadline = pc->wire_transfer_deadline, .merchant_payto_uri = pc->wm->payto_uri, @@ -1310,7 +1319,7 @@ AGE_FAIL: dc->dh = TALER_EXCHANGE_deposit (exchange_handle, &dcd, - &cdd, + &dc->cdd, &deposit_cb, dc, &ec); @@ -1409,12 +1418,12 @@ check_coin_paid (void *cls, continue; /* processed earlier, skip "expensive" memcmp() */ /* Get matching coin from results*/ if ( (0 != GNUNET_memcmp (coin_pub, - &dc->coin_pub)) || + &dc->cdd.coin_pub)) || (0 != strcmp (exchange_url, dc->exchange_url)) || (0 != TALER_amount_cmp (amount_with_fee, - &dc->amount_with_fee)) ) + &dc->cdd.amount)) ) continue; /* does not match, skip */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deposit of coin `%s' already in our DB.\n", @@ -1431,7 +1440,7 @@ check_coin_paid (void *cls, dc->deposit_fee = *deposit_fee; dc->refund_fee = *refund_fee; dc->wire_fee = *wire_fee; - dc->amount_with_fee = *amount_with_fee; + dc->cdd.amount = *amount_with_fee; dc->found_in_db = true; pc->pending--; } @@ -1469,7 +1478,7 @@ check_coin_refunded (void *cls, /* Get matching coins from results. */ if (0 != GNUNET_memcmp (coin_pub, - &dc->coin_pub)) + &dc->cdd.coin_pub)) continue; GNUNET_assert (0 <= TALER_amount_add (&pc->total_refunded, @@ -1506,7 +1515,7 @@ check_payment_sufficient (struct PayContext *pc) acc_fee = pc->dc[0].deposit_fee; total_wire_fee = pc->dc[0].wire_fee; - acc_amount = pc->dc[0].amount_with_fee; + acc_amount = pc->dc[0].cdd.amount; /** * This loops calculates what are the deposit fee / total @@ -1523,7 +1532,7 @@ check_payment_sufficient (struct PayContext *pc) &acc_fee)) || (0 > TALER_amount_add (&acc_amount, - &dc->amount_with_fee, + &dc->cdd.amount, &acc_amount)) ) { GNUNET_break (0); @@ -1536,7 +1545,7 @@ check_payment_sufficient (struct PayContext *pc) } if (1 == TALER_amount_cmp (&dc->deposit_fee, - &dc->amount_with_fee)) + &dc->cdd.amount)) { GNUNET_break_op (0); resume_pay_with_error (pc, @@ -2100,16 +2109,16 @@ parse_pay (struct PayContext *pc) const char *exchange_url; struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ("coin_sig", - &dc->coin_sig), + &dc->cdd.coin_sig), GNUNET_JSON_spec_fixed_auto ("coin_pub", - &dc->coin_pub), + &dc->cdd.coin_pub), TALER_JSON_spec_denom_sig ("ub_sig", - &dc->ub_sig), + &dc->cdd.denom_sig), GNUNET_JSON_spec_fixed_auto ("h_denom", - &dc->h_denom), + &dc->cdd.h_denom_pub), TALER_JSON_spec_amount ("contribution", TMH_currency, - &dc->amount_with_fee), + &dc->cdd.amount), GNUNET_JSON_spec_string ("exchange_url", &exchange_url), /* if a minimum age was required, the minimum_age_sig and @@ -2126,7 +2135,7 @@ parse_pay (struct PayContext *pc) * was used, h_age_commitment must be provided. */ GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_fixed_auto ("h_age_commitment", - &dc->h_age_commitment), + &dc->cdd.h_age_commitment), &dc->no_h_age_commitment), GNUNET_JSON_spec_end () }; @@ -2145,8 +2154,8 @@ parse_pay (struct PayContext *pc) for (unsigned int j = 0; j<coins_index; j++) { if (0 == - GNUNET_memcmp (&dc->coin_pub, - &pc->dc[j].coin_pub)) + GNUNET_memcmp (&dc->cdd.coin_pub, + &pc->dc[j].cdd.coin_pub)) { GNUNET_break_op (0); return (MHD_YES == @@ -2164,7 +2173,7 @@ parse_pay (struct PayContext *pc) dc->pc = pc; if (0 != - strcasecmp (dc->amount_with_fee.currency, + strcasecmp (dc->cdd.amount.currency, TMH_currency)) { GNUNET_break_op (0); @@ -2231,13 +2240,13 @@ deposit_paid_check ( struct DepositConfirmation *dci = &pc->dc[i]; if ( (0 == - GNUNET_memcmp (&dci->coin_pub, + GNUNET_memcmp (&dci->cdd.coin_pub, coin_pub)) && (0 == strcmp (dci->exchange_url, exchange_url)) && (0 == - TALER_amount_cmp (&dci->amount_with_fee, + TALER_amount_cmp (&dci->cdd.amount, amount_with_fee)) ) { dci->matched_in_db = true; @@ -2317,10 +2326,10 @@ handle_contract_paid (struct PayContext *pc) if (dci->matched_in_db) continue; - TALER_merchant_refund_sign (&dci->coin_pub, + TALER_merchant_refund_sign (&dci->cdd.coin_pub, &pc->h_contract_terms, 0, /* rtransaction id */ - &dci->amount_with_fee, + &dci->cdd.amount, &pc->hc->instance->merchant_priv, &merchant_sig); GNUNET_assert ( @@ -2330,12 +2339,12 @@ handle_contract_paid (struct PayContext *pc) GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ( "coin_pub", - &dci->coin_pub), + &dci->cdd.coin_pub), GNUNET_JSON_pack_data_auto ( "merchant_sig", &merchant_sig), TALER_JSON_pack_amount ("amount", - &dci->amount_with_fee), + &dci->cdd.amount), GNUNET_JSON_pack_uint64 ("rtransaction_id", 0)))); } |