From 1d7a2a33c56e0157472d2625b1c2deb6f5a98a02 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 1 May 2020 19:22:32 +0200 Subject: fix status code --- src/lib/exchange_api_common.c | 34 ++++++++++++++++------------------ src/lib/exchange_api_deposit.c | 4 ++-- src/lib/exchange_api_handle.c | 2 +- src/lib/exchange_api_refund.c | 21 ++++++--------------- src/lib/exchange_api_withdraw2.c | 2 -- 5 files changed, 25 insertions(+), 38 deletions(-) (limited to 'src/lib') diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index 07f5e1873..dc44291d0 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -146,11 +146,12 @@ TALER_EXCHANGE_parse_reserve_history ( { struct TALER_ReserveSignatureP sig; struct TALER_WithdrawRequestPS withdraw_purpose; + struct TALER_Amount withdraw_fee; struct GNUNET_JSON_Specification withdraw_spec[] = { GNUNET_JSON_spec_fixed_auto ("reserve_sig", &sig), - TALER_JSON_spec_amount_nbo ("withdraw_fee", - &withdraw_purpose.withdraw_fee), + TALER_JSON_spec_amount ("withdraw_fee", + &withdraw_fee), GNUNET_JSON_spec_fixed_auto ("h_denom_pub", &withdraw_purpose.h_denomination_pub), GNUNET_JSON_spec_fixed_auto ("h_coin_envelope", @@ -189,26 +190,23 @@ TALER_EXCHANGE_parse_reserve_history ( { const struct TALER_EXCHANGE_Keys *key_state; const struct TALER_EXCHANGE_DenomPublicKey *dki; - struct TALER_Amount fee; key_state = TALER_EXCHANGE_get_keys (exchange); dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state, &withdraw_purpose. h_denomination_pub); - TALER_amount_ntoh (&fee, - &withdraw_purpose.withdraw_fee); if ( (GNUNET_YES != - TALER_amount_cmp_currency (&fee, + TALER_amount_cmp_currency (&withdraw_fee, &dki->fee_withdraw)) || (0 != - TALER_amount_cmp (&fee, + TALER_amount_cmp (&withdraw_fee, &dki->fee_withdraw)) ) { GNUNET_break_op (0); GNUNET_JSON_parse_free (withdraw_spec); return GNUNET_SYSERR; } - rh->details.withdraw.fee = fee; + rh->details.withdraw.fee = withdraw_fee; } rh->details.withdraw.out_authorization_sig = json_object_get (transaction, @@ -634,9 +632,16 @@ TALER_EXCHANGE_verify_coin_history ( else if (0 == strcasecmp (type, "REFUND")) { - struct TALER_RefundRequestPS rr; struct TALER_MerchantSignatureP sig; + struct TALER_Amount refund_fee; + struct TALER_RefundRequestPS rr = { + .purpose.size = htonl (sizeof (rr)), + .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND), + .coin_pub = *coin_pub + }; struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount ("refund_fee", + &refund_fee), GNUNET_JSON_spec_fixed_auto ("merchant_sig", &sig), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", @@ -645,8 +650,6 @@ TALER_EXCHANGE_verify_coin_history ( &rr.merchant), GNUNET_JSON_spec_uint64 ("rtransaction_id", &rr.rtransaction_id), - TALER_JSON_spec_amount_nbo ("refund_fee", - &rr.refund_fee), GNUNET_JSON_spec_end () }; @@ -658,9 +661,6 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_break_op (0); return GNUNET_SYSERR; } - rr.purpose.size = htonl (sizeof (rr)); - rr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND); - rr.coin_pub = *coin_pub; TALER_amount_hton (&rr.refund_amount, &amount); if (GNUNET_OK != @@ -683,13 +683,11 @@ TALER_EXCHANGE_verify_coin_history ( /* check that refund fee matches our expectations from /keys! */ if (NULL != dk) { - TALER_amount_ntoh (&fee, - &rr.refund_fee); if ( (GNUNET_YES != - TALER_amount_cmp_currency (&fee, + TALER_amount_cmp_currency (&refund_fee, &dk->fee_refund)) || (0 != - TALER_amount_cmp (&fee, + TALER_amount_cmp (&refund_fee, &dk->fee_refund)) ) { GNUNET_break_op (0); diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 5f3749931..a5cf6c36a 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -196,8 +196,8 @@ verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh, { const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("sig", exchange_sig), - GNUNET_JSON_spec_fixed_auto ("pub", exchange_pub), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), GNUNET_JSON_spec_end () }; diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index c3ae16633..c9c1b09bd 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -39,7 +39,7 @@ * Which version of the Taler protocol is implemented * by this library? Used to determine compatibility. */ -#define EXCHANGE_PROTOCOL_CURRENT 7 +#define EXCHANGE_PROTOCOL_CURRENT 8 /** * How many versions are we backwards compatible with? diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index c64dcc97a..9cb8794d3 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -81,14 +81,14 @@ struct TALER_EXCHANGE_RefundHandle * Verify that the signature on the "200 OK" response * from the exchange is valid. * - * @param rh refund handle + * @param[in,out] rh refund handle (refund fee added) * @param json json reply with the signature * @param[out] exchange_pub set to the exchange's public key * @param[out] exchange_sig set to the exchange's signature * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int -verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, +verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh, const json_t *json, struct TALER_ExchangePublicKeyP *exchange_pub, struct TALER_ExchangeSignatureP *exchange_sig) @@ -96,8 +96,9 @@ verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, { const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("sig", exchange_sig), - GNUNET_JSON_spec_fixed_auto ("pub", exchange_pub), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), + TALER_JSON_spec_amount_nbo ("refund_fee", &rh->depconf.refund_fee), GNUNET_JSON_spec_end () }; @@ -256,7 +257,6 @@ handle_refund_finished (void *cls, * @param amount the amount to be refunded; must be larger than the refund fee * (as that fee is still being subtracted), and smaller than the amount * (with deposit fee) of the original deposit contribution of this coin - * @param refund_fee fee applicable to this coin for the refund * @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded * @param coin_pub coin’s public key of the coin from the original deposit operation * @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation); @@ -272,7 +272,6 @@ handle_refund_finished (void *cls, struct TALER_EXCHANGE_RefundHandle * TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_Amount *amount, - const struct TALER_Amount *refund_fee, const struct GNUNET_HashCode *h_contract_terms, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t rtransaction_id, @@ -294,14 +293,11 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, rr.rtransaction_id = GNUNET_htonll (rtransaction_id); TALER_amount_hton (&rr.refund_amount, amount); - TALER_amount_hton (&rr.refund_fee, - refund_fee); GNUNET_CRYPTO_eddsa_sign (&merchant_priv->eddsa_priv, &rr, &merchant_sig.eddsa_sig); return TALER_EXCHANGE_refund2 (exchange, amount, - refund_fee, h_contract_terms, coin_pub, rtransaction_id, @@ -329,7 +325,6 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, * @param amount the amount to be refunded; must be larger than the refund fee * (as that fee is still being subtracted), and smaller than the amount * (with deposit fee) of the original deposit contribution of this coin - * @param refund_fee fee applicable to this coin for the refund * @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded * @param coin_pub coin’s public key of the coin from the original deposit operation * @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation); @@ -346,7 +341,6 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, struct TALER_EXCHANGE_RefundHandle * TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_Amount *amount, - const struct TALER_Amount *refund_fee, const struct GNUNET_HashCode *h_contract_terms, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t rtransaction_id, @@ -376,12 +370,11 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, "/coins/%s/refund", pub_str); } - refund_obj = json_pack ("{s:o, s:o," /* amount/fee */ + refund_obj = json_pack ("{s:o," /* amount */ " s:o," /* h_contract_terms */ " s:I," /* rtransaction id */ " s:o, s:o}", /* merchant_pub, merchant_sig */ "refund_amount", TALER_JSON_from_amount (amount), - "refund_fee", TALER_JSON_from_amount (refund_fee), "h_contract_terms", GNUNET_JSON_from_data_auto ( h_contract_terms), "rtransaction_id", (json_int_t) rtransaction_id, @@ -410,8 +403,6 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, rh->depconf.rtransaction_id = GNUNET_htonll (rtransaction_id); TALER_amount_hton (&rh->depconf.refund_amount, amount); - TALER_amount_hton (&rh->depconf.refund_fee, - refund_fee); eh = TALER_EXCHANGE_curl_easy_get_ (rh->url); if ( (NULL == eh) || diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c index f9468927a..25f669143 100644 --- a/src/lib/exchange_api_withdraw2.c +++ b/src/lib/exchange_api_withdraw2.c @@ -429,8 +429,6 @@ TALER_EXCHANGE_withdraw2 ( TALER_amount_hton (&req.amount_with_fee, &wh->requested_amount); - TALER_amount_hton (&req.withdraw_fee, - &dk->fee_withdraw); GNUNET_CRYPTO_hash (pd->coin_ev, pd->coin_ev_size, &req.h_coin_envelope); -- cgit v1.2.3 From 1038107e6374ac42e6ae7f6ec41daf0cf206f709 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 3 May 2020 19:54:36 +0200 Subject: update exchange API to return struct instead of lots of individual args for TALER_EXCHANGE_transfers_get() -- simplifies merchant later --- src/include/taler_exchange_service.h | 72 ++++++++++--- src/lib/exchange_api_transfers_get.c | 164 ++++++++++++++--------------- src/testing/testing_api_cmd_transfer_get.c | 33 ++---- 3 files changed, 140 insertions(+), 129 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index a57a2655a..307a76de8 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1580,32 +1580,68 @@ TALER_EXCHANGE_link_cancel (struct TALER_EXCHANGE_LinkHandle *lh); struct TALER_EXCHANGE_TransfersGetHandle; +/** + * Information the exchange returns per wire transfer. + */ +struct TALER_EXCHANGE_TransferData +{ + + /** + * exchange key used to sign + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * exchange signature over the transfer data + */ + struct TALER_ExchangeSignatureP exchange_sig; + + /** + * hash of the wire transfer address the transfer went to + */ + struct GNUNET_HashCode h_wire; + + /** + * time when the exchange claims to have performed the wire transfer + */ + struct GNUNET_TIME_Absolute execution_time; + + /** + * amount of the wire transfer + */ + struct TALER_Amount total_amount; + + /** + * wire fee that was charged by the exchange + */ + struct TALER_Amount wire_fee; + + /** + * length of the @e details array + */ + unsigned int details_length; + + /** + * array with details about the combined transactions + */ + const struct TALER_TrackTransferDetails *details; + +}; + + /** * Function called with detailed wire transfer data, including all * of the coin transactions that were combined into the wire transfer. * * @param cls closure * @param hr HTTP response data - * @param sign_key exchange key used to sign @a json, or NULL - * @param h_wire hash of the wire transfer address the transfer went to, or NULL on error - * @param execution_time time when the exchange claims to have performed the wire transfer - * @param total_amount total amount of the wire transfer, or NULL if the exchange could - * not provide any @a wtid (set only if @a http_status is #MHD_HTTP_OK) - * @param wire_fee wire fee that was charged by the exchange - * @param details_length length of the @a details array - * @param details array with details about the combined transactions + * @param ta transfer data, (set only if @a http_status is #MHD_HTTP_OK, otherwise NULL) */ typedef void (*TALER_EXCHANGE_TransfersGetCallback)( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *sign_key, - const struct GNUNET_HashCode *h_wire, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *total_amount, - const struct TALER_Amount *wire_fee, - unsigned int details_length, - const struct TALER_TrackTransferDetails *details); + const struct TALER_EXCHANGE_TransferData *ta); /** @@ -1651,17 +1687,19 @@ struct TALER_EXCHANGE_DepositGetHandle; * * @param cls closure * @param hr HTTP response data - * @param sign_key exchange key used to sign @a json, or NULL + * @param exchange_pub exchange key used to sign @a json, or NULL * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not * yet execute the transaction * @param execution_time actual or planned execution time for the wire transfer * @param coin_contribution contribution to the total amount by this coin (can be NULL) + * // FIXME: also return the exchange signature + * // FIXME: combine all of the above (except cls,hr) into a 'struct'! => DepositData */ typedef void (*TALER_EXCHANGE_DepositGetCallback)( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *sign_key, + const struct TALER_ExchangePublicKeyP *exchange_pub, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute execution_time, const struct TALER_Amount *coin_contribution); diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c index 552536958..dd9b64467 100644 --- a/src/lib/exchange_api_transfers_get.c +++ b/src/lib/exchange_api_transfers_get.c @@ -85,24 +85,18 @@ check_transfers_get_response_ok ( const json_t *json) { json_t *details_j; - struct GNUNET_HashCode h_wire; - struct GNUNET_TIME_Absolute exec_time; - struct TALER_Amount total_amount; + struct TALER_EXCHANGE_TransferData td; struct TALER_Amount total_expected; - struct TALER_Amount wire_fee; struct TALER_MerchantPublicKeyP merchant_pub; - unsigned int num_details; - struct TALER_ExchangePublicKeyP exchange_pub; - struct TALER_ExchangeSignatureP exchange_sig; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount ("total", &total_amount), - TALER_JSON_spec_amount ("wire_fee", &wire_fee), + TALER_JSON_spec_amount ("total", &td.total_amount), + TALER_JSON_spec_amount ("wire_fee", &td.wire_fee), GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub), - GNUNET_JSON_spec_fixed_auto ("h_wire", &h_wire), - GNUNET_JSON_spec_absolute_time ("execution_time", &exec_time), + GNUNET_JSON_spec_fixed_auto ("h_wire", &td.h_wire), + GNUNET_JSON_spec_absolute_time ("execution_time", &td.execution_time), GNUNET_JSON_spec_json ("deposits", &details_j), - GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", &td.exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", &td.exchange_pub), GNUNET_JSON_spec_end () }; struct TALER_EXCHANGE_HttpResponse hr = { @@ -119,22 +113,32 @@ check_transfers_get_response_ok ( return GNUNET_SYSERR; } if (GNUNET_OK != - TALER_amount_get_zero (total_amount.currency, + TALER_amount_get_zero (td.total_amount.currency, &total_expected)) { GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - num_details = json_array_size (details_j); + if (GNUNET_OK != + TALER_EXCHANGE_test_signing_key ( + TALER_EXCHANGE_get_keys (wdh->exchange), + &td.exchange_pub)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + return GNUNET_SYSERR; + } + td.details_length = json_array_size (details_j); { - struct TALER_TrackTransferDetails details[num_details]; - unsigned int i; struct GNUNET_HashContext *hash_context; - struct TALER_WireDepositDetailP dd; - struct TALER_WireDepositDataPS wdp; + struct TALER_TrackTransferDetails *details; + details = GNUNET_new_array (td.details_length, + struct TALER_TrackTransferDetails); + td.details = details; hash_context = GNUNET_CRYPTO_hash_context_start (); - for (i = 0; ih_contract_terms; - dd.execution_time = GNUNET_TIME_absolute_hton (exec_time); - dd.coin_pub = detail->coin_pub; - TALER_amount_hton (&dd.deposit_value, - &detail->coin_value); - TALER_amount_hton (&dd.deposit_fee, - &detail->coin_fee); - if ( (0 > + if ( (GNUNET_OK != + GNUNET_JSON_parse (detail_j, + spec_detail, + NULL, NULL)) || + (0 > TALER_amount_add (&total_expected, &total_expected, &detail->coin_value)) || @@ -177,71 +167,78 @@ check_transfers_get_response_ok ( GNUNET_break_op (0); GNUNET_CRYPTO_hash_context_abort (hash_context); GNUNET_JSON_parse_free (spec); + GNUNET_free (details); return GNUNET_SYSERR; } - GNUNET_CRYPTO_hash_context_read ( - hash_context, - &dd, - sizeof (struct TALER_WireDepositDetailP)); + /* build up big hash for signature checking later */ + { + struct TALER_WireDepositDetailP dd; + + dd.h_contract_terms = detail->h_contract_terms; + dd.execution_time = GNUNET_TIME_absolute_hton (td.execution_time); + dd.coin_pub = detail->coin_pub; + TALER_amount_hton (&dd.deposit_value, + &detail->coin_value); + TALER_amount_hton (&dd.deposit_fee, + &detail->coin_fee); + GNUNET_CRYPTO_hash_context_read (hash_context, + &dd, + sizeof (dd)); + } } /* Check signature */ - wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT); - wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS)); - TALER_amount_hton (&wdp.total, - &total_amount); - TALER_amount_hton (&wdp.wire_fee, - &wire_fee); - wdp.merchant_pub = merchant_pub; - wdp.h_wire = h_wire; - GNUNET_CRYPTO_hash_context_finish (hash_context, - &wdp.h_details); - if (GNUNET_OK != - TALER_EXCHANGE_test_signing_key (TALER_EXCHANGE_get_keys ( - wdh->exchange), - &exchange_pub)) { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, - &wdp, - &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; + struct TALER_WireDepositDataPS wdp = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT), + .purpose.size = htonl (sizeof (wdp)), + .merchant_pub = merchant_pub, + .h_wire = td.h_wire + }; + + TALER_amount_hton (&wdp.total, + &td.total_amount); + TALER_amount_hton (&wdp.wire_fee, + &td.wire_fee); + GNUNET_CRYPTO_hash_context_finish (hash_context, + &wdp.h_details); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, + &wdp, + &td.exchange_sig.eddsa_signature, + &td.exchange_pub.eddsa_pub)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + GNUNET_free (details); + return GNUNET_SYSERR; + } } if (0 > TALER_amount_subtract (&total_expected, &total_expected, - &wire_fee)) + &td.wire_fee)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); + GNUNET_free (details); return GNUNET_SYSERR; } if (0 != TALER_amount_cmp (&total_expected, - &total_amount)) + &td.total_amount)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); + GNUNET_free (details); return GNUNET_SYSERR; } wdh->cb (wdh->cb_cls, &hr, - &exchange_pub, - &h_wire, - exec_time, - &total_amount, - &wire_fee, - num_details, - details); + &td); + GNUNET_free (details); } GNUNET_JSON_parse_free (spec); TALER_EXCHANGE_transfers_get_cancel (wdh); @@ -322,12 +319,7 @@ handle_transfers_get_finished (void *cls, } wdh->cb (wdh->cb_cls, &hr, - NULL, - NULL, - GNUNET_TIME_UNIT_ZERO_ABS, - NULL, - NULL, - 0, NULL); + NULL); TALER_EXCHANGE_transfers_get_cancel (wdh); } diff --git a/src/testing/testing_api_cmd_transfer_get.c b/src/testing/testing_api_cmd_transfer_get.c index 699313e56..3ca319cb5 100644 --- a/src/testing/testing_api_cmd_transfer_get.c +++ b/src/testing/testing_api_cmd_transfer_get.c @@ -121,37 +121,18 @@ track_transfer_cleanup (void *cls, * * @param cls closure. * @param hr HTTP response details - * @param exchange_pub public key the exchange used for signing - * the response. - * @param h_wire hash of the wire transfer address the transfer - * went to, or NULL on error. - * @param execution_time time when the exchange claims to have - * performed the wire transfer. - * @param total_amount total amount of the wire transfer, or NULL - * if the exchange could not provide any @a wtid (set only - * if @a http_status is "200 OK"). - * @param wire_fee wire fee that was charged by the exchange. - * @param details_length length of the @a details array. - * @param details array with details about the combined - * transactions. + * @param ta transfer data returned by the exchange */ static void track_transfer_cb (void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const struct GNUNET_HashCode *h_wire, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *total_amount, - const struct TALER_Amount *wire_fee, - unsigned int details_length, - const struct TALER_TrackTransferDetails *details) + const struct TALER_EXCHANGE_TransferData *ta) { struct TrackTransferState *tts = cls; struct TALER_TESTING_Interpreter *is = tts->is; struct TALER_TESTING_Command *cmd = &is->commands[is->ip]; struct TALER_Amount expected_amount; - (void) exchange_pub; tts->tth = NULL; if (tts->expected_response_code != hr->http_status) { @@ -193,14 +174,14 @@ track_transfer_cb (void *cls, TALER_TESTING_interpreter_fail (is); return; } - if (0 != TALER_amount_cmp (total_amount, + if (0 != TALER_amount_cmp (&ta->total_amount, &expected_amount)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Total amount mismatch to command %s - " "%s vs %s\n", cmd->label, - TALER_amount_to_string (total_amount), + TALER_amount_to_string (&ta->total_amount), TALER_amount_to_string (&expected_amount)); json_dumpf (hr->reply, stderr, @@ -219,7 +200,7 @@ track_transfer_cb (void *cls, return; } - if (0 != TALER_amount_cmp (wire_fee, + if (0 != TALER_amount_cmp (&ta->wire_fee, &expected_amount)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -266,7 +247,7 @@ track_transfer_cb (void *cls, TALER_JSON_merchant_wire_signature_hash (wire_details, &h_wire_details)); if (0 != GNUNET_memcmp (&h_wire_details, - h_wire)) + &ta->h_wire)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wire hash missmath to command %s\n", @@ -301,7 +282,7 @@ track_transfer_cb (void *cls, TALER_TESTING_interpreter_fail (is); return; } - if (0 != TALER_amount_cmp (total_amount, + if (0 != TALER_amount_cmp (&ta->total_amount, total_amount_from_reference)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -- cgit v1.2.3 From 62e33107749b54c026abcf7b3494d8b2a8658d73 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 3 May 2020 20:07:49 +0200 Subject: modify TALER_EXCHANGE_deposits_get() API to combine returned arguments into a struct (simplifies merchant later) --- src/include/taler_exchange_service.h | 52 +++++++++++++++----- src/lib/exchange_api_deposits_get.c | 77 +++++++++++++++++------------- src/testing/testing_api_cmd_deposits_get.c | 21 ++------ 3 files changed, 89 insertions(+), 61 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 307a76de8..320123041 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1682,27 +1682,57 @@ TALER_EXCHANGE_transfers_get_cancel ( struct TALER_EXCHANGE_DepositGetHandle; +/** + * Data returned for a successful GET /deposits/ request. Note that + * most fields are only set if the status is #MHD_HTTP_OK. Only + * the @e execution_time is available if the status is #MHD_HTTP_ACCEPTED. + */ +struct TALER_EXCHANGE_DepositData +{ + + /** + * exchange key used to sign, NULL if exchange did not + * yet execute the transaction + */ + const struct TALER_ExchangePublicKeyP *exchange_pub; + + /** + * signature from the exchange over the deposit data, NULL if exchange did not + * yet execute the transaction + */ + const struct TALER_ExchangeSignatureP *exchange_sig; + + /** + * wire transfer identifier used by the exchange, NULL if exchange did not + * yet execute the transaction + */ + const struct TALER_WireTransferIdentifierRawP *wtid; + + /** + * actual or planned execution time for the wire transfer + */ + struct GNUNET_TIME_Absolute execution_time; + + /** + * contribution to the total amount by this coin, NULL if exchange did not + * yet execute the transaction + */ + const struct TALER_Amount *coin_contribution; +}; + + /** * Function called with detailed wire transfer data. * * @param cls closure * @param hr HTTP response data - * @param exchange_pub exchange key used to sign @a json, or NULL - * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not - * yet execute the transaction - * @param execution_time actual or planned execution time for the wire transfer - * @param coin_contribution contribution to the total amount by this coin (can be NULL) - * // FIXME: also return the exchange signature - * // FIXME: combine all of the above (except cls,hr) into a 'struct'! => DepositData + * @param dd details about the deposit (NULL on errors) */ typedef void (*TALER_EXCHANGE_DepositGetCallback)( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *coin_contribution); + const struct TALER_EXCHANGE_DepositData *dd); /** diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c index aecd88240..6a2ad5c3d 100644 --- a/src/lib/exchange_api_deposits_get.c +++ b/src/lib/exchange_api_deposits_get.c @@ -33,7 +33,7 @@ /** - * @brief A Deposit Wtid Handle + * @brief A Deposit Get Handle */ struct TALER_EXCHANGE_DepositGetHandle { @@ -84,31 +84,19 @@ struct TALER_EXCHANGE_DepositGetHandle * * @param dwh deposit wtid handle * @param json json reply with the signature - * @param[out] exchange_pub set to the exchange's public key + * @param exchange_pub the exchange's public key + * @param exchange_sig the exchange's signature * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_deposit_wtid_signature_ok ( const struct TALER_EXCHANGE_DepositGetHandle *dwh, const json_t *json, - struct TALER_ExchangePublicKeyP *exchange_pub) + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_ExchangeSignatureP *exchange_sig) { - struct TALER_ExchangeSignatureP exchange_sig; const struct TALER_EXCHANGE_Keys *key_state; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), - GNUNET_JSON_spec_end () - }; - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } key_state = TALER_EXCHANGE_get_keys (dwh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, @@ -120,7 +108,7 @@ verify_deposit_wtid_signature_ok ( if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE, &dwh->depconf, - &exchange_sig.eddsa_signature, + &exchange_sig->eddsa_signature, &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); @@ -144,12 +132,6 @@ handle_deposit_wtid_finished (void *cls, const void *response) { struct TALER_EXCHANGE_DepositGetHandle *dwh = cls; - const struct TALER_WireTransferIdentifierRawP *wtid = NULL; - struct GNUNET_TIME_Absolute execution_time = GNUNET_TIME_UNIT_FOREVER_ABS; - const struct TALER_Amount *coin_contribution = NULL; - struct TALER_Amount coin_contribution_s; - struct TALER_ExchangePublicKeyP exchange_pub; - struct TALER_ExchangePublicKeyP *ep = NULL; const json_t *j = response; struct TALER_EXCHANGE_HttpResponse hr = { .reply = j, @@ -164,10 +146,16 @@ handle_deposit_wtid_finished (void *cls, break; case MHD_HTTP_OK: { + struct GNUNET_TIME_Absolute execution_time; + struct TALER_Amount coin_contribution; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangeSignatureP exchange_sig; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("wtid", &dwh->depconf.wtid), GNUNET_JSON_spec_absolute_time ("execution_time", &execution_time), - TALER_JSON_spec_amount ("coin_contribution", &coin_contribution_s), + TALER_JSON_spec_amount ("coin_contribution", &coin_contribution), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), GNUNET_JSON_spec_end () }; @@ -181,15 +169,14 @@ handle_deposit_wtid_finished (void *cls, hr.ec = TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE; break; } - wtid = &dwh->depconf.wtid; dwh->depconf.execution_time = GNUNET_TIME_absolute_hton (execution_time); TALER_amount_hton (&dwh->depconf.coin_contribution, - &coin_contribution_s); - coin_contribution = &coin_contribution_s; + &coin_contribution); if (GNUNET_OK != verify_deposit_wtid_signature_ok (dwh, j, - &exchange_pub)) + &exchange_pub, + &exchange_sig)) { GNUNET_break_op (0); hr.http_status = 0; @@ -197,13 +184,26 @@ handle_deposit_wtid_finished (void *cls, } else { - ep = &exchange_pub; + struct TALER_EXCHANGE_DepositData dd = { + .exchange_pub = &exchange_pub, + .exchange_sig = &exchange_sig, + .wtid = &dwh->depconf.wtid, + .execution_time = execution_time, + .coin_contribution = &coin_contribution + }; + + dwh->cb (dwh->cb_cls, + &hr, + &dd); + TALER_EXCHANGE_deposits_get_cancel (dwh); + return; } } break; case MHD_HTTP_ACCEPTED: { /* Transaction known, but not executed yet */ + struct GNUNET_TIME_Absolute execution_time; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_absolute_time ("execution_time", &execution_time), GNUNET_JSON_spec_end () @@ -219,6 +219,18 @@ handle_deposit_wtid_finished (void *cls, hr.ec = TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE; break; } + else + { + struct TALER_EXCHANGE_DepositData dd = { + .execution_time = execution_time + }; + + dwh->cb (dwh->cb_cls, + &hr, + &dd); + TALER_EXCHANGE_deposits_get_cancel (dwh); + return; + } } break; case MHD_HTTP_BAD_REQUEST: @@ -259,10 +271,7 @@ handle_deposit_wtid_finished (void *cls, } dwh->cb (dwh->cb_cls, &hr, - ep, - wtid, - execution_time, - coin_contribution); + NULL); TALER_EXCHANGE_deposits_get_cancel (dwh); } diff --git a/src/testing/testing_api_cmd_deposits_get.c b/src/testing/testing_api_cmd_deposits_get.c index fd02e75bb..6f0140116 100644 --- a/src/testing/testing_api_cmd_deposits_get.c +++ b/src/testing/testing_api_cmd_deposits_get.c @@ -81,29 +81,17 @@ struct TrackTransactionState * * @param cls closure. * @param hr HTTP response details - * @param exchange_pub public key of the exchange - * @param wtid wire transfer identifier, NULL if exchange did not - * execute the transaction yet. - * @param execution_time actual or planned execution time for the - * wire transfer. - * @param coin_contribution contribution to the total amount of - * the deposited coin (can be NULL). + * @param dd data about the wire transfer associated with the deposit */ static void deposit_wtid_cb (void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *coin_contribution) + const struct TALER_EXCHANGE_DepositData *dd) { struct TrackTransactionState *tts = cls; struct TALER_TESTING_Interpreter *is = tts->is; struct TALER_TESTING_Command *cmd = &is->commands[is->ip]; - (void) coin_contribution; - (void) exchange_pub; - (void) execution_time; tts->tth = NULL; if (tts->expected_response_code != hr->http_status) { @@ -123,7 +111,8 @@ deposit_wtid_cb (void *cls, switch (hr->http_status) { case MHD_HTTP_OK: - tts->wtid = *wtid; + GNUNET_assert (NULL != dd->wtid); + tts->wtid = *dd->wtid; if (NULL != tts->bank_transfer_reference) { const struct TALER_TESTING_Command *bank_transfer_cmd; @@ -151,7 +140,7 @@ deposit_wtid_cb (void *cls, } /* Compare that expected and gotten subjects match. */ - if (0 != GNUNET_memcmp (wtid, + if (0 != GNUNET_memcmp (dd->wtid, wtid_want)) { GNUNET_break (0); -- cgit v1.2.3 From 275ff5e8aab1a3630adf22d232eab209ada4f01f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 3 May 2020 20:12:18 +0200 Subject: modify TALER_EXCHANGE_deposits_get() API to avoid NULL pointers and need for deep copies --- src/include/taler_exchange_service.h | 16 +++++++-------- src/lib/exchange_api_deposits_get.c | 31 +++++++++++------------------- src/testing/testing_api_cmd_deposits_get.c | 5 ++--- 3 files changed, 21 insertions(+), 31 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 320123041..f94b8253d 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1691,22 +1691,22 @@ struct TALER_EXCHANGE_DepositData { /** - * exchange key used to sign, NULL if exchange did not + * exchange key used to sign, all zeros if exchange did not * yet execute the transaction */ - const struct TALER_ExchangePublicKeyP *exchange_pub; + struct TALER_ExchangePublicKeyP exchange_pub; /** - * signature from the exchange over the deposit data, NULL if exchange did not + * signature from the exchange over the deposit data, all zeros if exchange did not * yet execute the transaction */ - const struct TALER_ExchangeSignatureP *exchange_sig; + struct TALER_ExchangeSignatureP exchange_sig; /** - * wire transfer identifier used by the exchange, NULL if exchange did not + * wire transfer identifier used by the exchange, all zeros if exchange did not * yet execute the transaction */ - const struct TALER_WireTransferIdentifierRawP *wtid; + struct TALER_WireTransferIdentifierRawP wtid; /** * actual or planned execution time for the wire transfer @@ -1714,10 +1714,10 @@ struct TALER_EXCHANGE_DepositData struct GNUNET_TIME_Absolute execution_time; /** - * contribution to the total amount by this coin, NULL if exchange did not + * contribution to the total amount by this coin, all zeros if exchange did not * yet execute the transaction */ - const struct TALER_Amount *coin_contribution; + struct TALER_Amount coin_contribution; }; diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c index 6a2ad5c3d..004a24d42 100644 --- a/src/lib/exchange_api_deposits_get.c +++ b/src/lib/exchange_api_deposits_get.c @@ -146,16 +146,13 @@ handle_deposit_wtid_finished (void *cls, break; case MHD_HTTP_OK: { - struct GNUNET_TIME_Absolute execution_time; - struct TALER_Amount coin_contribution; - struct TALER_ExchangePublicKeyP exchange_pub; - struct TALER_ExchangeSignatureP exchange_sig; + struct TALER_EXCHANGE_DepositData dd; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("wtid", &dwh->depconf.wtid), - GNUNET_JSON_spec_absolute_time ("execution_time", &execution_time), - TALER_JSON_spec_amount ("coin_contribution", &coin_contribution), - GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), + GNUNET_JSON_spec_absolute_time ("execution_time", &dd.execution_time), + TALER_JSON_spec_amount ("coin_contribution", &dd.coin_contribution), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", &dd.exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", &dd.exchange_pub), GNUNET_JSON_spec_end () }; @@ -169,14 +166,15 @@ handle_deposit_wtid_finished (void *cls, hr.ec = TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE; break; } - dwh->depconf.execution_time = GNUNET_TIME_absolute_hton (execution_time); + dwh->depconf.execution_time = GNUNET_TIME_absolute_hton ( + dd.execution_time); TALER_amount_hton (&dwh->depconf.coin_contribution, - &coin_contribution); + &dd.coin_contribution); if (GNUNET_OK != verify_deposit_wtid_signature_ok (dwh, j, - &exchange_pub, - &exchange_sig)) + &dd.exchange_pub, + &dd.exchange_sig)) { GNUNET_break_op (0); hr.http_status = 0; @@ -184,14 +182,7 @@ handle_deposit_wtid_finished (void *cls, } else { - struct TALER_EXCHANGE_DepositData dd = { - .exchange_pub = &exchange_pub, - .exchange_sig = &exchange_sig, - .wtid = &dwh->depconf.wtid, - .execution_time = execution_time, - .coin_contribution = &coin_contribution - }; - + dd.wtid = dwh->depconf.wtid; dwh->cb (dwh->cb_cls, &hr, &dd); diff --git a/src/testing/testing_api_cmd_deposits_get.c b/src/testing/testing_api_cmd_deposits_get.c index 6f0140116..33987e161 100644 --- a/src/testing/testing_api_cmd_deposits_get.c +++ b/src/testing/testing_api_cmd_deposits_get.c @@ -111,8 +111,7 @@ deposit_wtid_cb (void *cls, switch (hr->http_status) { case MHD_HTTP_OK: - GNUNET_assert (NULL != dd->wtid); - tts->wtid = *dd->wtid; + tts->wtid = dd->wtid; if (NULL != tts->bank_transfer_reference) { const struct TALER_TESTING_Command *bank_transfer_cmd; @@ -140,7 +139,7 @@ deposit_wtid_cb (void *cls, } /* Compare that expected and gotten subjects match. */ - if (0 != GNUNET_memcmp (dd->wtid, + if (0 != GNUNET_memcmp (&dd->wtid, wtid_want)) { GNUNET_break (0); -- cgit v1.2.3 From 28dff45363c8f161ceac808b69579da791e4d5d1 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 5 May 2020 22:17:16 +0200 Subject: return fee as well --- src/include/taler_error_codes.h | 19 +++++++++++++++++++ src/include/taler_exchange_service.h | 2 ++ src/lib/exchange_api_refund.c | 4 +++- src/testing/testing_api_cmd_refund.c | 3 +++ 4 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h index f75464c35..74660303d 100644 --- a/src/include/taler_error_codes.h +++ b/src/include/taler_error_codes.h @@ -2198,6 +2198,25 @@ enum TALER_ErrorCode */ TALER_EC_TIP_PICKUP_UNBLIND_FAILURE = 2812, + /** + * We failed to fetch contract terms from our merchant database. The + * response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR = 2900, + + /** + * We failed to find the contract terms from our merchant database. + * The response is provided with HTTP status code #MHD_HTTP_NOT_FOUND. + */ + TALER_EC_GET_ORDERS_ID_UNKNOWN = 2901, + + /** + * The contract hash provided by the wallet does not match the order. + * The response is provided with HTTP status code #MHD_HTTP_FORBIDDEN. + */ + TALER_EC_GET_ORDERS_WRONG_CONTRACT = 2902, + /** * We failed to contract terms from our merchant database. The * response is provided with HTTP status code diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index f94b8253d..82b9b83df 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -851,6 +851,7 @@ struct TALER_EXCHANGE_RefundHandle; * * @param cls closure * @param hr HTTP response data + * @param refund_fee the refund fee the exchange charged us * @param sign_key exchange key used to sign @a obj, or NULL * @param signature the actual signature, or NULL on error */ @@ -858,6 +859,7 @@ typedef void (*TALER_EXCHANGE_RefundCallback) ( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + const struct TALER_Amount *refund_fee, const struct TALER_ExchangePublicKeyP *sign_key, const struct TALER_ExchangeSignatureP *signature); diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 9cb8794d3..b1ea176bf 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -92,7 +92,6 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh, const json_t *json, struct TALER_ExchangePublicKeyP *exchange_pub, struct TALER_ExchangeSignatureP *exchange_sig) - { const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { @@ -149,6 +148,7 @@ handle_refund_finished (void *cls, struct TALER_ExchangeSignatureP exchange_sig; struct TALER_ExchangePublicKeyP *ep = NULL; struct TALER_ExchangeSignatureP *es = NULL; + struct TALER_Amount *rf = NULL; const json_t *j = response; struct TALER_EXCHANGE_HttpResponse hr = { .reply = j, @@ -176,6 +176,7 @@ handle_refund_finished (void *cls, { ep = &exchange_pub; es = &exchange_sig; + rf = &rh->depconf.refund_fee; } break; case MHD_HTTP_BAD_REQUEST: @@ -234,6 +235,7 @@ handle_refund_finished (void *cls, } rh->cb (rh->cb_cls, &hr, + rf, ep, es); TALER_EXCHANGE_refund_cancel (rh); diff --git a/src/testing/testing_api_cmd_refund.c b/src/testing/testing_api_cmd_refund.c index c27311fbf..e662ace2e 100644 --- a/src/testing/testing_api_cmd_refund.c +++ b/src/testing/testing_api_cmd_refund.c @@ -76,6 +76,7 @@ struct RefundState * * @param cls closure * @param hr HTTP response details + * @param refund_fee the refund fee the exchange charged * @param exchange_pub public key the exchange * used for signing @a obj. * @param exchange_sig actual signature confirming the refund @@ -83,6 +84,7 @@ struct RefundState static void refund_cb (void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + const struct TALER_Amount *refund_fee, const struct TALER_ExchangePublicKeyP *exchange_pub, const struct TALER_ExchangeSignatureP *exchange_sig) { @@ -90,6 +92,7 @@ refund_cb (void *cls, struct RefundState *rs = cls; struct TALER_TESTING_Command *refund_cmd; + (void) refund_fee; refund_cmd = &rs->is->commands[rs->is->ip]; rs->rh = NULL; if (rs->expected_response_code != hr->http_status) -- cgit v1.2.3 From 141d4b154a9d6f57ba82edda1cd003be8adb1dd5 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 7 May 2020 20:22:02 +0200 Subject: towards changing timestamp in deposit confirmation (tests failing) --- .../taler-auditor-httpd_deposit-confirmation.c | 5 +- src/auditor/taler-helper-auditor-coins.c | 8 +- src/auditor/taler-helper-auditor-deposits.c | 9 +- src/auditordb/auditor-0001.sql | 2 +- src/auditordb/plugin_auditordb_postgres.c | 10 +- src/exchange/taler-exchange-aggregator.c | 12 ++ src/exchange/taler-exchange-httpd_deposit.c | 173 +++++++++++---------- src/exchange/taler-exchange-httpd_responses.c | 2 +- src/exchangedb/exchange-0001.sql | 3 +- src/exchangedb/plugin_exchangedb_postgres.c | 62 ++++++-- src/exchangedb/test_exchangedb.c | 71 ++++++--- src/include/taler_auditordb_plugin.h | 4 +- src/include/taler_error_codes.h | 45 ++++-- src/include/taler_exchange_service.h | 2 + src/include/taler_exchangedb_plugin.h | 18 ++- src/include/taler_signatures.h | 7 +- src/include/taler_testing_lib.h | 18 ++- src/lib/auditor_api_deposit_confirmation.c | 17 +- src/lib/exchange_api_common.c | 2 +- src/lib/exchange_api_deposit.c | 9 +- src/lib/exchange_api_refund.c | 7 +- src/testing/test_taler_exchange_aggregator.c | 24 +++ .../testing_api_cmd_auditor_deposit_confirmation.c | 8 +- src/testing/testing_api_cmd_deposit.c | 35 +++-- src/testing/testing_api_cmd_insert_deposit.c | 26 +++- 25 files changed, 390 insertions(+), 189 deletions(-) (limited to 'src/lib') diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c index 5f84a7253..1039164c4 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c @@ -155,7 +155,7 @@ verify_and_execute_deposit_confirmation ( .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)), .h_contract_terms = dc->h_contract_terms, .h_wire = dc->h_wire, - .timestamp = GNUNET_TIME_absolute_hton (dc->timestamp), + .exchange_timestamp = GNUNET_TIME_absolute_hton (dc->exchange_timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (dc->refund_deadline), .coin_pub = dc->coin_pub, .merchant = dc->merchant @@ -224,7 +224,8 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &dc.h_contract_terms), GNUNET_JSON_spec_fixed_auto ("h_wire", &dc.h_wire), - GNUNET_JSON_spec_absolute_time ("timestamp", &dc.timestamp), + GNUNET_JSON_spec_absolute_time ("exchange_timestamp", + &dc.exchange_timestamp), GNUNET_JSON_spec_absolute_time ("refund_deadline", &dc.refund_deadline), TALER_JSON_spec_amount ("amount_without_fee", &dc.amount_without_fee), GNUNET_JSON_spec_fixed_auto ("coin_pub", &dc.coin_pub), diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 2e32c5698..158baa8b3 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1535,7 +1535,8 @@ refresh_session_cb (void *cls, * * @param cls closure * @param rowid unique serial ID for the deposit in our DB - * @param timestamp when did the deposit happen + * @param exchange_timestamp when did the exchange get the deposit + * @param wallet_timestamp when did the contract signing happen * @param merchant_pub public key of the merchant * @param denom_pub denomination public key of @a coin_pub * @param coin_pub public key of the coin @@ -1553,7 +1554,8 @@ refresh_session_cb (void *cls, static int deposit_cb (void *cls, uint64_t rowid, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1611,7 +1613,7 @@ deposit_cb (void *cls, .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), .purpose.size = htonl (sizeof (dr)), .h_contract_terms = *h_contract_terms, - .timestamp = GNUNET_TIME_absolute_hton (timestamp), + .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .deposit_fee = issue->fee_deposit, .merchant = *merchant_pub, diff --git a/src/auditor/taler-helper-auditor-deposits.c b/src/auditor/taler-helper-auditor-deposits.c index 291558590..ed23c6a52 100644 --- a/src/auditor/taler-helper-auditor-deposits.c +++ b/src/auditor/taler-helper-auditor-deposits.c @@ -114,11 +114,15 @@ test_dc (void *cls, .h_wire = dc->h_wire, .refund_deadline = dc->refund_deadline }; + struct GNUNET_TIME_Absolute exchange_timestamp; + struct TALER_Amount deposit_fee; qs = TALER_ARL_edb->have_deposit (TALER_ARL_edb->cls, TALER_ARL_esession, &dep, - GNUNET_NO /* do not check refund deadline */); + GNUNET_NO /* do not check refund deadline */, + &deposit_fee, + &exchange_timestamp); if (qs > 0) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -137,7 +141,8 @@ test_dc (void *cls, TALER_ARL_report (report_deposit_confirmation_inconsistencies, json_pack ("{s:o, s:o, s:I, s:o}", "timestamp", - TALER_ARL_json_from_time_abs (dc->timestamp), + TALER_ARL_json_from_time_abs ( + dc->exchange_timestamp), "amount", TALER_JSON_from_amount (&dc->amount_without_fee), "rowid", diff --git a/src/auditordb/auditor-0001.sql b/src/auditordb/auditor-0001.sql index ff8867bee..b511a4d5b 100644 --- a/src/auditordb/auditor-0001.sql +++ b/src/auditordb/auditor-0001.sql @@ -251,7 +251,7 @@ CREATE TABLE IF NOT EXISTS deposit_confirmations ,serial_id BIGSERIAL UNIQUE ,h_contract_terms BYTEA CHECK (LENGTH(h_contract_terms)=64) ,h_wire BYTEA CHECK (LENGTH(h_wire)=64) - ,timestamp INT8 NOT NULL + ,exchange_timestamp INT8 NOT NULL ,refund_deadline INT8 NOT NULL ,amount_without_fee_val INT8 NOT NULL ,amount_without_fee_frac INT4 NOT NULL diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 467c4c6db..4f9101fdc 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -269,7 +269,7 @@ postgres_get_session (void *cls) "(master_pub" ",h_contract_terms" ",h_wire" - ",timestamp" + ",exchange_timestamp" ",refund_deadline" ",amount_without_fee_val" ",amount_without_fee_frac" @@ -286,7 +286,7 @@ postgres_get_session (void *cls) " serial_id" ",h_contract_terms" ",h_wire" - ",timestamp" + ",exchange_timestamp" ",refund_deadline" ",amount_without_fee_val" ",amount_without_fee_frac" @@ -1126,7 +1126,7 @@ postgres_insert_deposit_confirmation ( GNUNET_PQ_query_param_auto_from_type (&dc->master_public_key), GNUNET_PQ_query_param_auto_from_type (&dc->h_contract_terms), GNUNET_PQ_query_param_auto_from_type (&dc->h_wire), - TALER_PQ_query_param_absolute_time (&dc->timestamp), + TALER_PQ_query_param_absolute_time (&dc->exchange_timestamp), TALER_PQ_query_param_absolute_time (&dc->refund_deadline), TALER_PQ_query_param_amount (&dc->amount_without_fee), GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub), @@ -1207,8 +1207,8 @@ deposit_confirmation_cb (void *cls, &dc.h_contract_terms), GNUNET_PQ_result_spec_auto_from_type ("h_wire", &dc.h_wire), - GNUNET_PQ_result_spec_absolute_time ("timestamp", - &dc.timestamp), + GNUNET_PQ_result_spec_absolute_time ("exchange_timestamp", + &dc.exchange_timestamp), GNUNET_PQ_result_spec_absolute_time ("refund_deadline", &dc.refund_deadline), TALER_PQ_RESULT_SPEC_AMOUNT ("amount_without_fee", diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 21a29e506..69c73746c 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -330,6 +330,8 @@ refund_by_coin_cb (void *cls, * * @param cls a `struct AggregationUnit` * @param row_id identifies database entry + * @param exchange_timestamp when did the deposit happen + * @param wallet_timestamp when did the contract happen * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin * @param amount_with_fee amount that was deposited including fee @@ -343,6 +345,8 @@ refund_by_coin_cb (void *cls, static enum GNUNET_DB_QueryStatus deposit_cb (void *cls, uint64_t row_id, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, @@ -358,6 +362,8 @@ deposit_cb (void *cls, /* NOTE: potential optimization: use custom SQL API to not fetch this one: */ (void) wire_deadline; /* already checked by SQL query */ + (void) exchange_timestamp; + (void) wallet_timestamp; au->merchant_pub = *merchant_pub; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Aggregator processing payment %s with amount %s\n", @@ -501,6 +507,8 @@ deposit_cb (void *cls, * * @param cls a `struct AggregationUnit` * @param row_id identifies database entry + * @param exchange_timestamp when did the exchange receive the deposit + * @param wallet_timestamp when did the wallet sign the contract * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin * @param amount_with_fee amount that was deposited including fee @@ -514,6 +522,8 @@ deposit_cb (void *cls, static enum GNUNET_DB_QueryStatus aggregate_cb (void *cls, uint64_t row_id, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, @@ -529,6 +539,8 @@ aggregate_cb (void *cls, /* NOTE: potential optimization: use custom SQL API to not fetch these: */ (void) wire_deadline; /* checked by SQL */ + (void) exchange_timestamp; + (void) wallet_timestamp; (void) wire; /* must match */ GNUNET_break (0 == GNUNET_memcmp (&au->merchant_pub, merchant_pub)); diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 65251863a..fe8fdf061 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -47,7 +47,7 @@ * @param coin_pub public key of the coin * @param h_wire hash of wire details * @param h_contract_terms hash of contract details - * @param timestamp client's timestamp + * @param exchange_timestamp exchange's timestamp * @param refund_deadline until when this deposit be refunded * @param merchant merchant public key * @param amount_without_fee fraction of coin value to deposit, without the fee @@ -58,7 +58,7 @@ reply_deposit_success (struct MHD_Connection *connection, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract_terms, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_MerchantPublicKeyP *merchant, const struct TALER_Amount *amount_without_fee) @@ -70,7 +70,7 @@ reply_deposit_success (struct MHD_Connection *connection, .purpose.size = htonl (sizeof (dc)), .h_contract_terms = *h_contract_terms, .h_wire = *h_wire, - .timestamp = GNUNET_TIME_absolute_hton (timestamp), + .exchange_timestamp = GNUNET_TIME_absolute_hton (exchange_timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .coin_pub = *coin_pub, .merchant = *merchant @@ -88,13 +88,16 @@ reply_deposit_success (struct MHD_Connection *connection, TALER_EC_EXCHANGE_BAD_CONFIGURATION, "no keys"); } - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:o, s:o}", - "exchange_sig", - GNUNET_JSON_from_data_auto (&sig), - "exchange_pub", - GNUNET_JSON_from_data_auto (&pub)); + return TALER_MHD_reply_json_pack ( + connection, + MHD_HTTP_OK, + "{s:o, s:o, s:o}", + "exchange_timestamp", + GNUNET_JSON_from_time_abs (exchange_timestamp), + "exchange_sig", + GNUNET_JSON_from_data_auto (&sig), + "exchange_pub", + GNUNET_JSON_from_data_auto (&pub)); } @@ -108,6 +111,11 @@ struct DepositContext */ const struct TALER_EXCHANGEDB_Deposit *deposit; + /** + * Our timestamp (when we received the request). + */ + struct GNUNET_TIME_Absolute exchange_timestamp; + /** * Value of the coin. */ @@ -117,12 +125,11 @@ struct DepositContext /** - * Execute database transaction for /deposit. Runs the transaction - * logic; IF it returns a non-error code, the transaction logic MUST - * NOT queue a MHD response. IF it returns an hard error, the - * transaction logic MUST queue a MHD response and set @a mhd_ret. IF - * it returns the soft error code, the function MAY be called again to - * retry and MUST not queue a MHD response. + * Check if /deposit is already in the database. IF it returns a non-error + * code, the transaction logic MUST NOT queue a MHD response. IF it returns + * an hard error, the transaction logic MUST queue a MHD response and set @a + * mhd_ret. We do return a "hard" error also if we found the deposit in the + * database and generated a regular response. * * @param cls a `struct DepositContext` * @param connection MHD request context @@ -131,20 +138,22 @@ struct DepositContext * @return transaction status */ static enum GNUNET_DB_QueryStatus -deposit_transaction (void *cls, - struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - MHD_RESULT *mhd_ret) +deposit_precheck (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + MHD_RESULT *mhd_ret) { struct DepositContext *dc = cls; const struct TALER_EXCHANGEDB_Deposit *deposit = dc->deposit; - struct TALER_Amount spent; + struct TALER_Amount deposit_fee; enum GNUNET_DB_QueryStatus qs; qs = TEH_plugin->have_deposit (TEH_plugin->cls, session, deposit, - GNUNET_YES /* check refund deadline */); + GNUNET_YES /* check refund deadline */, + &deposit_fee, + &dc->exchange_timestamp); if (qs < 0) { if (GNUNET_DB_STATUS_HARD_ERROR == qs) @@ -166,12 +175,12 @@ deposit_transaction (void *cls, GNUNET_assert (0 <= TALER_amount_subtract (&amount_without_fee, &deposit->amount_with_fee, - &deposit->deposit_fee)); + &deposit_fee)); *mhd_ret = reply_deposit_success (connection, &deposit->coin.coin_pub, &deposit->h_wire, &deposit->h_contract_terms, - deposit->timestamp, + dc->exchange_timestamp, deposit->refund_deadline, &deposit->merchant_pub, &amount_without_fee); @@ -179,6 +188,44 @@ deposit_transaction (void *cls, never try again. */ return GNUNET_DB_STATUS_HARD_ERROR; } + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; +} + + +/** + * Execute database transaction for /deposit. Runs the transaction + * logic; IF it returns a non-error code, the transaction logic MUST + * NOT queue a MHD response. IF it returns an hard error, the + * transaction logic MUST queue a MHD response and set @a mhd_ret. IF + * it returns the soft error code, the function MAY be called again to + * retry and MUST not queue a MHD response. + * + * @param cls a `struct DepositContext` + * @param connection MHD request context + * @param session database session and transaction to use + * @param[out] mhd_ret set to MHD status on error + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +deposit_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + MHD_RESULT *mhd_ret) +{ + struct DepositContext *dc = cls; + const struct TALER_EXCHANGEDB_Deposit *deposit = dc->deposit; + struct TALER_Amount spent; + enum GNUNET_DB_QueryStatus qs; + + /* Theoretically, someone other threat may have received + and committed the deposit in the meantime. Check now + that we are in the transaction scope. */ + qs = deposit_precheck (cls, + connection, + session, + mhd_ret); + if (qs < 0) + return qs; /* Start with fee for THIS transaction */ spent = deposit->amount_with_fee; @@ -238,6 +285,7 @@ deposit_transaction (void *cls, } qs = TEH_plugin->insert_deposit (TEH_plugin->cls, session, + dc->exchange_timestamp, deposit); if (GNUNET_DB_STATUS_HARD_ERROR == qs) { @@ -251,45 +299,6 @@ deposit_transaction (void *cls, } -/** - * Check that @a ts is reasonably close to our own RTC. - * - * @param ts timestamp to check - * @return #GNUNET_OK if @a ts is reasonable - */ -static int -check_timestamp_current (struct GNUNET_TIME_Absolute ts) -{ - struct GNUNET_TIME_Relative r; - struct GNUNET_TIME_Relative tolerance; - - /* Let's be VERY generous (after all, this is basically about - which year the deposit counts for in terms of tax purposes) */ - tolerance = GNUNET_TIME_UNIT_MONTHS; - r = GNUNET_TIME_absolute_get_duration (ts); - if (r.rel_value_us > tolerance.rel_value_us) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Deposit timestamp too old: %llu vs %llu > %llu\n", - (unsigned long long) ts.abs_value_us, - (unsigned long long) GNUNET_TIME_absolute_get ().abs_value_us, - (unsigned long long) tolerance.rel_value_us); - return GNUNET_SYSERR; - } - r = GNUNET_TIME_absolute_get_remaining (ts); - if (r.rel_value_us > tolerance.rel_value_us) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Deposit timestamp too new: %llu vs %llu < - %llu\n", - (unsigned long long) ts.abs_value_us, - (unsigned long long) GNUNET_TIME_absolute_get ().abs_value_us, - (unsigned long long) tolerance.rel_value_us); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - /** * Handle a "/coins/$COIN_PUB/deposit" request. Parses the JSON, and, if * successful, passes the JSON data to #deposit_transaction() to @@ -367,17 +376,6 @@ TEH_handler_deposit (struct MHD_Connection *connection, TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, "refund_deadline"); } - - if (GNUNET_OK != - check_timestamp_current (deposit.timestamp)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_DEPOSIT_INVALID_TIMESTAMP, - "timestamp"); - } if (GNUNET_OK != TALER_JSON_merchant_wire_signature_hash (wire, &my_h_wire)) @@ -401,6 +399,26 @@ TEH_handler_deposit (struct MHD_Connection *connection, "h_wire"); } + /* Check for idempotency: did we get this request before? */ + dc.deposit = &deposit; + { + MHD_RESULT mhd_ret; + + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "precheck deposit", + &mhd_ret, + &deposit_precheck, + &dc)) + { + GNUNET_JSON_parse_free (spec); + return mhd_ret; + } + } + + /* new deposit */ + dc.exchange_timestamp = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&dc.exchange_timestamp); /* check denomination exists and is valid */ { struct TEH_KS_StateHandle *key_state; @@ -408,7 +426,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, enum TALER_ErrorCode ec; unsigned int hc; - key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); + key_state = TEH_KS_acquire (dc.exchange_timestamp); if (NULL == key_state) { TALER_LOG_ERROR ("Lacking keys to operate\n"); @@ -502,7 +520,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, .purpose.size = htonl (sizeof (dr)), .h_contract_terms = deposit.h_contract_terms, .h_wire = deposit.h_wire, - .timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp), + .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (deposit.refund_deadline), .merchant = deposit.merchant_pub, .coin_pub = deposit.coin.coin_pub @@ -528,7 +546,6 @@ TEH_handler_deposit (struct MHD_Connection *connection, } /* execute transaction */ - dc.deposit = &deposit; { MHD_RESULT mhd_ret; @@ -557,7 +574,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, &deposit.coin.coin_pub, &deposit.h_wire, &deposit.h_contract_terms, - deposit.timestamp, + dc.exchange_timestamp, deposit.refund_deadline, &deposit.merchant_pub, &amount_without_fee); diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 7924ad54c..f65951614 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -66,7 +66,7 @@ TEH_RESPONSE_compile_transaction_history ( .purpose.size = htonl (sizeof (dr)), .h_contract_terms = deposit->h_contract_terms, .h_wire = deposit->h_wire, - .timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp), + .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp), .refund_deadline = GNUNET_TIME_absolute_hton ( deposit->refund_deadline), .merchant = deposit->merchant_pub, diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index bec9af5ba..ad05e7797 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -254,7 +254,8 @@ CREATE TABLE IF NOT EXISTS deposits ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE ,amount_with_fee_val INT8 NOT NULL ,amount_with_fee_frac INT4 NOT NULL - ,timestamp INT8 NOT NULL + ,wallet_timestamp INT8 NOT NULL + ,exchange_timestamp INT8 NOT NULL ,refund_deadline INT8 NOT NULL ,wire_deadline INT8 NOT NULL ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32) diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 5bd674b2d..93577feb4 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -796,7 +796,7 @@ postgres_get_session (void *cls) "(coin_pub" ",amount_with_fee_val" ",amount_with_fee_frac" - ",timestamp" + ",wallet_timestamp" ",refund_deadline" ",wire_deadline" ",merchant_pub" @@ -804,22 +804,28 @@ postgres_get_session (void *cls) ",h_wire" ",coin_sig" ",wire" + ",exchange_timestamp" ") VALUES " "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," - " $11);", - 11), + " $11, $12);", + 12), /* Fetch an existing deposit request, used to ensure idempotency during /deposit processing. Used in #postgres_have_deposit(). */ GNUNET_PQ_make_prepare ("get_deposit", "SELECT" " amount_with_fee_val" ",amount_with_fee_frac" - ",timestamp" + ",denominations.fee_deposit_val" + ",denominations.fee_deposit_frac" + ",wallet_timestamp" + ",exchange_timestamp" ",refund_deadline" ",wire_deadline" ",h_contract_terms" ",h_wire" " FROM deposits" + " JOIN known_coins USING (coin_pub)" + " JOIN denominations USING (denom_pub_hash)" " WHERE ((coin_pub=$1)" " AND (merchant_pub=$3)" " AND (h_contract_terms=$2))" @@ -830,7 +836,8 @@ postgres_get_session (void *cls) "SELECT" " amount_with_fee_val" ",amount_with_fee_frac" - ",timestamp" + ",wallet_timestamp" + ",exchange_timestamp" ",merchant_pub" ",denom.denom_pub" ",coin_pub" @@ -881,6 +888,8 @@ postgres_get_session (void *cls) ",wire" ",merchant_pub" ",coin_pub" + ",exchange_timestamp" + ",wallet_timestamp" " FROM deposits" " JOIN known_coins USING (coin_pub)" " JOIN denominations denom USING (denom_pub_hash)" @@ -900,6 +909,8 @@ postgres_get_session (void *cls) ",denom.fee_deposit_val" ",denom.fee_deposit_frac" ",wire_deadline" + ",exchange_timestamp" + ",wallet_timestamp" ",h_contract_terms" ",coin_pub" " FROM deposits" @@ -945,7 +956,7 @@ postgres_get_session (void *cls) ",amount_with_fee_frac" ",denom.fee_deposit_val" ",denom.fee_deposit_frac" - ",timestamp" + ",wallet_timestamp" ",refund_deadline" ",wire_deadline" ",merchant_pub" @@ -2571,6 +2582,8 @@ postgres_get_reserve_history (void *cls, * @param session database connection * @param deposit deposit to search for * @param check_extras whether to check extra fields match or not + * @param[out] deposit_fee set to the deposit fee the exchange charged + * @param[out] exchange_timestamp set to the time when the exchange received the deposit * @return 1 if we know this operation, * 0 if this exact deposit is unknown to us, * otherwise transaction error status @@ -2579,7 +2592,9 @@ static enum GNUNET_DB_QueryStatus postgres_have_deposit (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct TALER_EXCHANGEDB_Deposit *deposit, - int check_extras) + int check_extras, + struct TALER_Amount *deposit_fee, + struct GNUNET_TIME_Absolute *exchange_timestamp) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -2592,12 +2607,16 @@ postgres_have_deposit (void *cls, struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", &deposit2.amount_with_fee), - TALER_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("wallet_timestamp", &deposit2.timestamp), + TALER_PQ_result_spec_absolute_time ("exchange_timestamp", + exchange_timestamp), TALER_PQ_result_spec_absolute_time ("refund_deadline", &deposit2.refund_deadline), TALER_PQ_result_spec_absolute_time ("wire_deadline", &deposit2.wire_deadline), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + deposit_fee), GNUNET_PQ_result_spec_auto_from_type ("h_wire", &deposit2.h_wire), GNUNET_PQ_result_spec_end @@ -2776,6 +2795,8 @@ postgres_get_ready_deposit (void *cls, struct TALER_Amount amount_with_fee; struct TALER_Amount deposit_fee; struct GNUNET_TIME_Absolute wire_deadline; + struct GNUNET_TIME_Absolute wallet_timestamp; + struct GNUNET_TIME_Absolute exchange_timestamp; struct GNUNET_HashCode h_contract_terms; struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_CoinSpendPublicKeyP coin_pub; @@ -2788,6 +2809,10 @@ postgres_get_ready_deposit (void *cls, &amount_with_fee), TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", &deposit_fee), + TALER_PQ_result_spec_absolute_time ("exchange_timestamp", + &exchange_timestamp), + TALER_PQ_result_spec_absolute_time ("wallet_timestamp", + &wallet_timestamp), TALER_PQ_result_spec_absolute_time ("wire_deadline", &wire_deadline), GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", @@ -2817,6 +2842,8 @@ postgres_get_ready_deposit (void *cls, qs = deposit_cb (deposit_cb_cls, serial_id, + exchange_timestamp, + wallet_timestamp, &merchant_pub, &coin_pub, &amount_with_fee, @@ -2898,6 +2925,8 @@ match_deposit_cb (void *cls, { struct TALER_Amount amount_with_fee; struct TALER_Amount deposit_fee; + struct GNUNET_TIME_Absolute exchange_timestamp; + struct GNUNET_TIME_Absolute wallet_timestamp; struct GNUNET_TIME_Absolute wire_deadline; struct GNUNET_HashCode h_contract_terms; struct TALER_CoinSpendPublicKeyP coin_pub; @@ -2912,6 +2941,10 @@ match_deposit_cb (void *cls, &deposit_fee), TALER_PQ_result_spec_absolute_time ("wire_deadline", &wire_deadline), + TALER_PQ_result_spec_absolute_time ("exchange_timestamp", + &exchange_timestamp), + TALER_PQ_result_spec_absolute_time ("wallet_timestamp", + &wallet_timestamp), GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", &h_contract_terms), GNUNET_PQ_result_spec_auto_from_type ("coin_pub", @@ -2930,6 +2963,8 @@ match_deposit_cb (void *cls, } qs = mdc->deposit_cb (mdc->deposit_cb_cls, serial_id, + exchange_timestamp, + wallet_timestamp, mdc->merchant_pub, &coin_pub, &amount_with_fee, @@ -3210,12 +3245,14 @@ postgres_ensure_coin_known (void *cls, * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param session connection to the database + * @param exchange_timestamp time the exchange received the deposit request * @param deposit deposit information to store * @return query result status */ static enum GNUNET_DB_QueryStatus postgres_insert_deposit (void *cls, struct TALER_EXCHANGEDB_Session *session, + struct GNUNET_TIME_Absolute exchange_timestamp, const struct TALER_EXCHANGEDB_Deposit *deposit) { struct GNUNET_PQ_QueryParam params[] = { @@ -3229,6 +3266,7 @@ postgres_insert_deposit (void *cls, GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire), GNUNET_PQ_query_param_auto_from_type (&deposit->csig), TALER_PQ_query_param_json (deposit->receiver_wire_account), + TALER_PQ_query_param_absolute_time (&exchange_timestamp), GNUNET_PQ_query_param_end }; @@ -4042,7 +4080,7 @@ add_coin_deposit (void *cls, &deposit->amount_with_fee), TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", &deposit->deposit_fee), - TALER_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("wallet_timestamp", &deposit->timestamp), TALER_PQ_result_spec_absolute_time ("refund_deadline", &deposit->refund_deadline), @@ -5462,14 +5500,17 @@ deposit_serial_helper_cb (void *cls, for (unsigned int i = 0; icb (dsc->cb_cls, rowid, + exchange_timestamp, deposit.timestamp, &deposit.merchant_pub, &denom_pub, diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index eea484e94..fe3ed7854 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -833,6 +833,8 @@ static uint64_t deposit_rowid; * @param cls closure a `struct TALER_EXCHANGEDB_Deposit *` * @param rowid unique ID for the deposit in our DB, used for marking * it as 'tiny' or 'done' + * @param exchange_timestamp when did the deposit happen + * @param wallet_timestamp when did the wallet sign the contract * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin * @param amount_with_fee amount that was deposited including fee @@ -846,6 +848,8 @@ static uint64_t deposit_rowid; static enum GNUNET_DB_QueryStatus deposit_cb (void *cls, uint64_t rowid, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, @@ -890,7 +894,8 @@ deposit_cb (void *cls, * * @param cls closure * @param rowid unique serial ID for the deposit in our DB - * @param timestamp when did the deposit happen + * @param exchange_timestamp when did the deposit happen + * @param wallet_timestamp when did the wallet sign the contract * @param merchant_pub public key of the merchant * @param denom_pub denomination of the @a coin_pub * @param coin_pub public key of the coin @@ -908,7 +913,8 @@ deposit_cb (void *cls, static int audit_deposit_cb (void *cls, uint64_t rowid, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1878,15 +1884,27 @@ run (void *cls) plugin->ensure_coin_known (plugin->cls, session, &deposit.coin)); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->insert_deposit (plugin->cls, + { + struct GNUNET_TIME_Absolute now; + struct GNUNET_TIME_Absolute r; + struct TALER_Amount deposit_fee; + + now = GNUNET_TIME_absolute_get (); + GNUNET_TIME_round_abs (&now); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->insert_deposit (plugin->cls, + session, + now, + &deposit)); + FAILIF (1 != + plugin->have_deposit (plugin->cls, session, - &deposit)); - FAILIF (1 != - plugin->have_deposit (plugin->cls, - session, - &deposit, - GNUNET_YES)); + &deposit, + GNUNET_YES, + &deposit_fee, + &r)); + FAILIF (now.abs_value_us != r.abs_value_us); + } { struct GNUNET_TIME_Absolute start_range; struct GNUNET_TIME_Absolute end_range; @@ -1983,18 +2001,27 @@ run (void *cls) session, "test-2")); RND_BLK (&deposit2.merchant_pub); /* should fail if merchant is different */ - FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != - plugin->have_deposit (plugin->cls, - session, - &deposit2, - GNUNET_YES)); - deposit2.merchant_pub = deposit.merchant_pub; - RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ - FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != - plugin->have_deposit (plugin->cls, - session, - &deposit2, - GNUNET_YES)); + { + struct GNUNET_TIME_Absolute r; + struct TALER_Amount deposit_fee; + + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->have_deposit (plugin->cls, + session, + &deposit2, + GNUNET_YES, + &deposit_fee, + &r)); + deposit2.merchant_pub = deposit.merchant_pub; + RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->have_deposit (plugin->cls, + session, + &deposit2, + GNUNET_YES, + &deposit_fee, + &r)); + } FAILIF (GNUNET_OK != test_melting (session)); FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index 9a7f6ed7a..7c58e654e 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -300,9 +300,9 @@ struct TALER_AUDITORDB_DepositConfirmation struct GNUNET_HashCode h_wire; /** - * Time when this confirmation was generated. + * Time when this deposit confirmation was generated by the exchange. */ - struct GNUNET_TIME_Absolute timestamp; + struct GNUNET_TIME_Absolute exchange_timestamp; /** * How much time does the @e merchant have to issue a refund diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h index 74660303d..eded23339 100644 --- a/src/include/taler_error_codes.h +++ b/src/include/taler_error_codes.h @@ -1542,73 +1542,92 @@ enum TALER_ErrorCode * This response is provided with HTTP status code * #MHD_HTTP_SERVICE_UNAVAILABLE. */ - TALER_EC_TRACK_TRANSFER_EXCHANGE_TIMEOUT = 2400, + TALER_EC_POST_TRANSFERS_EXCHANGE_TIMEOUT = 2400, /** * We failed to obtain an acceptable /keys response from the exchange * for the /track/transfer request. This response is provided with * HTTP status code #MHD_HTTP_FAILED_DEPENDENCY. */ - TALER_EC_TRACK_TRANSFER_EXCHANGE_KEYS_FAILURE = 2401, + TALER_EC_POST_TRANSFERS_EXCHANGE_KEYS_FAILURE = 2401, /** * We failed to persist coin wire transfer information in our merchant * database. The response is provided with HTTP status code * #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_DB_STORE_COIN_ERROR = 2402, + TALER_EC_POST_TRANSFERS_DB_STORE_COIN_ERROR = 2402, /** * We internally failed to execute the /track/transfer request. The * response is provided with HTTP status code * #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_REQUEST_ERROR = 2403, + TALER_EC_POST_TRANSFERS_REQUEST_ERROR = 2403, /** * We failed to persist wire transfer information in our merchant * database. The response is provided with HTTP status code * #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_DB_STORE_TRANSFER_ERROR = 2404, + TALER_EC_POST_TRANSFERS_DB_STORE_TRANSFER_ERROR = 2404, /** * The exchange returned an error from /track/transfer. The response * is provided with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY. */ - TALER_EC_TRACK_TRANSFER_EXCHANGE_ERROR = 2405, + TALER_EC_POST_TRANSFERS_EXCHANGE_ERROR = 2405, /** * We failed to fetch deposit information from our merchant database. * The response is provided with HTTP status code * #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_DB_FETCH_DEPOSIT_ERROR = 2406, + TALER_EC_POST_TRANSFERS_DB_FETCH_DEPOSIT_ERROR = 2406, /** * We encountered an internal logic error. The response is provided * with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_DB_INTERNAL_LOGIC_ERROR = 2407, + TALER_EC_POST_TRANSFERS_DB_INTERNAL_LOGIC_ERROR = 2407, /** * The exchange gave conflicting information about a coin which has * been wire transferred. The response is provided with HTTP status * code #MHD_HTTP_FAILED_DEPENDENCY. */ - TALER_EC_TRACK_TRANSFER_CONFLICTING_REPORTS = 2408, + TALER_EC_POST_TRANSFERS_CONFLICTING_REPORTS = 2408, /** * The merchant backend had problems in creating the JSON response. */ - TALER_EC_TRACK_TRANSFER_JSON_RESPONSE_ERROR = 2409, + TALER_EC_POST_TRANSFERS_JSON_RESPONSE_ERROR = 2409, /** * The exchange charged a different wire fee than what it originally - * advertised, and it is higher. The response is provied with an HTTP - * status of #MHD_HTTP_FAILED_DEPENDENCY. + * advertised, and it is higher. The response is provided with an + * HTTP status of #MHD_HTTP_FAILED_DEPENDENCY. */ - TALER_EC_TRACK_TRANSFER_JSON_BAD_WIRE_FEE = 2410, + TALER_EC_POST_TRANSFERS_JSON_BAD_WIRE_FEE = 2410, + + /** + * We did not find the account that the transfer was made to. The + * response is provided with an HTTP status of #MHD_HTTP_NOT_FOUND. + */ + TALER_EC_POST_TRANSFERS_ACCOUNT_NOT_FOUND = 2411, + + /** + * We did failed to store information in our database. The response is + * provided with an HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_POST_TRANSFERS_DB_STORE_ERROR = 2412, + + /** + * We did failed to retrieve information from our database. The + * response is provided with an HTTP status of + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_POST_TRANSFERS_DB_LOOKUP_ERROR = 2413, /** * The merchant backend cannot create an instance under the given diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 82b9b83df..38928dc18 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -756,6 +756,7 @@ struct TALER_EXCHANGE_DepositHandle; * * @param cls closure * @param hr HTTP response data + * @param deposit_timestamp time when the exchange generated the deposit confirmation * @param exchange_sig signature provided by the exchange * @param exchange_pub exchange key used to sign @a obj, or NULL */ @@ -763,6 +764,7 @@ typedef void (*TALER_EXCHANGE_DepositResultCallback) ( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + struct GNUNET_TIME_Absolute deposit_timestamp, const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangePublicKeyP *exchange_pub); diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 4fd580724..9fb932362 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -975,6 +975,8 @@ struct TALER_EXCHANGEDB_Session; * @param cls closure * @param rowid unique ID for the deposit in our DB, used for marking * it as 'tiny' or 'done' + * @param exchange_timestamp when did the exchange receive the deposit + * @param wallet_timestamp when did the wallet sign the contract * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin * @param amount_with_fee amount that was deposited including fee @@ -990,6 +992,8 @@ typedef enum GNUNET_DB_QueryStatus (*TALER_EXCHANGEDB_DepositIterator)( void *cls, uint64_t rowid, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, @@ -1022,7 +1026,8 @@ typedef void * * @param cls closure * @param rowid unique serial ID for the deposit in our DB - * @param timestamp when did the deposit happen + * @param exchange_timestamp when did the deposit happen + * @param wallet_timestamp when did the contract happen * @param merchant_pub public key of the merchant * @param denom_pub denomination public key of @a coin_pub * @param coin_pub public key of the coin @@ -1042,7 +1047,8 @@ typedef int (*TALER_EXCHANGEDB_DepositCallback)( void *cls, uint64_t rowid, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1841,6 +1847,8 @@ struct TALER_EXCHANGEDB_Plugin * @param session database connection * @param deposit deposit to search for * @param check_extras whether to check extra fields or not + * @param[out] deposit_fee set to the deposit fee the exchange charged + * @param[out] exchange_timestamp set to the time when the exchange received the deposit * @return 1 if we know this operation, * 0 if this exact deposit is unknown to us, * otherwise transaction error status @@ -1849,7 +1857,9 @@ struct TALER_EXCHANGEDB_Plugin (*have_deposit)(void *cls, struct TALER_EXCHANGEDB_Session *session, const struct TALER_EXCHANGEDB_Deposit *deposit, - int check_extras); + int check_extras, + struct TALER_Amount *deposit_fee, + struct GNUNET_TIME_Absolute *exchange_timestamp); /** @@ -1857,12 +1867,14 @@ struct TALER_EXCHANGEDB_Plugin * * @param cls the @e cls of this struct with the plugin-specific state * @param session connection to the database + * @param exchange_timestamp time the exchange received the deposit request * @param deposit deposit information to store * @return query result status */ enum GNUNET_DB_QueryStatus (*insert_deposit)(void *cls, struct TALER_EXCHANGEDB_Session *session, + struct GNUNET_TIME_Absolute exchange_timestamp, const struct TALER_EXCHANGEDB_Deposit *deposit); diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index c346a6cee..38b895d7f 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -363,7 +363,7 @@ struct TALER_DepositRequestPS * deposit request in a timely fashion (so back-dating is not * prevented). */ - struct GNUNET_TIME_AbsoluteNBO timestamp; + struct GNUNET_TIME_AbsoluteNBO wallet_timestamp; /** * How much time does the merchant have to issue a refund request? @@ -429,9 +429,10 @@ struct TALER_DepositConfirmationPS struct GNUNET_HashCode h_wire GNUNET_PACKED; /** - * Time when this confirmation was generated. + * Time when this confirmation was generated / when the exchange received + * the deposit request. */ - struct GNUNET_TIME_AbsoluteNBO timestamp; + struct GNUNET_TIME_AbsoluteNBO exchange_timestamp; /** * How much time does the @e merchant have to issue a refund diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index acc218ac5..6a4fa024a 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -1903,6 +1903,7 @@ TALER_TESTING_cmd_connect_with_state (const char *label, * @param dbc collects plugin and session handles * @param merchant_name Human-readable name of the merchant. * @param merchant_account merchant's account name (NOT a payto:// URI) + * @param exchange_timestamp when did the exchange receive the deposit * @param wire_deadline point in time where the aggregator should have * wired money to the merchant. * @param amount_with_fee amount to deposit (inclusive of deposit fee) @@ -1910,14 +1911,15 @@ TALER_TESTING_cmd_connect_with_state (const char *label, * @return the command. */ struct TALER_TESTING_Command -TALER_TESTING_cmd_insert_deposit (const char *label, - const struct - TALER_TESTING_DatabaseConnection *dbc, - const char *merchant_name, - const char *merchant_account, - struct GNUNET_TIME_Relative wire_deadline, - const char *amount_with_fee, - const char *deposit_fee); +TALER_TESTING_cmd_insert_deposit ( + const char *label, + const struct TALER_TESTING_DatabaseConnection *dbc, + const char *merchant_name, + const char *merchant_account, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Relative wire_deadline, + const char *amount_with_fee, + const char *deposit_fee); /** diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c index cddfe8b14..1856a89f4 100644 --- a/src/lib/auditor_api_deposit_confirmation.c +++ b/src/lib/auditor_api_deposit_confirmation.c @@ -148,7 +148,7 @@ handle_deposit_confirmation_finished (void *cls, * * @param h_wire hash of merchant wire details * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor) - * @param timestamp timestamp when the contract was finalized, must not be too far in the future + * @param exchange_timestamp timestamp when the deposit was received by the wallet * @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant * @param coin_pub coin’s public key @@ -165,7 +165,7 @@ handle_deposit_confirmation_finished (void *cls, static int verify_signatures (const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract_terms, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_Amount *amount_without_fee, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -184,7 +184,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire, .purpose.size = htonl (sizeof (dc)), .h_contract_terms = *h_contract_terms, .h_wire = *h_wire, - .timestamp = GNUNET_TIME_absolute_hton (timestamp), + .exchange_timestamp = GNUNET_TIME_absolute_hton (exchange_timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .coin_pub = *coin_pub, .merchant = *merchant_pub @@ -256,7 +256,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire, * @param auditor the auditor handle; the auditor must be ready to operate * @param h_wire hash of merchant wire details * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor) - * @param timestamp timestamp when the contract was finalized, must not be too far in the future + * @param exchange_timestamp timestamp when deposit was received by the exchange * @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant * @param coin_pub coin’s public key @@ -278,7 +278,7 @@ TALER_AUDITOR_deposit_confirmation ( struct TALER_AUDITOR_Handle *auditor, const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract_terms, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_Amount *amount_without_fee, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -298,7 +298,7 @@ TALER_AUDITOR_deposit_confirmation ( json_t *deposit_confirmation_obj; CURL *eh; - (void) GNUNET_TIME_round_abs (×tamp); + (void) GNUNET_TIME_round_abs (&exchange_timestamp); (void) GNUNET_TIME_round_abs (&refund_deadline); (void) GNUNET_TIME_round_abs (&ep_start); (void) GNUNET_TIME_round_abs (&ep_expire); @@ -308,7 +308,7 @@ TALER_AUDITOR_deposit_confirmation ( if (GNUNET_OK != verify_signatures (h_wire, h_contract_terms, - timestamp, + exchange_timestamp, refund_deadline, amount_without_fee, coin_pub, @@ -336,7 +336,8 @@ TALER_AUDITOR_deposit_confirmation ( "h_wire", GNUNET_JSON_from_data_auto (h_wire), "h_contract_terms", GNUNET_JSON_from_data_auto ( h_contract_terms), - "timestamp", GNUNET_JSON_from_time_abs (timestamp), + "exchange_timestamp", GNUNET_JSON_from_time_abs ( + exchange_timestamp), "refund_deadline", GNUNET_JSON_from_time_abs (refund_deadline), "amount_without_fee", TALER_JSON_from_amount ( amount_without_fee), diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index dc44291d0..bf8eb5376 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -524,7 +524,7 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_JSON_spec_fixed_auto ("h_wire", &dr.h_wire), GNUNET_JSON_spec_absolute_time_nbo ("timestamp", - &dr.timestamp), + &dr.wallet_timestamp), GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline", &dr.refund_deadline), TALER_JSON_spec_amount_nbo ("deposit_fee", diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index a5cf6c36a..276053658 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -160,7 +160,7 @@ auditor_cb (void *cls, ah, &dh->depconf.h_wire, &dh->depconf.h_contract_terms, - GNUNET_TIME_absolute_ntoh (dh->depconf.timestamp), + GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp), GNUNET_TIME_absolute_ntoh (dh->depconf.refund_deadline), &amount_without_fee, &dh->depconf.coin_pub, @@ -198,6 +198,8 @@ verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), + GNUNET_JSON_spec_absolute_time_nbo ("exchange_timestamp", + &dh->depconf.exchange_timestamp), GNUNET_JSON_spec_end () }; @@ -386,6 +388,7 @@ handle_deposit_finished (void *cls, } dh->cb (dh->cb_cls, &hr, + GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp), es, ep); TALER_EXCHANGE_deposit_cancel (dh); @@ -429,7 +432,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, .purpose.size = htonl (sizeof (dr)), .h_contract_terms = *h_contract_terms, .h_wire = *h_wire, - .timestamp = GNUNET_TIME_absolute_hton (timestamp), + .wallet_timestamp = GNUNET_TIME_absolute_hton (timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .merchant = *merchant_pub, .coin_pub = *coin_pub @@ -658,7 +661,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT); dh->depconf.h_contract_terms = *h_contract_terms; dh->depconf.h_wire = h_wire; - dh->depconf.timestamp = GNUNET_TIME_absolute_hton (timestamp); + /* dh->depconf.exchange_timestamp; -- initialized later from exchange reply! */ dh->depconf.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline); TALER_amount_hton (&dh->depconf.amount_without_fee, &amount_without_fee); diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index b1ea176bf..6f91389f1 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -148,7 +148,8 @@ handle_refund_finished (void *cls, struct TALER_ExchangeSignatureP exchange_sig; struct TALER_ExchangePublicKeyP *ep = NULL; struct TALER_ExchangeSignatureP *es = NULL; - struct TALER_Amount *rf = NULL; + struct TALER_Amount ra; + const struct TALER_Amount *rf = NULL; const json_t *j = response; struct TALER_EXCHANGE_HttpResponse hr = { .reply = j, @@ -176,7 +177,9 @@ handle_refund_finished (void *cls, { ep = &exchange_pub; es = &exchange_sig; - rf = &rh->depconf.refund_fee; + TALER_amount_ntoh (&ra, + &rh->depconf.refund_fee); + rf = &ra; } break; case MHD_HTTP_BAD_REQUEST: diff --git a/src/testing/test_taler_exchange_aggregator.c b/src/testing/test_taler_exchange_aggregator.c index eaa621cfe..d5c392d3a 100644 --- a/src/testing/test_taler_exchange_aggregator.c +++ b/src/testing/test_taler_exchange_aggregator.c @@ -108,6 +108,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -126,6 +127,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -134,6 +136,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -153,6 +156,7 @@ run (void *cls, &dbc, "bob", "4", + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -160,6 +164,7 @@ run (void *cls, &dbc, "bob", "5", + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -167,6 +172,7 @@ run (void *cls, &dbc, "alice", "4", + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -195,6 +201,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -204,6 +211,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -229,6 +237,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), @@ -239,6 +248,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -263,6 +273,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.102", "EUR:0.1"), @@ -274,6 +285,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.102", "EUR:0.1"), @@ -281,6 +293,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.102", "EUR:0.1"), @@ -292,6 +305,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.102", "EUR:0.1"), @@ -303,6 +317,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.112", "EUR:0.1"), @@ -319,6 +334,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.109", "EUR:0.1"), @@ -330,6 +346,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.119", "EUR:0.1"), @@ -346,6 +363,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.122", "EUR:0.1"), @@ -362,6 +380,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -375,6 +394,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -390,6 +410,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.122", "EUR:0.1"), @@ -406,6 +427,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -419,6 +441,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -434,6 +457,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.112", "EUR:0.1"), diff --git a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c index 247399a9d..1442380bf 100644 --- a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c +++ b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c @@ -203,6 +203,7 @@ deposit_confirmation_run (void *cls, const struct TALER_TESTING_Command *deposit_cmd; struct GNUNET_HashCode h_wire; struct GNUNET_HashCode h_contract_terms; + const struct GNUNET_TIME_Absolute *exchange_timestamp = NULL; struct GNUNET_TIME_Absolute timestamp; struct GNUNET_TIME_Absolute refund_deadline; struct TALER_Amount amount_without_fee; @@ -238,6 +239,11 @@ deposit_confirmation_run (void *cls, TALER_TESTING_get_trait_exchange_sig (deposit_cmd, dcs->coin_index, &exchange_sig)); + GNUNET_assert (GNUNET_OK == + TALER_TESTING_get_trait_absolute_time (deposit_cmd, + dcs->coin_index, + &exchange_timestamp)); + GNUNET_assert (NULL != exchange_timestamp); keys = TALER_EXCHANGE_get_keys (dcs->is->exchange); GNUNET_assert (NULL != keys); spk = TALER_EXCHANGE_get_signing_key_info (keys, @@ -309,7 +315,7 @@ deposit_confirmation_run (void *cls, dcs->dc = TALER_AUDITOR_deposit_confirmation (dcs->auditor, &h_wire, &h_contract_terms, - timestamp, + *exchange_timestamp, refund_deadline, &amount_without_fee, &coin_pub, diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index 9468e7acb..049f36f25 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -91,9 +91,9 @@ struct DepositState struct TALER_EXCHANGE_DepositHandle *dh; /** - * Timestamp of the /deposit operation. + * Timestamp of the /deposit operation in the wallet (contract signing time). */ - struct GNUNET_TIME_Absolute timestamp; + struct GNUNET_TIME_Absolute wallet_timestamp; /** * Interpreter state. @@ -126,6 +126,11 @@ struct DepositState */ int deposit_succeeded; + /** + * When did the exchange receive the deposit? + */ + struct GNUNET_TIME_Absolute exchange_timestamp; + /** * Signing key used by the exchange to sign the * deposit confirmation. @@ -198,6 +203,7 @@ do_retry (void *cls) * * @param cls closure. * @param hr HTTP response details + * @param exchange_timestamp when did the exchange receive the deposit permission * @param exchange_sig signature provided by the exchange * (NULL on errors) * @param exchange_pub public key of the exchange, @@ -206,6 +212,7 @@ do_retry (void *cls) static void deposit_cb (void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + const struct GNUNET_TIME_Absolute exchange_timestamp, const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangePublicKeyP *exchange_pub) { @@ -254,6 +261,7 @@ deposit_cb (void *cls, if (MHD_HTTP_OK == hr->http_status) { ds->deposit_succeeded = GNUNET_YES; + ds->exchange_timestamp = exchange_timestamp; ds->exchange_pub = *exchange_pub; ds->exchange_sig = *exchange_sig; } @@ -305,7 +313,7 @@ deposit_run (void *cls, ds->coin_index = ods->coin_index; ds->wire_details = json_incref (ods->wire_details); ds->contract_terms = json_incref (ods->contract_terms); - ds->timestamp = ods->timestamp; + ds->wallet_timestamp = ods->wallet_timestamp; ds->refund_deadline = ods->refund_deadline; ds->amount = ods->amount; ds->merchant_priv = ods->merchant_priv; @@ -379,7 +387,7 @@ deposit_run (void *cls, } else { - ds->refund_deadline = ds->timestamp; + ds->refund_deadline = ds->wallet_timestamp; wire_deadline = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_ZERO); } @@ -388,6 +396,7 @@ deposit_run (void *cls, (void) GNUNET_TIME_round_abs (&wire_deadline); + // FIXME: This should be part of TALER_EXCHANGE_deposit()! { struct TALER_DepositRequestPS dr; @@ -400,7 +409,7 @@ deposit_run (void *cls, GNUNET_assert (GNUNET_OK == TALER_JSON_merchant_wire_signature_hash (ds->wire_details, &dr.h_wire)); - dr.timestamp = GNUNET_TIME_absolute_hton (ds->timestamp); + dr.wallet_timestamp = GNUNET_TIME_absolute_hton (ds->wallet_timestamp); dr.refund_deadline = GNUNET_TIME_absolute_hton (ds->refund_deadline); TALER_amount_hton (&dr.amount_with_fee, @@ -421,7 +430,7 @@ deposit_run (void *cls, &coin_pub, denom_pub_sig, &denom_pub->key, - ds->timestamp, + ds->wallet_timestamp, &merchant_pub, ds->refund_deadline, &coin_sig, @@ -534,6 +543,8 @@ deposit_traits (void *cls, &ds->merchant_priv), TALER_TESTING_make_trait_amount_obj (0, &ds->amount), + TALER_TESTING_make_trait_absolute_time (0, + &ds->exchange_timestamp), TALER_TESTING_trait_end () }; @@ -599,12 +610,12 @@ TALER_TESTING_cmd_deposit (const char *label, label); GNUNET_assert (0); } - ds->timestamp = GNUNET_TIME_absolute_get (); - (void) GNUNET_TIME_round_abs (&ds->timestamp); + ds->wallet_timestamp = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&ds->wallet_timestamp); json_object_set_new (ds->contract_terms, "timestamp", - GNUNET_JSON_from_time_abs (ds->timestamp)); + GNUNET_JSON_from_time_abs (ds->wallet_timestamp)); if (0 != refund_deadline.rel_value_us) { ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline); @@ -687,12 +698,12 @@ TALER_TESTING_cmd_deposit_with_ref (const char *label, label); GNUNET_assert (0); } - ds->timestamp = GNUNET_TIME_absolute_get (); - (void) GNUNET_TIME_round_abs (&ds->timestamp); + ds->wallet_timestamp = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&ds->wallet_timestamp); json_object_set_new (ds->contract_terms, "timestamp", - GNUNET_JSON_from_time_abs (ds->timestamp)); + GNUNET_JSON_from_time_abs (ds->wallet_timestamp)); if (0 != refund_deadline.rel_value_us) { ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline); diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c index 356528009..cff2884aa 100644 --- a/src/testing/testing_api_cmd_insert_deposit.c +++ b/src/testing/testing_api_cmd_insert_deposit.c @@ -57,6 +57,11 @@ struct InsertDepositState */ struct GNUNET_TIME_Relative wire_deadline; + /** + * When did the exchange receive the deposit? + */ + struct GNUNET_TIME_Absolute exchange_timestamp; + /** * Amount to deposit, inclusive of deposit fee. */ @@ -210,6 +215,7 @@ insert_deposit_run (void *cls, (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != ids->dbc->plugin->insert_deposit (ids->dbc->plugin->cls, ids->dbc->session, + ids->exchange_timestamp, &deposit)) || (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != ids->dbc->plugin->commit (ids->dbc->plugin->cls, @@ -275,6 +281,7 @@ insert_deposit_traits (void *cls, * @param dbc collects database plugin and session handles. * @param merchant_name Human-readable name of the merchant. * @param merchant_account merchant's account name (NOT a payto:// URI) + * @param exchange_timestamp when did the exchange receive the deposit * @param wire_deadline point in time where the aggregator should have * wired money to the merchant. * @param amount_with_fee amount to deposit (inclusive of deposit fee) @@ -282,21 +289,24 @@ insert_deposit_traits (void *cls, * @return the command. */ struct TALER_TESTING_Command -TALER_TESTING_cmd_insert_deposit (const char *label, - const struct - TALER_TESTING_DatabaseConnection *dbc, - const char *merchant_name, - const char *merchant_account, - struct GNUNET_TIME_Relative wire_deadline, - const char *amount_with_fee, - const char *deposit_fee) +TALER_TESTING_cmd_insert_deposit ( + const char *label, + const struct TALER_TESTING_DatabaseConnection *dbc, + const char *merchant_name, + const char *merchant_account, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Relative wire_deadline, + const char *amount_with_fee, + const char *deposit_fee) { struct InsertDepositState *ids; + GNUNET_TIME_round_abs (&exchange_timestamp); ids = GNUNET_new (struct InsertDepositState); ids->dbc = dbc; ids->merchant_name = merchant_name; ids->merchant_account = merchant_account; + ids->exchange_timestamp = exchange_timestamp; ids->wire_deadline = wire_deadline; ids->amount_with_fee = amount_with_fee; ids->deposit_fee = deposit_fee; -- cgit v1.2.3 From 6801e8e560e3dc7e35cf9b3dcd5bd6673d352b72 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 31 May 2020 17:39:26 +0200 Subject: update ECs --- src/include/taler_error_codes.h | 55 +++++++++++++++++++++++++++++++++++++++++ src/lib/exchange_api_melt.c | 10 ++++---- 2 files changed, 60 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h index 1e031f4b6..87feea2d3 100644 --- a/src/include/taler_error_codes.h +++ b/src/include/taler_error_codes.h @@ -2165,6 +2165,61 @@ enum TALER_ErrorCode */ TALER_EC_RESERVES_DELETE_NO_SUCH_RESERVE = 2722, + /** + * The backend got an unexpected error trying to lookup reserve + * details from the backend. This response is provided with HTTP + * status code #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_LOOKUP_RESERVE_DB_FAILURE = 2723, + + /** + * The backend repeatedly failed to serialize the transaction to + * authorize the tip. This response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_SERIALIZATION_FAILURE = 2724, + + /** + * The backend failed to start the transaction to authorize the tip. + * This response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_START_FAILURE = 2725, + + /** + * The backend failed looking up the reserve needed to authorize the + * tip. This response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_LOOKUP_RESERVE_FAILURE = 2726, + + /** + * The backend failed to find a reserve needed to authorize the tip. + * This response is provided with HTTP status code + * #MHD_HTTP_SERVICE_UNAVAILABLE. + */ + TALER_EC_TIP_AUTHORIZE_DB_RESERVE_NOT_FOUND = 2727, + + /** + * The backend encountered an internal invariant violation. This + * response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_RESERVE_INVARIANT_FAILURE = 2728, + + /** + * The selected exchange expired. This response is provided with HTTP + * status code #MHD_HTTP_GONE. + */ + TALER_EC_TIP_AUTHORIZE_DB_RESERVE_EXPIRED = 2729, + + /** + * The backend failed updating the reserve needed to authorize the + * tip. This response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_UPDATE_RESERVE_FAILURE = 2730, + /** * The backend had trouble accessing the database to persist * information about enabling tips. Returned with an HTTP status code diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index f89036e40..0695f997b 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -445,11 +445,11 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2]; char *end; - end = GNUNET_STRINGS_data_to_string (&melt.coin_pub, - sizeof (struct - TALER_CoinSpendPublicKeyP), - pub_str, - sizeof (pub_str)); + end = GNUNET_STRINGS_data_to_string ( + &melt.coin_pub, + sizeof (struct TALER_CoinSpendPublicKeyP), + pub_str, + sizeof (pub_str)); *end = '\0'; GNUNET_snprintf (arg_str, sizeof (arg_str), -- cgit v1.2.3 From 48d4690fbd0576e900332dcbfb285d0537091abf Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 23 Jun 2020 10:30:31 +0200 Subject: clarify with/without wire fee issue, sanity checks on currencies --- src/include/taler_exchange_service.h | 2 +- src/lib/exchange_api_transfers_get.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 079987020..e61a07c91 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1611,7 +1611,7 @@ struct TALER_EXCHANGE_TransferData struct GNUNET_TIME_Absolute execution_time; /** - * amount of the wire transfer; FIXME: total wired (without fee), or including @a wire_fee? + * Actual amount of the wire transfer, excluding the wire fee. */ struct TALER_Amount total_amount; diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c index dd9b64467..6b5bba8e8 100644 --- a/src/lib/exchange_api_transfers_get.c +++ b/src/lib/exchange_api_transfers_get.c @@ -155,6 +155,12 @@ check_transfers_get_response_ok ( GNUNET_JSON_parse (detail_j, spec_detail, NULL, NULL)) || + (GNUNET_OK != + TALER_amount_cmp_currency (&total_expected, + &detail->coin_value)) || + (GNUNET_OK != + TALER_amount_cmp_currency (&total_expected, + &detail->coin_fee)) || (0 > TALER_amount_add (&total_expected, &total_expected, -- cgit v1.2.3 From d5ba2437f130e642da35b5320d6852552f42b6a4 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 27 Jun 2020 18:49:12 +0200 Subject: fix FIXME by exposing deposit permission signing in API instead of doing it inside of the testing logic --- src/include/taler_exchange_service.h | 26 +++++++++++++++++ src/lib/exchange_api_deposit.c | 53 +++++++++++++++++++++++++++++++++++ src/testing/testing_api_cmd_deposit.c | 39 +++++++++----------------- 3 files changed, 92 insertions(+), 26 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index e61a07c91..02ab182f2 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -744,6 +744,32 @@ TALER_EXCHANGE_wire_cancel (struct TALER_EXCHANGE_WireHandle *wh); /* ********************* /coins/$COIN_PUB/deposit *********************** */ +/** + * Sign a deposit permission. Function for wallets. + * + * @param amount the amount to be deposited + * @param deposit_fee the deposit fee we expect to pay + * @param h_wire hash of the merchant’s account details + * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) + * @param coin_priv coin’s private key + * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future + * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) + * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline + * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT + */ +void +TALER_EXCHANGE_deposit_permission_sign ( + const struct TALER_Amount *amount, + const struct TALER_Amount *deposit_fee, + const struct GNUNET_HashCode *h_wire, + const struct GNUNET_HashCode *h_contract_terms, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct GNUNET_TIME_Absolute wallet_timestamp, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct GNUNET_TIME_Absolute refund_deadline, + struct TALER_CoinSpendSignatureP *coin_sig); + + /** * @brief A Deposit Handle */ diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 276053658..351fa7a10 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -490,6 +490,59 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, } +/** + * Sign a deposit permission. Function for wallets. + * + * @param amount the amount to be deposited + * @param deposit_fee the deposit fee we expect to pay + * @param h_wire hash of the merchant’s account details + * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) + * @param coin_priv coin’s private key + * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future + * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) + * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline + * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT + */ +void +TALER_EXCHANGE_deposit_permission_sign ( + const struct TALER_Amount *amount, + const struct TALER_Amount *deposit_fee, + const struct GNUNET_HashCode *h_wire, + const struct GNUNET_HashCode *h_contract_terms, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct GNUNET_TIME_Absolute wallet_timestamp, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct GNUNET_TIME_Absolute refund_deadline, + struct TALER_CoinSpendSignatureP *coin_sig) +{ + struct TALER_DepositRequestPS dr = { + .purpose.size = htonl + (sizeof (dr)), + .purpose.purpose = htonl + (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), + .h_contract_terms = *h_contract_terms, + .h_wire = *h_wire, + .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp), + .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), + .merchant = *merchant_pub + }; + + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&wallet_timestamp)); + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&refund_deadline)); + GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, + &dr.coin_pub.eddsa_pub); + TALER_amount_hton (&dr.amount_with_fee, + amount); + TALER_amount_hton (&dr.deposit_fee, + deposit_fee); + GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, + &dr, + &coin_sig->eddsa_signature); +} + + /** * Submit a deposit permission to the exchange and get the exchange's response. * Note that while we return the response verbatim to the caller for diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index f302a218b..e7a4c2988 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -394,39 +394,26 @@ deposit_run (void *cls, else { ds->refund_deadline = ds->wallet_timestamp; - wire_deadline = GNUNET_TIME_relative_to_absolute - (GNUNET_TIME_UNIT_ZERO); + wire_deadline = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_ZERO); } GNUNET_CRYPTO_eddsa_key_get_public (&ds->merchant_priv.eddsa_priv, &merchant_pub.eddsa_pub); - (void) GNUNET_TIME_round_abs (&wire_deadline); - - // FIXME: This should be part of TALER_EXCHANGE_deposit()! { - struct TALER_DepositRequestPS dr; - - memset (&dr, 0, sizeof (dr)); - dr.purpose.size = htonl - (sizeof (struct TALER_DepositRequestPS)); - dr.purpose.purpose = htonl - (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); - dr.h_contract_terms = h_contract_terms; + struct GNUNET_HashCode h_wire; + GNUNET_assert (GNUNET_OK == TALER_JSON_merchant_wire_signature_hash (ds->wire_details, - &dr.h_wire)); - dr.wallet_timestamp = GNUNET_TIME_absolute_hton (ds->wallet_timestamp); - dr.refund_deadline = GNUNET_TIME_absolute_hton - (ds->refund_deadline); - TALER_amount_hton (&dr.amount_with_fee, - &ds->amount); - TALER_amount_hton (&dr.deposit_fee, - &denom_pub->fee_deposit); - dr.merchant = merchant_pub; - dr.coin_pub = coin_pub; - GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, - &dr, - &coin_sig.eddsa_signature); + &h_wire)); + TALER_EXCHANGE_deposit_permission_sign (&ds->amount, + &denom_pub->fee_deposit, + &h_wire, + &h_contract_terms, + coin_priv, + ds->wallet_timestamp, + &merchant_pub, + ds->refund_deadline, + &coin_sig); } ds->dh = TALER_EXCHANGE_deposit (is->exchange, &ds->amount, -- cgit v1.2.3 From 5ac448738dfe213bf27d89abe253455ce0a38acf Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 1 May 2020 19:22:32 +0200 Subject: fix status code --- src/auditor/taler-helper-auditor-coins.c | 1 - src/auditor/taler-helper-auditor-reserves.c | 1 - src/exchange/taler-exchange-httpd_deposit.c | 30 +++++--- src/exchange/taler-exchange-httpd_refund.c | 99 +++++++-------------------- src/exchange/taler-exchange-httpd_responses.c | 2 - src/exchange/taler-exchange-httpd_withdraw.c | 4 -- src/include/taler_exchange_service.h | 4 -- src/include/taler_signatures.h | 24 ------- src/include/taler_testing_lib.h | 4 -- src/lib/exchange_api_common.c | 34 +++++---- src/lib/exchange_api_deposit.c | 4 +- src/lib/exchange_api_handle.c | 2 +- src/lib/exchange_api_refund.c | 21 ++---- src/lib/exchange_api_withdraw2.c | 2 - src/testing/test_auditor_api.c | 1 - src/testing/test_exchange_api.c | 5 -- src/testing/test_exchange_api_twisted.c | 10 --- src/testing/testing_api_cmd_refund.c | 26 ------- 18 files changed, 67 insertions(+), 207 deletions(-) (limited to 'src/lib') diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 9d5e66706..2e32c5698 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1802,7 +1802,6 @@ refund_cb (void *cls, .coin_pub = *coin_pub, .merchant = *merchant_pub, .rtransaction_id = GNUNET_htonll (rtransaction_id), - .refund_fee = issue->fee_refund }; TALER_amount_hton (&rr.refund_amount, diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c index 8879d4950..3460515a2 100644 --- a/src/auditor/taler-helper-auditor-reserves.c +++ b/src/auditor/taler-helper-auditor-reserves.c @@ -550,7 +550,6 @@ handle_reserve_out (void *cls, } /* check reserve_sig (first: setup remaining members of wsrd) */ - wsrd.withdraw_fee = issue->fee_withdraw; TALER_amount_hton (&wsrd.amount_with_fee, amount_with_fee); if (GNUNET_OK != diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 3f895857b..65251863a 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -90,10 +90,11 @@ reply_deposit_success (struct MHD_Connection *connection, } return TALER_MHD_reply_json_pack (connection, MHD_HTTP_OK, - "{s:s, s:o, s:o}", - "status", "DEPOSIT_OK", - "sig", GNUNET_JSON_from_data_auto (&sig), - "pub", GNUNET_JSON_from_data_auto (&pub)); + "{s:o, s:o}", + "exchange_sig", + GNUNET_JSON_from_data_auto (&sig), + "exchange_pub", + GNUNET_JSON_from_data_auto (&pub)); } @@ -312,15 +313,22 @@ TEH_handler_deposit (struct MHD_Connection *connection, struct GNUNET_HashCode my_h_wire; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_json ("wire", &wire), - TALER_JSON_spec_amount ("contribution", &deposit.amount_with_fee), + TALER_JSON_spec_amount ("contribution", + &deposit.amount_with_fee), GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", &deposit.coin.denom_pub_hash), - TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig), - GNUNET_JSON_spec_fixed_auto ("merchant_pub", &deposit.merchant_pub), - GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &deposit.h_contract_terms), - GNUNET_JSON_spec_fixed_auto ("h_wire", &deposit.h_wire), - GNUNET_JSON_spec_fixed_auto ("coin_sig", &deposit.csig), - GNUNET_JSON_spec_absolute_time ("timestamp", &deposit.timestamp), + TALER_JSON_spec_denomination_signature ("ub_sig", + &deposit.coin.denom_sig), + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &deposit.merchant_pub), + GNUNET_JSON_spec_fixed_auto ("h_contract_terms", + &deposit.h_contract_terms), + GNUNET_JSON_spec_fixed_auto ("h_wire", + &deposit.h_wire), + GNUNET_JSON_spec_fixed_auto ("coin_sig", + &deposit.csig), + GNUNET_JSON_spec_absolute_time ("timestamp", + &deposit.timestamp), GNUNET_JSON_spec_absolute_time ("refund_deadline", &deposit.refund_deadline), GNUNET_JSON_spec_absolute_time ("wire_transfer_deadline", diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c index 7c2b149f2..a6a2c3d6f 100644 --- a/src/exchange/taler-exchange-httpd_refund.c +++ b/src/exchange/taler-exchange-httpd_refund.c @@ -73,12 +73,13 @@ reply_refund_success (struct MHD_Connection *connection, TALER_EC_EXCHANGE_BAD_CONFIGURATION, "no online signing key"); } - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:s, s:o, s:o}", - "status", "REFUND_OK", - "sig", GNUNET_JSON_from_data_auto (&sig), - "pub", GNUNET_JSON_from_data_auto (&pub)); + return TALER_MHD_reply_json_pack ( + connection, + MHD_HTTP_OK, + "{s:o, s:o, s:o}", + "refund_fee", TALER_JSON_from_amount (&refund->refund_fee), + "exchange_sig", GNUNET_JSON_from_data_auto (&sig), + "exchange_pub", GNUNET_JSON_from_data_auto (&pub)); } @@ -246,18 +247,15 @@ refund_transaction (void *cls, } /* check currency is compatible */ - if ( (GNUNET_YES != - TALER_amount_cmp_currency (&refund->details.refund_amount, - &dep->amount_with_fee)) || - (GNUNET_YES != - TALER_amount_cmp_currency (&refund->details.refund_fee, - &dep->deposit_fee)) ) + if (GNUNET_YES != + TALER_amount_cmp_currency (&refund->details.refund_amount, + &dep->amount_with_fee)) { GNUNET_break_op (0); /* currency mismatch */ TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_PRECONDITION_FAILED, + MHD_HTTP_BAD_REQUEST, TALER_EC_REFUND_CURRENCY_MISMATCH, "currencies involved do not match"); return GNUNET_DB_STATUS_HARD_ERROR; @@ -339,15 +337,14 @@ refund_transaction (void *cls, * the fee structure, so this is not done here. * * @param connection the MHD connection to handle - * @param refund information about the refund + * @param[in,out] refund information about the refund * @return MHD result code */ static MHD_RESULT verify_and_execute_refund (struct MHD_Connection *connection, - const struct TALER_EXCHANGEDB_Refund *refund) + struct TALER_EXCHANGEDB_Refund *refund) { struct GNUNET_HashCode denom_hash; - struct TALER_Amount expect_fee; { struct TALER_RefundRequestPS rr = { @@ -361,8 +358,6 @@ verify_and_execute_refund (struct MHD_Connection *connection, TALER_amount_hton (&rr.refund_amount, &refund->details.refund_amount); - TALER_amount_hton (&rr.refund_fee, - &refund->details.refund_fee); if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND, &rr, @@ -429,43 +424,12 @@ verify_and_execute_refund (struct MHD_Connection *connection, ec, "denomination not found, but coin known"); } - TALER_amount_ntoh (&expect_fee, + TALER_amount_ntoh (&refund->details.refund_fee, &dki->issue.properties.fee_refund); } TEH_KS_release (key_state); } - /* Check refund fee matches fee of denomination key! */ - if (GNUNET_YES != - TALER_amount_cmp_currency (&expect_fee, - &refund->details.refund_fee) ) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_REFUND_FEE_CURRENCY_MISMATCH, - "refund_fee"); - } - { - int fee_cmp; - - fee_cmp = TALER_amount_cmp (&refund->details.refund_fee, - &expect_fee); - if (-1 == fee_cmp) - { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_REFUND_FEE_TOO_LOW, - "refund_fee"); - } - if (1 == fee_cmp) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Refund fee proposed by merchant is higher than necessary.\n"); - } - } - - /* Finally run the actual transaction logic */ { MHD_RESULT mhd_ret; @@ -502,16 +466,20 @@ TEH_handler_refund (struct MHD_Connection *connection, const struct TALER_CoinSpendPublicKeyP *coin_pub, const json_t *root) { - struct TALER_EXCHANGEDB_Refund refund; + struct TALER_EXCHANGEDB_Refund refund = { + .details.refund_fee.currency = {0} /* set to invalid, just to be sure */ + }; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount ("refund_amount", &refund.details.refund_amount), - TALER_JSON_spec_amount ("refund_fee", &refund.details.refund_fee), + TALER_JSON_spec_amount ("refund_amount", + &refund.details.refund_amount), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &refund.details.h_contract_terms), - GNUNET_JSON_spec_fixed_auto ("merchant_pub", &refund.details.merchant_pub), + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &refund.details.merchant_pub), GNUNET_JSON_spec_uint64 ("rtransaction_id", &refund.details.rtransaction_id), - GNUNET_JSON_spec_fixed_auto ("merchant_sig", &refund.details.merchant_sig), + GNUNET_JSON_spec_fixed_auto ("merchant_sig", + &refund.details.merchant_sig), GNUNET_JSON_spec_end () }; @@ -527,27 +495,6 @@ TEH_handler_refund (struct MHD_Connection *connection, if (GNUNET_NO == res) return MHD_YES; /* failure */ } - if (GNUNET_YES != - TALER_amount_cmp_currency (&refund.details.refund_amount, - &refund.details.refund_fee) ) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_REFUND_FEE_CURRENCY_MISMATCH, - "refund_amount or refund_fee"); - } - if (-1 == TALER_amount_cmp (&refund.details.refund_amount, - &refund.details.refund_fee) ) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_REFUND_FEE_ABOVE_AMOUNT, - "refund_amount"); - } { MHD_RESULT res; diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 06673afc1..7924ad54c 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -185,8 +185,6 @@ TEH_RESPONSE_compile_transaction_history ( TALER_amount_hton (&rr.refund_amount, &refund->refund_amount); - TALER_amount_hton (&rr.refund_fee, - &refund->refund_fee); #if ENABLE_SANITY_CHECKS /* internal sanity check before we hand out a bogus sig... */ if (GNUNET_OK != diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c index 4d662e712..c4c72d6a4 100644 --- a/src/exchange/taler-exchange-httpd_withdraw.c +++ b/src/exchange/taler-exchange-httpd_withdraw.c @@ -306,8 +306,6 @@ withdraw_transaction (void *cls, #endif wc->collectable.denom_pub_hash = wc->denom_pub_hash; wc->collectable.amount_with_fee = wc->amount_required; - TALER_amount_ntoh (&wc->collectable.withdraw_fee, - &wc->dki->issue.properties.fee_withdraw); wc->collectable.reserve_pub = wc->wsrd.reserve_pub; wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope; wc->collectable.reserve_sig = wc->signature; @@ -436,8 +434,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, } TALER_amount_hton (&wc.wsrd.amount_with_fee, &wc.amount_required); - TALER_amount_hton (&wc.wsrd.withdraw_fee, - &fee_withdraw); } /* verify signature! */ diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index f7fa71443..a57a2655a 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -878,7 +878,6 @@ typedef void * @param amount the amount to be refunded; must be larger than the refund fee * (as that fee is still being subtracted), and smaller than the amount * (with deposit fee) of the original deposit contribution of this coin - * @param refund_fee fee applicable to this coin for the refund * @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded * @param coin_pub coin’s public key of the coin from the original deposit operation * @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation); @@ -894,7 +893,6 @@ typedef void struct TALER_EXCHANGE_RefundHandle * TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_Amount *amount, - const struct TALER_Amount *refund_fee, const struct GNUNET_HashCode *h_contract_terms, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t rtransaction_id, @@ -922,7 +920,6 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, * @param amount the amount to be refunded; must be larger than the refund fee * (as that fee is still being subtracted), and smaller than the amount * (with deposit fee) of the original deposit contribution of this coin - * @param refund_fee fee applicable to this coin for the refund * @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded * @param coin_pub coin’s public key of the coin from the original deposit operation * @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation); @@ -939,7 +936,6 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, struct TALER_EXCHANGE_RefundHandle * TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_Amount *amount, - const struct TALER_Amount *refund_fee, const struct GNUNET_HashCode *h_contract_terms, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t rtransaction_id, diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index f55f0c2e4..c346a6cee 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -316,19 +316,6 @@ struct TALER_WithdrawRequestPS */ struct TALER_AmountNBO amount_with_fee; - /** - * Withdrawal fee charged by the exchange. This must match the Exchange's - * denomination key's withdrawal fee. If the client puts in an - * invalid withdrawal fee (too high or too low) that does not match - * the Exchange's denomination key, the withdraw operation is invalid - * and will be rejected by the exchange. The @e amount_with_fee minus - * the @e withdraw_fee is must match the value of the generated - * coin. We include this in what is being signed so that we can - * verify a exchange's accounting without needing to access the - * respective denomination key information each time. - */ - struct TALER_AmountNBO withdraw_fee; - /** * Hash of the denomination public key for the coin that is withdrawn. */ @@ -517,17 +504,6 @@ struct TALER_RefundRequestPS */ struct TALER_AmountNBO refund_amount; - /** - * Refund fee charged by the exchange. This must match the - * Exchange's denomination key's refund fee. If the client puts in - * an invalid refund fee (too high or too low) that does not match - * the Exchange's denomination key, the refund operation is invalid - * and will be rejected by the exchange. The @e amount_with_fee - * minus the @e refund_fee is the amount that will be credited to - * the original coin. - */ - struct TALER_AmountNBO refund_fee; - }; diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index 0696573ea..9abb0cca7 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -1670,7 +1670,6 @@ TALER_TESTING_cmd_check_bank_empty (const char *label); * @param label command label. * @param expected_response_code expected HTTP status code. * @param refund_amount the amount to ask a refund for. - * @param refund_fee expected refund fee. * @param coin_reference reference to a command that can * provide a coin to be refunded. * @param refund_transaction_id transaction id to use @@ -1682,7 +1681,6 @@ struct TALER_TESTING_Command TALER_TESTING_cmd_refund_with_id (const char *label, unsigned int expected_response_code, const char *refund_amount, - const char *refund_fee, const char *deposit_reference, uint64_t refund_transaction_id); @@ -1693,7 +1691,6 @@ TALER_TESTING_cmd_refund_with_id (const char *label, * @param label command label. * @param expected_response_code expected HTTP status code. * @param refund_amount the amount to ask a refund for. - * @param refund_fee expected refund fee. * @param coin_reference reference to a command that can * provide a coin to be refunded. * @@ -1703,7 +1700,6 @@ struct TALER_TESTING_Command TALER_TESTING_cmd_refund (const char *label, unsigned int expected_response_code, const char *refund_amount, - const char *refund_fee, const char *deposit_reference); diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index 07f5e1873..dc44291d0 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -146,11 +146,12 @@ TALER_EXCHANGE_parse_reserve_history ( { struct TALER_ReserveSignatureP sig; struct TALER_WithdrawRequestPS withdraw_purpose; + struct TALER_Amount withdraw_fee; struct GNUNET_JSON_Specification withdraw_spec[] = { GNUNET_JSON_spec_fixed_auto ("reserve_sig", &sig), - TALER_JSON_spec_amount_nbo ("withdraw_fee", - &withdraw_purpose.withdraw_fee), + TALER_JSON_spec_amount ("withdraw_fee", + &withdraw_fee), GNUNET_JSON_spec_fixed_auto ("h_denom_pub", &withdraw_purpose.h_denomination_pub), GNUNET_JSON_spec_fixed_auto ("h_coin_envelope", @@ -189,26 +190,23 @@ TALER_EXCHANGE_parse_reserve_history ( { const struct TALER_EXCHANGE_Keys *key_state; const struct TALER_EXCHANGE_DenomPublicKey *dki; - struct TALER_Amount fee; key_state = TALER_EXCHANGE_get_keys (exchange); dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state, &withdraw_purpose. h_denomination_pub); - TALER_amount_ntoh (&fee, - &withdraw_purpose.withdraw_fee); if ( (GNUNET_YES != - TALER_amount_cmp_currency (&fee, + TALER_amount_cmp_currency (&withdraw_fee, &dki->fee_withdraw)) || (0 != - TALER_amount_cmp (&fee, + TALER_amount_cmp (&withdraw_fee, &dki->fee_withdraw)) ) { GNUNET_break_op (0); GNUNET_JSON_parse_free (withdraw_spec); return GNUNET_SYSERR; } - rh->details.withdraw.fee = fee; + rh->details.withdraw.fee = withdraw_fee; } rh->details.withdraw.out_authorization_sig = json_object_get (transaction, @@ -634,9 +632,16 @@ TALER_EXCHANGE_verify_coin_history ( else if (0 == strcasecmp (type, "REFUND")) { - struct TALER_RefundRequestPS rr; struct TALER_MerchantSignatureP sig; + struct TALER_Amount refund_fee; + struct TALER_RefundRequestPS rr = { + .purpose.size = htonl (sizeof (rr)), + .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND), + .coin_pub = *coin_pub + }; struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount ("refund_fee", + &refund_fee), GNUNET_JSON_spec_fixed_auto ("merchant_sig", &sig), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", @@ -645,8 +650,6 @@ TALER_EXCHANGE_verify_coin_history ( &rr.merchant), GNUNET_JSON_spec_uint64 ("rtransaction_id", &rr.rtransaction_id), - TALER_JSON_spec_amount_nbo ("refund_fee", - &rr.refund_fee), GNUNET_JSON_spec_end () }; @@ -658,9 +661,6 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_break_op (0); return GNUNET_SYSERR; } - rr.purpose.size = htonl (sizeof (rr)); - rr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND); - rr.coin_pub = *coin_pub; TALER_amount_hton (&rr.refund_amount, &amount); if (GNUNET_OK != @@ -683,13 +683,11 @@ TALER_EXCHANGE_verify_coin_history ( /* check that refund fee matches our expectations from /keys! */ if (NULL != dk) { - TALER_amount_ntoh (&fee, - &rr.refund_fee); if ( (GNUNET_YES != - TALER_amount_cmp_currency (&fee, + TALER_amount_cmp_currency (&refund_fee, &dk->fee_refund)) || (0 != - TALER_amount_cmp (&fee, + TALER_amount_cmp (&refund_fee, &dk->fee_refund)) ) { GNUNET_break_op (0); diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 5f3749931..a5cf6c36a 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -196,8 +196,8 @@ verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh, { const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("sig", exchange_sig), - GNUNET_JSON_spec_fixed_auto ("pub", exchange_pub), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), GNUNET_JSON_spec_end () }; diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index c3ae16633..c9c1b09bd 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -39,7 +39,7 @@ * Which version of the Taler protocol is implemented * by this library? Used to determine compatibility. */ -#define EXCHANGE_PROTOCOL_CURRENT 7 +#define EXCHANGE_PROTOCOL_CURRENT 8 /** * How many versions are we backwards compatible with? diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index c64dcc97a..9cb8794d3 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -81,14 +81,14 @@ struct TALER_EXCHANGE_RefundHandle * Verify that the signature on the "200 OK" response * from the exchange is valid. * - * @param rh refund handle + * @param[in,out] rh refund handle (refund fee added) * @param json json reply with the signature * @param[out] exchange_pub set to the exchange's public key * @param[out] exchange_sig set to the exchange's signature * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int -verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, +verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh, const json_t *json, struct TALER_ExchangePublicKeyP *exchange_pub, struct TALER_ExchangeSignatureP *exchange_sig) @@ -96,8 +96,9 @@ verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, { const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("sig", exchange_sig), - GNUNET_JSON_spec_fixed_auto ("pub", exchange_pub), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), + TALER_JSON_spec_amount_nbo ("refund_fee", &rh->depconf.refund_fee), GNUNET_JSON_spec_end () }; @@ -256,7 +257,6 @@ handle_refund_finished (void *cls, * @param amount the amount to be refunded; must be larger than the refund fee * (as that fee is still being subtracted), and smaller than the amount * (with deposit fee) of the original deposit contribution of this coin - * @param refund_fee fee applicable to this coin for the refund * @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded * @param coin_pub coin’s public key of the coin from the original deposit operation * @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation); @@ -272,7 +272,6 @@ handle_refund_finished (void *cls, struct TALER_EXCHANGE_RefundHandle * TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_Amount *amount, - const struct TALER_Amount *refund_fee, const struct GNUNET_HashCode *h_contract_terms, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t rtransaction_id, @@ -294,14 +293,11 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, rr.rtransaction_id = GNUNET_htonll (rtransaction_id); TALER_amount_hton (&rr.refund_amount, amount); - TALER_amount_hton (&rr.refund_fee, - refund_fee); GNUNET_CRYPTO_eddsa_sign (&merchant_priv->eddsa_priv, &rr, &merchant_sig.eddsa_sig); return TALER_EXCHANGE_refund2 (exchange, amount, - refund_fee, h_contract_terms, coin_pub, rtransaction_id, @@ -329,7 +325,6 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, * @param amount the amount to be refunded; must be larger than the refund fee * (as that fee is still being subtracted), and smaller than the amount * (with deposit fee) of the original deposit contribution of this coin - * @param refund_fee fee applicable to this coin for the refund * @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded * @param coin_pub coin’s public key of the coin from the original deposit operation * @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation); @@ -346,7 +341,6 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, struct TALER_EXCHANGE_RefundHandle * TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_Amount *amount, - const struct TALER_Amount *refund_fee, const struct GNUNET_HashCode *h_contract_terms, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t rtransaction_id, @@ -376,12 +370,11 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, "/coins/%s/refund", pub_str); } - refund_obj = json_pack ("{s:o, s:o," /* amount/fee */ + refund_obj = json_pack ("{s:o," /* amount */ " s:o," /* h_contract_terms */ " s:I," /* rtransaction id */ " s:o, s:o}", /* merchant_pub, merchant_sig */ "refund_amount", TALER_JSON_from_amount (amount), - "refund_fee", TALER_JSON_from_amount (refund_fee), "h_contract_terms", GNUNET_JSON_from_data_auto ( h_contract_terms), "rtransaction_id", (json_int_t) rtransaction_id, @@ -410,8 +403,6 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, rh->depconf.rtransaction_id = GNUNET_htonll (rtransaction_id); TALER_amount_hton (&rh->depconf.refund_amount, amount); - TALER_amount_hton (&rh->depconf.refund_fee, - refund_fee); eh = TALER_EXCHANGE_curl_easy_get_ (rh->url); if ( (NULL == eh) || diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c index f9468927a..25f669143 100644 --- a/src/lib/exchange_api_withdraw2.c +++ b/src/lib/exchange_api_withdraw2.c @@ -429,8 +429,6 @@ TALER_EXCHANGE_withdraw2 ( TALER_amount_hton (&req.amount_with_fee, &wh->requested_amount); - TALER_amount_hton (&req.withdraw_fee, - &dk->fee_withdraw); GNUNET_CRYPTO_hash (pd->coin_ev, pd->coin_ev_size, &req.h_coin_envelope); diff --git a/src/testing/test_auditor_api.c b/src/testing/test_auditor_api.c index 7b6996264..0ff28b29b 100644 --- a/src/testing/test_auditor_api.c +++ b/src/testing/test_auditor_api.c @@ -353,7 +353,6 @@ run (void *cls, TALER_TESTING_cmd_refund ("refund-ok", MHD_HTTP_OK, "EUR:5", - "EUR:0.01", "deposit-refund-1"), /** * Spend 4.99 EUR of the refunded 4.99 EUR coin (1ct gone diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c index 0c3f48379..a2bf90014 100644 --- a/src/testing/test_exchange_api.c +++ b/src/testing/test_exchange_api.c @@ -528,18 +528,15 @@ run (void *cls, TALER_TESTING_cmd_refund ("refund-ok", MHD_HTTP_OK, "EUR:5", - "EUR:0.01", "deposit-refund-1"), TALER_TESTING_cmd_refund ("refund-ok-double", MHD_HTTP_OK, "EUR:5", - "EUR:0.01", "deposit-refund-1"), /* Previous /refund(s) had id == 0. */ TALER_TESTING_cmd_refund_with_id ("refund-conflicting", MHD_HTTP_CONFLICT, "EUR:5", - "EUR:0.01", "deposit-refund-1", 1), /** @@ -573,7 +570,6 @@ run (void *cls, TALER_TESTING_cmd_refund ("refund-fail", MHD_HTTP_GONE, "EUR:4.99", - "EUR:0.01", "deposit-refund-2"), TALER_TESTING_cmd_check_bank_empty ("check-empty-after-refund"), /** @@ -607,7 +603,6 @@ run (void *cls, TALER_TESTING_cmd_refund ("refund-ok-fast", MHD_HTTP_OK, "EUR:5", - "EUR:0.01", "deposit-refund-1b"), /** * Run transfers. This will do the transfer as refund deadline diff --git a/src/testing/test_exchange_api_twisted.c b/src/testing/test_exchange_api_twisted.c index 9aac3d1e3..053372197 100644 --- a/src/testing/test_exchange_api_twisted.c +++ b/src/testing/test_exchange_api_twisted.c @@ -173,12 +173,6 @@ run (void *cls, TALER_TESTING_cmd_refund ("refund-currency-mismatch", MHD_HTTP_BAD_REQUEST, "USD:5", - "USD:0.01", - "deposit-refund-1"), - TALER_TESTING_cmd_refund ("refund-fee-above-amount", - MHD_HTTP_BAD_REQUEST, - "EUR:5", - "EUR:10", "deposit-refund-1"), TALER_TESTING_cmd_flip_upload ("flip-upload", CONFIG_FILE, @@ -186,7 +180,6 @@ run (void *cls, TALER_TESTING_cmd_refund ("refund-bad-sig", MHD_HTTP_FORBIDDEN, "EUR:5", - "EUR:0.01", "deposit-refund-1"), /* This next deposit CMD is only used to provide a @@ -207,17 +200,14 @@ run (void *cls, TALER_TESTING_cmd_refund ("refund-deposit-not-found", MHD_HTTP_NOT_FOUND, "EUR:5", - "EUR:0.01", "deposit-refund-to-fail"), TALER_TESTING_cmd_refund ("refund-insufficient-funds", MHD_HTTP_PRECONDITION_FAILED, "EUR:50", - "EUR:0.01", "deposit-refund-1"), TALER_TESTING_cmd_refund ("refund-fee-too-low", MHD_HTTP_BAD_REQUEST, "EUR:5", - "EUR:0.000001", "deposit-refund-1"), TALER_TESTING_cmd_end () }; diff --git a/src/testing/testing_api_cmd_refund.c b/src/testing/testing_api_cmd_refund.c index 47f5a0609..c27311fbf 100644 --- a/src/testing/testing_api_cmd_refund.c +++ b/src/testing/testing_api_cmd_refund.c @@ -43,11 +43,6 @@ struct RefundState */ const char *refund_amount; - /** - * Expected refund fee. - */ - const char *refund_fee; - /** * Reference to any command that can provide a coin to refund. */ @@ -133,7 +128,6 @@ refund_run (void *cls, struct TALER_CoinSpendPublicKeyP coin; const json_t *contract_terms; struct GNUNET_HashCode h_contract_terms; - struct TALER_Amount refund_fee; struct TALER_Amount refund_amount; const struct TALER_MerchantPrivateKeyP *merchant_priv; const struct TALER_TESTING_Command *coin_cmd; @@ -153,19 +147,6 @@ refund_run (void *cls, TALER_TESTING_interpreter_fail (is); return; } - if (GNUNET_OK != - TALER_string_to_amount (rs->refund_fee, - &refund_fee)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse amount `%s' at %u/%s\n", - rs->refund_fee, - is->ip, - cmd->label); - TALER_TESTING_interpreter_fail (is); - return; - } - coin_cmd = TALER_TESTING_interpreter_lookup_command (is, rs->coin_reference); if (NULL == coin_cmd) @@ -211,7 +192,6 @@ refund_run (void *cls, } rs->rh = TALER_EXCHANGE_refund (rs->exchange, &refund_amount, - &refund_fee, &h_contract_terms, &coin, rs->refund_transaction_id, @@ -254,7 +234,6 @@ refund_cleanup (void *cls, * @param label command label. * @param expected_response_code expected HTTP status code. * @param refund_amount the amount to ask a refund for. - * @param refund_fee expected refund fee. * @param coin_reference reference to a command that can * provide a coin to be refunded. * @@ -264,7 +243,6 @@ struct TALER_TESTING_Command TALER_TESTING_cmd_refund (const char *label, unsigned int expected_response_code, const char *refund_amount, - const char *refund_fee, const char *coin_reference) { struct RefundState *rs; @@ -273,7 +251,6 @@ TALER_TESTING_cmd_refund (const char *label, rs->expected_response_code = expected_response_code; rs->refund_amount = refund_amount; - rs->refund_fee = refund_fee; rs->coin_reference = coin_reference; { struct TALER_TESTING_Command cmd = { @@ -295,7 +272,6 @@ TALER_TESTING_cmd_refund (const char *label, * @param label command label. * @param expected_response_code expected HTTP status code. * @param refund_amount the amount to ask a refund for. - * @param refund_fee expected refund fee. * @param coin_reference reference to a command that can * provide a coin to be refunded. * @param refund_transaction_id transaction id to use @@ -308,7 +284,6 @@ TALER_TESTING_cmd_refund_with_id (const char *label, unsigned int expected_response_code, const char *refund_amount, - const char *refund_fee, const char *coin_reference, uint64_t refund_transaction_id) { @@ -317,7 +292,6 @@ TALER_TESTING_cmd_refund_with_id rs = GNUNET_new (struct RefundState); rs->expected_response_code = expected_response_code; rs->refund_amount = refund_amount; - rs->refund_fee = refund_fee; rs->coin_reference = coin_reference; rs->refund_transaction_id = refund_transaction_id; { -- cgit v1.2.3 From 77ab94eb6869ec3494d435b6ee285fd58be3d30d Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 3 May 2020 19:54:36 +0200 Subject: update exchange API to return struct instead of lots of individual args for TALER_EXCHANGE_transfers_get() -- simplifies merchant later --- src/include/taler_exchange_service.h | 72 ++++++++++--- src/lib/exchange_api_transfers_get.c | 164 ++++++++++++++--------------- src/testing/testing_api_cmd_transfer_get.c | 33 ++---- 3 files changed, 140 insertions(+), 129 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index a57a2655a..307a76de8 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1580,32 +1580,68 @@ TALER_EXCHANGE_link_cancel (struct TALER_EXCHANGE_LinkHandle *lh); struct TALER_EXCHANGE_TransfersGetHandle; +/** + * Information the exchange returns per wire transfer. + */ +struct TALER_EXCHANGE_TransferData +{ + + /** + * exchange key used to sign + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * exchange signature over the transfer data + */ + struct TALER_ExchangeSignatureP exchange_sig; + + /** + * hash of the wire transfer address the transfer went to + */ + struct GNUNET_HashCode h_wire; + + /** + * time when the exchange claims to have performed the wire transfer + */ + struct GNUNET_TIME_Absolute execution_time; + + /** + * amount of the wire transfer + */ + struct TALER_Amount total_amount; + + /** + * wire fee that was charged by the exchange + */ + struct TALER_Amount wire_fee; + + /** + * length of the @e details array + */ + unsigned int details_length; + + /** + * array with details about the combined transactions + */ + const struct TALER_TrackTransferDetails *details; + +}; + + /** * Function called with detailed wire transfer data, including all * of the coin transactions that were combined into the wire transfer. * * @param cls closure * @param hr HTTP response data - * @param sign_key exchange key used to sign @a json, or NULL - * @param h_wire hash of the wire transfer address the transfer went to, or NULL on error - * @param execution_time time when the exchange claims to have performed the wire transfer - * @param total_amount total amount of the wire transfer, or NULL if the exchange could - * not provide any @a wtid (set only if @a http_status is #MHD_HTTP_OK) - * @param wire_fee wire fee that was charged by the exchange - * @param details_length length of the @a details array - * @param details array with details about the combined transactions + * @param ta transfer data, (set only if @a http_status is #MHD_HTTP_OK, otherwise NULL) */ typedef void (*TALER_EXCHANGE_TransfersGetCallback)( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *sign_key, - const struct GNUNET_HashCode *h_wire, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *total_amount, - const struct TALER_Amount *wire_fee, - unsigned int details_length, - const struct TALER_TrackTransferDetails *details); + const struct TALER_EXCHANGE_TransferData *ta); /** @@ -1651,17 +1687,19 @@ struct TALER_EXCHANGE_DepositGetHandle; * * @param cls closure * @param hr HTTP response data - * @param sign_key exchange key used to sign @a json, or NULL + * @param exchange_pub exchange key used to sign @a json, or NULL * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not * yet execute the transaction * @param execution_time actual or planned execution time for the wire transfer * @param coin_contribution contribution to the total amount by this coin (can be NULL) + * // FIXME: also return the exchange signature + * // FIXME: combine all of the above (except cls,hr) into a 'struct'! => DepositData */ typedef void (*TALER_EXCHANGE_DepositGetCallback)( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *sign_key, + const struct TALER_ExchangePublicKeyP *exchange_pub, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute execution_time, const struct TALER_Amount *coin_contribution); diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c index 552536958..dd9b64467 100644 --- a/src/lib/exchange_api_transfers_get.c +++ b/src/lib/exchange_api_transfers_get.c @@ -85,24 +85,18 @@ check_transfers_get_response_ok ( const json_t *json) { json_t *details_j; - struct GNUNET_HashCode h_wire; - struct GNUNET_TIME_Absolute exec_time; - struct TALER_Amount total_amount; + struct TALER_EXCHANGE_TransferData td; struct TALER_Amount total_expected; - struct TALER_Amount wire_fee; struct TALER_MerchantPublicKeyP merchant_pub; - unsigned int num_details; - struct TALER_ExchangePublicKeyP exchange_pub; - struct TALER_ExchangeSignatureP exchange_sig; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount ("total", &total_amount), - TALER_JSON_spec_amount ("wire_fee", &wire_fee), + TALER_JSON_spec_amount ("total", &td.total_amount), + TALER_JSON_spec_amount ("wire_fee", &td.wire_fee), GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub), - GNUNET_JSON_spec_fixed_auto ("h_wire", &h_wire), - GNUNET_JSON_spec_absolute_time ("execution_time", &exec_time), + GNUNET_JSON_spec_fixed_auto ("h_wire", &td.h_wire), + GNUNET_JSON_spec_absolute_time ("execution_time", &td.execution_time), GNUNET_JSON_spec_json ("deposits", &details_j), - GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", &td.exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", &td.exchange_pub), GNUNET_JSON_spec_end () }; struct TALER_EXCHANGE_HttpResponse hr = { @@ -119,22 +113,32 @@ check_transfers_get_response_ok ( return GNUNET_SYSERR; } if (GNUNET_OK != - TALER_amount_get_zero (total_amount.currency, + TALER_amount_get_zero (td.total_amount.currency, &total_expected)) { GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - num_details = json_array_size (details_j); + if (GNUNET_OK != + TALER_EXCHANGE_test_signing_key ( + TALER_EXCHANGE_get_keys (wdh->exchange), + &td.exchange_pub)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + return GNUNET_SYSERR; + } + td.details_length = json_array_size (details_j); { - struct TALER_TrackTransferDetails details[num_details]; - unsigned int i; struct GNUNET_HashContext *hash_context; - struct TALER_WireDepositDetailP dd; - struct TALER_WireDepositDataPS wdp; + struct TALER_TrackTransferDetails *details; + details = GNUNET_new_array (td.details_length, + struct TALER_TrackTransferDetails); + td.details = details; hash_context = GNUNET_CRYPTO_hash_context_start (); - for (i = 0; ih_contract_terms; - dd.execution_time = GNUNET_TIME_absolute_hton (exec_time); - dd.coin_pub = detail->coin_pub; - TALER_amount_hton (&dd.deposit_value, - &detail->coin_value); - TALER_amount_hton (&dd.deposit_fee, - &detail->coin_fee); - if ( (0 > + if ( (GNUNET_OK != + GNUNET_JSON_parse (detail_j, + spec_detail, + NULL, NULL)) || + (0 > TALER_amount_add (&total_expected, &total_expected, &detail->coin_value)) || @@ -177,71 +167,78 @@ check_transfers_get_response_ok ( GNUNET_break_op (0); GNUNET_CRYPTO_hash_context_abort (hash_context); GNUNET_JSON_parse_free (spec); + GNUNET_free (details); return GNUNET_SYSERR; } - GNUNET_CRYPTO_hash_context_read ( - hash_context, - &dd, - sizeof (struct TALER_WireDepositDetailP)); + /* build up big hash for signature checking later */ + { + struct TALER_WireDepositDetailP dd; + + dd.h_contract_terms = detail->h_contract_terms; + dd.execution_time = GNUNET_TIME_absolute_hton (td.execution_time); + dd.coin_pub = detail->coin_pub; + TALER_amount_hton (&dd.deposit_value, + &detail->coin_value); + TALER_amount_hton (&dd.deposit_fee, + &detail->coin_fee); + GNUNET_CRYPTO_hash_context_read (hash_context, + &dd, + sizeof (dd)); + } } /* Check signature */ - wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT); - wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS)); - TALER_amount_hton (&wdp.total, - &total_amount); - TALER_amount_hton (&wdp.wire_fee, - &wire_fee); - wdp.merchant_pub = merchant_pub; - wdp.h_wire = h_wire; - GNUNET_CRYPTO_hash_context_finish (hash_context, - &wdp.h_details); - if (GNUNET_OK != - TALER_EXCHANGE_test_signing_key (TALER_EXCHANGE_get_keys ( - wdh->exchange), - &exchange_pub)) { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, - &wdp, - &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; + struct TALER_WireDepositDataPS wdp = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT), + .purpose.size = htonl (sizeof (wdp)), + .merchant_pub = merchant_pub, + .h_wire = td.h_wire + }; + + TALER_amount_hton (&wdp.total, + &td.total_amount); + TALER_amount_hton (&wdp.wire_fee, + &td.wire_fee); + GNUNET_CRYPTO_hash_context_finish (hash_context, + &wdp.h_details); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, + &wdp, + &td.exchange_sig.eddsa_signature, + &td.exchange_pub.eddsa_pub)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + GNUNET_free (details); + return GNUNET_SYSERR; + } } if (0 > TALER_amount_subtract (&total_expected, &total_expected, - &wire_fee)) + &td.wire_fee)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); + GNUNET_free (details); return GNUNET_SYSERR; } if (0 != TALER_amount_cmp (&total_expected, - &total_amount)) + &td.total_amount)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); + GNUNET_free (details); return GNUNET_SYSERR; } wdh->cb (wdh->cb_cls, &hr, - &exchange_pub, - &h_wire, - exec_time, - &total_amount, - &wire_fee, - num_details, - details); + &td); + GNUNET_free (details); } GNUNET_JSON_parse_free (spec); TALER_EXCHANGE_transfers_get_cancel (wdh); @@ -322,12 +319,7 @@ handle_transfers_get_finished (void *cls, } wdh->cb (wdh->cb_cls, &hr, - NULL, - NULL, - GNUNET_TIME_UNIT_ZERO_ABS, - NULL, - NULL, - 0, NULL); + NULL); TALER_EXCHANGE_transfers_get_cancel (wdh); } diff --git a/src/testing/testing_api_cmd_transfer_get.c b/src/testing/testing_api_cmd_transfer_get.c index 699313e56..3ca319cb5 100644 --- a/src/testing/testing_api_cmd_transfer_get.c +++ b/src/testing/testing_api_cmd_transfer_get.c @@ -121,37 +121,18 @@ track_transfer_cleanup (void *cls, * * @param cls closure. * @param hr HTTP response details - * @param exchange_pub public key the exchange used for signing - * the response. - * @param h_wire hash of the wire transfer address the transfer - * went to, or NULL on error. - * @param execution_time time when the exchange claims to have - * performed the wire transfer. - * @param total_amount total amount of the wire transfer, or NULL - * if the exchange could not provide any @a wtid (set only - * if @a http_status is "200 OK"). - * @param wire_fee wire fee that was charged by the exchange. - * @param details_length length of the @a details array. - * @param details array with details about the combined - * transactions. + * @param ta transfer data returned by the exchange */ static void track_transfer_cb (void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const struct GNUNET_HashCode *h_wire, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *total_amount, - const struct TALER_Amount *wire_fee, - unsigned int details_length, - const struct TALER_TrackTransferDetails *details) + const struct TALER_EXCHANGE_TransferData *ta) { struct TrackTransferState *tts = cls; struct TALER_TESTING_Interpreter *is = tts->is; struct TALER_TESTING_Command *cmd = &is->commands[is->ip]; struct TALER_Amount expected_amount; - (void) exchange_pub; tts->tth = NULL; if (tts->expected_response_code != hr->http_status) { @@ -193,14 +174,14 @@ track_transfer_cb (void *cls, TALER_TESTING_interpreter_fail (is); return; } - if (0 != TALER_amount_cmp (total_amount, + if (0 != TALER_amount_cmp (&ta->total_amount, &expected_amount)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Total amount mismatch to command %s - " "%s vs %s\n", cmd->label, - TALER_amount_to_string (total_amount), + TALER_amount_to_string (&ta->total_amount), TALER_amount_to_string (&expected_amount)); json_dumpf (hr->reply, stderr, @@ -219,7 +200,7 @@ track_transfer_cb (void *cls, return; } - if (0 != TALER_amount_cmp (wire_fee, + if (0 != TALER_amount_cmp (&ta->wire_fee, &expected_amount)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -266,7 +247,7 @@ track_transfer_cb (void *cls, TALER_JSON_merchant_wire_signature_hash (wire_details, &h_wire_details)); if (0 != GNUNET_memcmp (&h_wire_details, - h_wire)) + &ta->h_wire)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wire hash missmath to command %s\n", @@ -301,7 +282,7 @@ track_transfer_cb (void *cls, TALER_TESTING_interpreter_fail (is); return; } - if (0 != TALER_amount_cmp (total_amount, + if (0 != TALER_amount_cmp (&ta->total_amount, total_amount_from_reference)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -- cgit v1.2.3 From cde71b7fe74c2a5abb32bf07d40a112e9d7b1135 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 3 May 2020 20:07:49 +0200 Subject: modify TALER_EXCHANGE_deposits_get() API to combine returned arguments into a struct (simplifies merchant later) --- src/include/taler_exchange_service.h | 52 +++++++++++++++----- src/lib/exchange_api_deposits_get.c | 77 +++++++++++++++++------------- src/testing/testing_api_cmd_deposits_get.c | 21 ++------ 3 files changed, 89 insertions(+), 61 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 307a76de8..320123041 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1682,27 +1682,57 @@ TALER_EXCHANGE_transfers_get_cancel ( struct TALER_EXCHANGE_DepositGetHandle; +/** + * Data returned for a successful GET /deposits/ request. Note that + * most fields are only set if the status is #MHD_HTTP_OK. Only + * the @e execution_time is available if the status is #MHD_HTTP_ACCEPTED. + */ +struct TALER_EXCHANGE_DepositData +{ + + /** + * exchange key used to sign, NULL if exchange did not + * yet execute the transaction + */ + const struct TALER_ExchangePublicKeyP *exchange_pub; + + /** + * signature from the exchange over the deposit data, NULL if exchange did not + * yet execute the transaction + */ + const struct TALER_ExchangeSignatureP *exchange_sig; + + /** + * wire transfer identifier used by the exchange, NULL if exchange did not + * yet execute the transaction + */ + const struct TALER_WireTransferIdentifierRawP *wtid; + + /** + * actual or planned execution time for the wire transfer + */ + struct GNUNET_TIME_Absolute execution_time; + + /** + * contribution to the total amount by this coin, NULL if exchange did not + * yet execute the transaction + */ + const struct TALER_Amount *coin_contribution; +}; + + /** * Function called with detailed wire transfer data. * * @param cls closure * @param hr HTTP response data - * @param exchange_pub exchange key used to sign @a json, or NULL - * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not - * yet execute the transaction - * @param execution_time actual or planned execution time for the wire transfer - * @param coin_contribution contribution to the total amount by this coin (can be NULL) - * // FIXME: also return the exchange signature - * // FIXME: combine all of the above (except cls,hr) into a 'struct'! => DepositData + * @param dd details about the deposit (NULL on errors) */ typedef void (*TALER_EXCHANGE_DepositGetCallback)( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *coin_contribution); + const struct TALER_EXCHANGE_DepositData *dd); /** diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c index aecd88240..6a2ad5c3d 100644 --- a/src/lib/exchange_api_deposits_get.c +++ b/src/lib/exchange_api_deposits_get.c @@ -33,7 +33,7 @@ /** - * @brief A Deposit Wtid Handle + * @brief A Deposit Get Handle */ struct TALER_EXCHANGE_DepositGetHandle { @@ -84,31 +84,19 @@ struct TALER_EXCHANGE_DepositGetHandle * * @param dwh deposit wtid handle * @param json json reply with the signature - * @param[out] exchange_pub set to the exchange's public key + * @param exchange_pub the exchange's public key + * @param exchange_sig the exchange's signature * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_deposit_wtid_signature_ok ( const struct TALER_EXCHANGE_DepositGetHandle *dwh, const json_t *json, - struct TALER_ExchangePublicKeyP *exchange_pub) + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_ExchangeSignatureP *exchange_sig) { - struct TALER_ExchangeSignatureP exchange_sig; const struct TALER_EXCHANGE_Keys *key_state; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), - GNUNET_JSON_spec_end () - }; - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } key_state = TALER_EXCHANGE_get_keys (dwh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, @@ -120,7 +108,7 @@ verify_deposit_wtid_signature_ok ( if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE, &dwh->depconf, - &exchange_sig.eddsa_signature, + &exchange_sig->eddsa_signature, &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); @@ -144,12 +132,6 @@ handle_deposit_wtid_finished (void *cls, const void *response) { struct TALER_EXCHANGE_DepositGetHandle *dwh = cls; - const struct TALER_WireTransferIdentifierRawP *wtid = NULL; - struct GNUNET_TIME_Absolute execution_time = GNUNET_TIME_UNIT_FOREVER_ABS; - const struct TALER_Amount *coin_contribution = NULL; - struct TALER_Amount coin_contribution_s; - struct TALER_ExchangePublicKeyP exchange_pub; - struct TALER_ExchangePublicKeyP *ep = NULL; const json_t *j = response; struct TALER_EXCHANGE_HttpResponse hr = { .reply = j, @@ -164,10 +146,16 @@ handle_deposit_wtid_finished (void *cls, break; case MHD_HTTP_OK: { + struct GNUNET_TIME_Absolute execution_time; + struct TALER_Amount coin_contribution; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangeSignatureP exchange_sig; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("wtid", &dwh->depconf.wtid), GNUNET_JSON_spec_absolute_time ("execution_time", &execution_time), - TALER_JSON_spec_amount ("coin_contribution", &coin_contribution_s), + TALER_JSON_spec_amount ("coin_contribution", &coin_contribution), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), GNUNET_JSON_spec_end () }; @@ -181,15 +169,14 @@ handle_deposit_wtid_finished (void *cls, hr.ec = TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE; break; } - wtid = &dwh->depconf.wtid; dwh->depconf.execution_time = GNUNET_TIME_absolute_hton (execution_time); TALER_amount_hton (&dwh->depconf.coin_contribution, - &coin_contribution_s); - coin_contribution = &coin_contribution_s; + &coin_contribution); if (GNUNET_OK != verify_deposit_wtid_signature_ok (dwh, j, - &exchange_pub)) + &exchange_pub, + &exchange_sig)) { GNUNET_break_op (0); hr.http_status = 0; @@ -197,13 +184,26 @@ handle_deposit_wtid_finished (void *cls, } else { - ep = &exchange_pub; + struct TALER_EXCHANGE_DepositData dd = { + .exchange_pub = &exchange_pub, + .exchange_sig = &exchange_sig, + .wtid = &dwh->depconf.wtid, + .execution_time = execution_time, + .coin_contribution = &coin_contribution + }; + + dwh->cb (dwh->cb_cls, + &hr, + &dd); + TALER_EXCHANGE_deposits_get_cancel (dwh); + return; } } break; case MHD_HTTP_ACCEPTED: { /* Transaction known, but not executed yet */ + struct GNUNET_TIME_Absolute execution_time; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_absolute_time ("execution_time", &execution_time), GNUNET_JSON_spec_end () @@ -219,6 +219,18 @@ handle_deposit_wtid_finished (void *cls, hr.ec = TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE; break; } + else + { + struct TALER_EXCHANGE_DepositData dd = { + .execution_time = execution_time + }; + + dwh->cb (dwh->cb_cls, + &hr, + &dd); + TALER_EXCHANGE_deposits_get_cancel (dwh); + return; + } } break; case MHD_HTTP_BAD_REQUEST: @@ -259,10 +271,7 @@ handle_deposit_wtid_finished (void *cls, } dwh->cb (dwh->cb_cls, &hr, - ep, - wtid, - execution_time, - coin_contribution); + NULL); TALER_EXCHANGE_deposits_get_cancel (dwh); } diff --git a/src/testing/testing_api_cmd_deposits_get.c b/src/testing/testing_api_cmd_deposits_get.c index fd02e75bb..6f0140116 100644 --- a/src/testing/testing_api_cmd_deposits_get.c +++ b/src/testing/testing_api_cmd_deposits_get.c @@ -81,29 +81,17 @@ struct TrackTransactionState * * @param cls closure. * @param hr HTTP response details - * @param exchange_pub public key of the exchange - * @param wtid wire transfer identifier, NULL if exchange did not - * execute the transaction yet. - * @param execution_time actual or planned execution time for the - * wire transfer. - * @param coin_contribution contribution to the total amount of - * the deposited coin (can be NULL). + * @param dd data about the wire transfer associated with the deposit */ static void deposit_wtid_cb (void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *coin_contribution) + const struct TALER_EXCHANGE_DepositData *dd) { struct TrackTransactionState *tts = cls; struct TALER_TESTING_Interpreter *is = tts->is; struct TALER_TESTING_Command *cmd = &is->commands[is->ip]; - (void) coin_contribution; - (void) exchange_pub; - (void) execution_time; tts->tth = NULL; if (tts->expected_response_code != hr->http_status) { @@ -123,7 +111,8 @@ deposit_wtid_cb (void *cls, switch (hr->http_status) { case MHD_HTTP_OK: - tts->wtid = *wtid; + GNUNET_assert (NULL != dd->wtid); + tts->wtid = *dd->wtid; if (NULL != tts->bank_transfer_reference) { const struct TALER_TESTING_Command *bank_transfer_cmd; @@ -151,7 +140,7 @@ deposit_wtid_cb (void *cls, } /* Compare that expected and gotten subjects match. */ - if (0 != GNUNET_memcmp (wtid, + if (0 != GNUNET_memcmp (dd->wtid, wtid_want)) { GNUNET_break (0); -- cgit v1.2.3 From 4844023f6904d2281cc90fe23d372978a9d9c137 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 3 May 2020 20:12:18 +0200 Subject: modify TALER_EXCHANGE_deposits_get() API to avoid NULL pointers and need for deep copies --- src/include/taler_exchange_service.h | 16 +++++++-------- src/lib/exchange_api_deposits_get.c | 31 +++++++++++------------------- src/testing/testing_api_cmd_deposits_get.c | 5 ++--- 3 files changed, 21 insertions(+), 31 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 320123041..f94b8253d 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1691,22 +1691,22 @@ struct TALER_EXCHANGE_DepositData { /** - * exchange key used to sign, NULL if exchange did not + * exchange key used to sign, all zeros if exchange did not * yet execute the transaction */ - const struct TALER_ExchangePublicKeyP *exchange_pub; + struct TALER_ExchangePublicKeyP exchange_pub; /** - * signature from the exchange over the deposit data, NULL if exchange did not + * signature from the exchange over the deposit data, all zeros if exchange did not * yet execute the transaction */ - const struct TALER_ExchangeSignatureP *exchange_sig; + struct TALER_ExchangeSignatureP exchange_sig; /** - * wire transfer identifier used by the exchange, NULL if exchange did not + * wire transfer identifier used by the exchange, all zeros if exchange did not * yet execute the transaction */ - const struct TALER_WireTransferIdentifierRawP *wtid; + struct TALER_WireTransferIdentifierRawP wtid; /** * actual or planned execution time for the wire transfer @@ -1714,10 +1714,10 @@ struct TALER_EXCHANGE_DepositData struct GNUNET_TIME_Absolute execution_time; /** - * contribution to the total amount by this coin, NULL if exchange did not + * contribution to the total amount by this coin, all zeros if exchange did not * yet execute the transaction */ - const struct TALER_Amount *coin_contribution; + struct TALER_Amount coin_contribution; }; diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c index 6a2ad5c3d..004a24d42 100644 --- a/src/lib/exchange_api_deposits_get.c +++ b/src/lib/exchange_api_deposits_get.c @@ -146,16 +146,13 @@ handle_deposit_wtid_finished (void *cls, break; case MHD_HTTP_OK: { - struct GNUNET_TIME_Absolute execution_time; - struct TALER_Amount coin_contribution; - struct TALER_ExchangePublicKeyP exchange_pub; - struct TALER_ExchangeSignatureP exchange_sig; + struct TALER_EXCHANGE_DepositData dd; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("wtid", &dwh->depconf.wtid), - GNUNET_JSON_spec_absolute_time ("execution_time", &execution_time), - TALER_JSON_spec_amount ("coin_contribution", &coin_contribution), - GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), + GNUNET_JSON_spec_absolute_time ("execution_time", &dd.execution_time), + TALER_JSON_spec_amount ("coin_contribution", &dd.coin_contribution), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", &dd.exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", &dd.exchange_pub), GNUNET_JSON_spec_end () }; @@ -169,14 +166,15 @@ handle_deposit_wtid_finished (void *cls, hr.ec = TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE; break; } - dwh->depconf.execution_time = GNUNET_TIME_absolute_hton (execution_time); + dwh->depconf.execution_time = GNUNET_TIME_absolute_hton ( + dd.execution_time); TALER_amount_hton (&dwh->depconf.coin_contribution, - &coin_contribution); + &dd.coin_contribution); if (GNUNET_OK != verify_deposit_wtid_signature_ok (dwh, j, - &exchange_pub, - &exchange_sig)) + &dd.exchange_pub, + &dd.exchange_sig)) { GNUNET_break_op (0); hr.http_status = 0; @@ -184,14 +182,7 @@ handle_deposit_wtid_finished (void *cls, } else { - struct TALER_EXCHANGE_DepositData dd = { - .exchange_pub = &exchange_pub, - .exchange_sig = &exchange_sig, - .wtid = &dwh->depconf.wtid, - .execution_time = execution_time, - .coin_contribution = &coin_contribution - }; - + dd.wtid = dwh->depconf.wtid; dwh->cb (dwh->cb_cls, &hr, &dd); diff --git a/src/testing/testing_api_cmd_deposits_get.c b/src/testing/testing_api_cmd_deposits_get.c index 6f0140116..33987e161 100644 --- a/src/testing/testing_api_cmd_deposits_get.c +++ b/src/testing/testing_api_cmd_deposits_get.c @@ -111,8 +111,7 @@ deposit_wtid_cb (void *cls, switch (hr->http_status) { case MHD_HTTP_OK: - GNUNET_assert (NULL != dd->wtid); - tts->wtid = *dd->wtid; + tts->wtid = dd->wtid; if (NULL != tts->bank_transfer_reference) { const struct TALER_TESTING_Command *bank_transfer_cmd; @@ -140,7 +139,7 @@ deposit_wtid_cb (void *cls, } /* Compare that expected and gotten subjects match. */ - if (0 != GNUNET_memcmp (dd->wtid, + if (0 != GNUNET_memcmp (&dd->wtid, wtid_want)) { GNUNET_break (0); -- cgit v1.2.3 From 727b7b04f3ae23fd49da7479fe4b4258513aef83 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 5 May 2020 22:17:16 +0200 Subject: return fee as well --- src/include/taler_error_codes.h | 19 +++++++++++++++++++ src/include/taler_exchange_service.h | 2 ++ src/lib/exchange_api_refund.c | 4 +++- src/testing/testing_api_cmd_refund.c | 3 +++ 4 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h index f75464c35..74660303d 100644 --- a/src/include/taler_error_codes.h +++ b/src/include/taler_error_codes.h @@ -2198,6 +2198,25 @@ enum TALER_ErrorCode */ TALER_EC_TIP_PICKUP_UNBLIND_FAILURE = 2812, + /** + * We failed to fetch contract terms from our merchant database. The + * response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR = 2900, + + /** + * We failed to find the contract terms from our merchant database. + * The response is provided with HTTP status code #MHD_HTTP_NOT_FOUND. + */ + TALER_EC_GET_ORDERS_ID_UNKNOWN = 2901, + + /** + * The contract hash provided by the wallet does not match the order. + * The response is provided with HTTP status code #MHD_HTTP_FORBIDDEN. + */ + TALER_EC_GET_ORDERS_WRONG_CONTRACT = 2902, + /** * We failed to contract terms from our merchant database. The * response is provided with HTTP status code diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index f94b8253d..82b9b83df 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -851,6 +851,7 @@ struct TALER_EXCHANGE_RefundHandle; * * @param cls closure * @param hr HTTP response data + * @param refund_fee the refund fee the exchange charged us * @param sign_key exchange key used to sign @a obj, or NULL * @param signature the actual signature, or NULL on error */ @@ -858,6 +859,7 @@ typedef void (*TALER_EXCHANGE_RefundCallback) ( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + const struct TALER_Amount *refund_fee, const struct TALER_ExchangePublicKeyP *sign_key, const struct TALER_ExchangeSignatureP *signature); diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 9cb8794d3..b1ea176bf 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -92,7 +92,6 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh, const json_t *json, struct TALER_ExchangePublicKeyP *exchange_pub, struct TALER_ExchangeSignatureP *exchange_sig) - { const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { @@ -149,6 +148,7 @@ handle_refund_finished (void *cls, struct TALER_ExchangeSignatureP exchange_sig; struct TALER_ExchangePublicKeyP *ep = NULL; struct TALER_ExchangeSignatureP *es = NULL; + struct TALER_Amount *rf = NULL; const json_t *j = response; struct TALER_EXCHANGE_HttpResponse hr = { .reply = j, @@ -176,6 +176,7 @@ handle_refund_finished (void *cls, { ep = &exchange_pub; es = &exchange_sig; + rf = &rh->depconf.refund_fee; } break; case MHD_HTTP_BAD_REQUEST: @@ -234,6 +235,7 @@ handle_refund_finished (void *cls, } rh->cb (rh->cb_cls, &hr, + rf, ep, es); TALER_EXCHANGE_refund_cancel (rh); diff --git a/src/testing/testing_api_cmd_refund.c b/src/testing/testing_api_cmd_refund.c index c27311fbf..e662ace2e 100644 --- a/src/testing/testing_api_cmd_refund.c +++ b/src/testing/testing_api_cmd_refund.c @@ -76,6 +76,7 @@ struct RefundState * * @param cls closure * @param hr HTTP response details + * @param refund_fee the refund fee the exchange charged * @param exchange_pub public key the exchange * used for signing @a obj. * @param exchange_sig actual signature confirming the refund @@ -83,6 +84,7 @@ struct RefundState static void refund_cb (void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + const struct TALER_Amount *refund_fee, const struct TALER_ExchangePublicKeyP *exchange_pub, const struct TALER_ExchangeSignatureP *exchange_sig) { @@ -90,6 +92,7 @@ refund_cb (void *cls, struct RefundState *rs = cls; struct TALER_TESTING_Command *refund_cmd; + (void) refund_fee; refund_cmd = &rs->is->commands[rs->is->ip]; rs->rh = NULL; if (rs->expected_response_code != hr->http_status) -- cgit v1.2.3 From 4f82885560d5d468ef5230f7ec383c612cc9625c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 7 May 2020 20:22:02 +0200 Subject: towards changing timestamp in deposit confirmation (tests failing) --- .../taler-auditor-httpd_deposit-confirmation.c | 5 +- src/auditor/taler-helper-auditor-coins.c | 8 +- src/auditor/taler-helper-auditor-deposits.c | 9 +- src/auditordb/auditor-0001.sql | 2 +- src/auditordb/plugin_auditordb_postgres.c | 10 +- src/exchange/taler-exchange-aggregator.c | 12 ++ src/exchange/taler-exchange-httpd_deposit.c | 173 +++++++++++---------- src/exchange/taler-exchange-httpd_responses.c | 2 +- src/exchangedb/exchange-0001.sql | 3 +- src/exchangedb/plugin_exchangedb_postgres.c | 62 ++++++-- src/exchangedb/test_exchangedb.c | 71 ++++++--- src/include/taler_auditordb_plugin.h | 4 +- src/include/taler_error_codes.h | 45 ++++-- src/include/taler_exchange_service.h | 2 + src/include/taler_exchangedb_plugin.h | 18 ++- src/include/taler_signatures.h | 7 +- src/include/taler_testing_lib.h | 18 ++- src/lib/auditor_api_deposit_confirmation.c | 17 +- src/lib/exchange_api_common.c | 2 +- src/lib/exchange_api_deposit.c | 9 +- src/lib/exchange_api_refund.c | 7 +- src/testing/test_taler_exchange_aggregator.c | 24 +++ .../testing_api_cmd_auditor_deposit_confirmation.c | 8 +- src/testing/testing_api_cmd_deposit.c | 35 +++-- src/testing/testing_api_cmd_insert_deposit.c | 26 +++- 25 files changed, 390 insertions(+), 189 deletions(-) (limited to 'src/lib') diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c index 5f84a7253..1039164c4 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c @@ -155,7 +155,7 @@ verify_and_execute_deposit_confirmation ( .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)), .h_contract_terms = dc->h_contract_terms, .h_wire = dc->h_wire, - .timestamp = GNUNET_TIME_absolute_hton (dc->timestamp), + .exchange_timestamp = GNUNET_TIME_absolute_hton (dc->exchange_timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (dc->refund_deadline), .coin_pub = dc->coin_pub, .merchant = dc->merchant @@ -224,7 +224,8 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &dc.h_contract_terms), GNUNET_JSON_spec_fixed_auto ("h_wire", &dc.h_wire), - GNUNET_JSON_spec_absolute_time ("timestamp", &dc.timestamp), + GNUNET_JSON_spec_absolute_time ("exchange_timestamp", + &dc.exchange_timestamp), GNUNET_JSON_spec_absolute_time ("refund_deadline", &dc.refund_deadline), TALER_JSON_spec_amount ("amount_without_fee", &dc.amount_without_fee), GNUNET_JSON_spec_fixed_auto ("coin_pub", &dc.coin_pub), diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 2e32c5698..158baa8b3 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1535,7 +1535,8 @@ refresh_session_cb (void *cls, * * @param cls closure * @param rowid unique serial ID for the deposit in our DB - * @param timestamp when did the deposit happen + * @param exchange_timestamp when did the exchange get the deposit + * @param wallet_timestamp when did the contract signing happen * @param merchant_pub public key of the merchant * @param denom_pub denomination public key of @a coin_pub * @param coin_pub public key of the coin @@ -1553,7 +1554,8 @@ refresh_session_cb (void *cls, static int deposit_cb (void *cls, uint64_t rowid, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1611,7 +1613,7 @@ deposit_cb (void *cls, .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), .purpose.size = htonl (sizeof (dr)), .h_contract_terms = *h_contract_terms, - .timestamp = GNUNET_TIME_absolute_hton (timestamp), + .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .deposit_fee = issue->fee_deposit, .merchant = *merchant_pub, diff --git a/src/auditor/taler-helper-auditor-deposits.c b/src/auditor/taler-helper-auditor-deposits.c index 291558590..ed23c6a52 100644 --- a/src/auditor/taler-helper-auditor-deposits.c +++ b/src/auditor/taler-helper-auditor-deposits.c @@ -114,11 +114,15 @@ test_dc (void *cls, .h_wire = dc->h_wire, .refund_deadline = dc->refund_deadline }; + struct GNUNET_TIME_Absolute exchange_timestamp; + struct TALER_Amount deposit_fee; qs = TALER_ARL_edb->have_deposit (TALER_ARL_edb->cls, TALER_ARL_esession, &dep, - GNUNET_NO /* do not check refund deadline */); + GNUNET_NO /* do not check refund deadline */, + &deposit_fee, + &exchange_timestamp); if (qs > 0) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -137,7 +141,8 @@ test_dc (void *cls, TALER_ARL_report (report_deposit_confirmation_inconsistencies, json_pack ("{s:o, s:o, s:I, s:o}", "timestamp", - TALER_ARL_json_from_time_abs (dc->timestamp), + TALER_ARL_json_from_time_abs ( + dc->exchange_timestamp), "amount", TALER_JSON_from_amount (&dc->amount_without_fee), "rowid", diff --git a/src/auditordb/auditor-0001.sql b/src/auditordb/auditor-0001.sql index ff8867bee..b511a4d5b 100644 --- a/src/auditordb/auditor-0001.sql +++ b/src/auditordb/auditor-0001.sql @@ -251,7 +251,7 @@ CREATE TABLE IF NOT EXISTS deposit_confirmations ,serial_id BIGSERIAL UNIQUE ,h_contract_terms BYTEA CHECK (LENGTH(h_contract_terms)=64) ,h_wire BYTEA CHECK (LENGTH(h_wire)=64) - ,timestamp INT8 NOT NULL + ,exchange_timestamp INT8 NOT NULL ,refund_deadline INT8 NOT NULL ,amount_without_fee_val INT8 NOT NULL ,amount_without_fee_frac INT4 NOT NULL diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 467c4c6db..4f9101fdc 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -269,7 +269,7 @@ postgres_get_session (void *cls) "(master_pub" ",h_contract_terms" ",h_wire" - ",timestamp" + ",exchange_timestamp" ",refund_deadline" ",amount_without_fee_val" ",amount_without_fee_frac" @@ -286,7 +286,7 @@ postgres_get_session (void *cls) " serial_id" ",h_contract_terms" ",h_wire" - ",timestamp" + ",exchange_timestamp" ",refund_deadline" ",amount_without_fee_val" ",amount_without_fee_frac" @@ -1126,7 +1126,7 @@ postgres_insert_deposit_confirmation ( GNUNET_PQ_query_param_auto_from_type (&dc->master_public_key), GNUNET_PQ_query_param_auto_from_type (&dc->h_contract_terms), GNUNET_PQ_query_param_auto_from_type (&dc->h_wire), - TALER_PQ_query_param_absolute_time (&dc->timestamp), + TALER_PQ_query_param_absolute_time (&dc->exchange_timestamp), TALER_PQ_query_param_absolute_time (&dc->refund_deadline), TALER_PQ_query_param_amount (&dc->amount_without_fee), GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub), @@ -1207,8 +1207,8 @@ deposit_confirmation_cb (void *cls, &dc.h_contract_terms), GNUNET_PQ_result_spec_auto_from_type ("h_wire", &dc.h_wire), - GNUNET_PQ_result_spec_absolute_time ("timestamp", - &dc.timestamp), + GNUNET_PQ_result_spec_absolute_time ("exchange_timestamp", + &dc.exchange_timestamp), GNUNET_PQ_result_spec_absolute_time ("refund_deadline", &dc.refund_deadline), TALER_PQ_RESULT_SPEC_AMOUNT ("amount_without_fee", diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 21a29e506..69c73746c 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -330,6 +330,8 @@ refund_by_coin_cb (void *cls, * * @param cls a `struct AggregationUnit` * @param row_id identifies database entry + * @param exchange_timestamp when did the deposit happen + * @param wallet_timestamp when did the contract happen * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin * @param amount_with_fee amount that was deposited including fee @@ -343,6 +345,8 @@ refund_by_coin_cb (void *cls, static enum GNUNET_DB_QueryStatus deposit_cb (void *cls, uint64_t row_id, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, @@ -358,6 +362,8 @@ deposit_cb (void *cls, /* NOTE: potential optimization: use custom SQL API to not fetch this one: */ (void) wire_deadline; /* already checked by SQL query */ + (void) exchange_timestamp; + (void) wallet_timestamp; au->merchant_pub = *merchant_pub; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Aggregator processing payment %s with amount %s\n", @@ -501,6 +507,8 @@ deposit_cb (void *cls, * * @param cls a `struct AggregationUnit` * @param row_id identifies database entry + * @param exchange_timestamp when did the exchange receive the deposit + * @param wallet_timestamp when did the wallet sign the contract * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin * @param amount_with_fee amount that was deposited including fee @@ -514,6 +522,8 @@ deposit_cb (void *cls, static enum GNUNET_DB_QueryStatus aggregate_cb (void *cls, uint64_t row_id, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, @@ -529,6 +539,8 @@ aggregate_cb (void *cls, /* NOTE: potential optimization: use custom SQL API to not fetch these: */ (void) wire_deadline; /* checked by SQL */ + (void) exchange_timestamp; + (void) wallet_timestamp; (void) wire; /* must match */ GNUNET_break (0 == GNUNET_memcmp (&au->merchant_pub, merchant_pub)); diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 65251863a..fe8fdf061 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -47,7 +47,7 @@ * @param coin_pub public key of the coin * @param h_wire hash of wire details * @param h_contract_terms hash of contract details - * @param timestamp client's timestamp + * @param exchange_timestamp exchange's timestamp * @param refund_deadline until when this deposit be refunded * @param merchant merchant public key * @param amount_without_fee fraction of coin value to deposit, without the fee @@ -58,7 +58,7 @@ reply_deposit_success (struct MHD_Connection *connection, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract_terms, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_MerchantPublicKeyP *merchant, const struct TALER_Amount *amount_without_fee) @@ -70,7 +70,7 @@ reply_deposit_success (struct MHD_Connection *connection, .purpose.size = htonl (sizeof (dc)), .h_contract_terms = *h_contract_terms, .h_wire = *h_wire, - .timestamp = GNUNET_TIME_absolute_hton (timestamp), + .exchange_timestamp = GNUNET_TIME_absolute_hton (exchange_timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .coin_pub = *coin_pub, .merchant = *merchant @@ -88,13 +88,16 @@ reply_deposit_success (struct MHD_Connection *connection, TALER_EC_EXCHANGE_BAD_CONFIGURATION, "no keys"); } - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:o, s:o}", - "exchange_sig", - GNUNET_JSON_from_data_auto (&sig), - "exchange_pub", - GNUNET_JSON_from_data_auto (&pub)); + return TALER_MHD_reply_json_pack ( + connection, + MHD_HTTP_OK, + "{s:o, s:o, s:o}", + "exchange_timestamp", + GNUNET_JSON_from_time_abs (exchange_timestamp), + "exchange_sig", + GNUNET_JSON_from_data_auto (&sig), + "exchange_pub", + GNUNET_JSON_from_data_auto (&pub)); } @@ -108,6 +111,11 @@ struct DepositContext */ const struct TALER_EXCHANGEDB_Deposit *deposit; + /** + * Our timestamp (when we received the request). + */ + struct GNUNET_TIME_Absolute exchange_timestamp; + /** * Value of the coin. */ @@ -117,12 +125,11 @@ struct DepositContext /** - * Execute database transaction for /deposit. Runs the transaction - * logic; IF it returns a non-error code, the transaction logic MUST - * NOT queue a MHD response. IF it returns an hard error, the - * transaction logic MUST queue a MHD response and set @a mhd_ret. IF - * it returns the soft error code, the function MAY be called again to - * retry and MUST not queue a MHD response. + * Check if /deposit is already in the database. IF it returns a non-error + * code, the transaction logic MUST NOT queue a MHD response. IF it returns + * an hard error, the transaction logic MUST queue a MHD response and set @a + * mhd_ret. We do return a "hard" error also if we found the deposit in the + * database and generated a regular response. * * @param cls a `struct DepositContext` * @param connection MHD request context @@ -131,20 +138,22 @@ struct DepositContext * @return transaction status */ static enum GNUNET_DB_QueryStatus -deposit_transaction (void *cls, - struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - MHD_RESULT *mhd_ret) +deposit_precheck (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + MHD_RESULT *mhd_ret) { struct DepositContext *dc = cls; const struct TALER_EXCHANGEDB_Deposit *deposit = dc->deposit; - struct TALER_Amount spent; + struct TALER_Amount deposit_fee; enum GNUNET_DB_QueryStatus qs; qs = TEH_plugin->have_deposit (TEH_plugin->cls, session, deposit, - GNUNET_YES /* check refund deadline */); + GNUNET_YES /* check refund deadline */, + &deposit_fee, + &dc->exchange_timestamp); if (qs < 0) { if (GNUNET_DB_STATUS_HARD_ERROR == qs) @@ -166,12 +175,12 @@ deposit_transaction (void *cls, GNUNET_assert (0 <= TALER_amount_subtract (&amount_without_fee, &deposit->amount_with_fee, - &deposit->deposit_fee)); + &deposit_fee)); *mhd_ret = reply_deposit_success (connection, &deposit->coin.coin_pub, &deposit->h_wire, &deposit->h_contract_terms, - deposit->timestamp, + dc->exchange_timestamp, deposit->refund_deadline, &deposit->merchant_pub, &amount_without_fee); @@ -179,6 +188,44 @@ deposit_transaction (void *cls, never try again. */ return GNUNET_DB_STATUS_HARD_ERROR; } + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; +} + + +/** + * Execute database transaction for /deposit. Runs the transaction + * logic; IF it returns a non-error code, the transaction logic MUST + * NOT queue a MHD response. IF it returns an hard error, the + * transaction logic MUST queue a MHD response and set @a mhd_ret. IF + * it returns the soft error code, the function MAY be called again to + * retry and MUST not queue a MHD response. + * + * @param cls a `struct DepositContext` + * @param connection MHD request context + * @param session database session and transaction to use + * @param[out] mhd_ret set to MHD status on error + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +deposit_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + MHD_RESULT *mhd_ret) +{ + struct DepositContext *dc = cls; + const struct TALER_EXCHANGEDB_Deposit *deposit = dc->deposit; + struct TALER_Amount spent; + enum GNUNET_DB_QueryStatus qs; + + /* Theoretically, someone other threat may have received + and committed the deposit in the meantime. Check now + that we are in the transaction scope. */ + qs = deposit_precheck (cls, + connection, + session, + mhd_ret); + if (qs < 0) + return qs; /* Start with fee for THIS transaction */ spent = deposit->amount_with_fee; @@ -238,6 +285,7 @@ deposit_transaction (void *cls, } qs = TEH_plugin->insert_deposit (TEH_plugin->cls, session, + dc->exchange_timestamp, deposit); if (GNUNET_DB_STATUS_HARD_ERROR == qs) { @@ -251,45 +299,6 @@ deposit_transaction (void *cls, } -/** - * Check that @a ts is reasonably close to our own RTC. - * - * @param ts timestamp to check - * @return #GNUNET_OK if @a ts is reasonable - */ -static int -check_timestamp_current (struct GNUNET_TIME_Absolute ts) -{ - struct GNUNET_TIME_Relative r; - struct GNUNET_TIME_Relative tolerance; - - /* Let's be VERY generous (after all, this is basically about - which year the deposit counts for in terms of tax purposes) */ - tolerance = GNUNET_TIME_UNIT_MONTHS; - r = GNUNET_TIME_absolute_get_duration (ts); - if (r.rel_value_us > tolerance.rel_value_us) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Deposit timestamp too old: %llu vs %llu > %llu\n", - (unsigned long long) ts.abs_value_us, - (unsigned long long) GNUNET_TIME_absolute_get ().abs_value_us, - (unsigned long long) tolerance.rel_value_us); - return GNUNET_SYSERR; - } - r = GNUNET_TIME_absolute_get_remaining (ts); - if (r.rel_value_us > tolerance.rel_value_us) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Deposit timestamp too new: %llu vs %llu < - %llu\n", - (unsigned long long) ts.abs_value_us, - (unsigned long long) GNUNET_TIME_absolute_get ().abs_value_us, - (unsigned long long) tolerance.rel_value_us); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - /** * Handle a "/coins/$COIN_PUB/deposit" request. Parses the JSON, and, if * successful, passes the JSON data to #deposit_transaction() to @@ -367,17 +376,6 @@ TEH_handler_deposit (struct MHD_Connection *connection, TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, "refund_deadline"); } - - if (GNUNET_OK != - check_timestamp_current (deposit.timestamp)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_DEPOSIT_INVALID_TIMESTAMP, - "timestamp"); - } if (GNUNET_OK != TALER_JSON_merchant_wire_signature_hash (wire, &my_h_wire)) @@ -401,6 +399,26 @@ TEH_handler_deposit (struct MHD_Connection *connection, "h_wire"); } + /* Check for idempotency: did we get this request before? */ + dc.deposit = &deposit; + { + MHD_RESULT mhd_ret; + + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "precheck deposit", + &mhd_ret, + &deposit_precheck, + &dc)) + { + GNUNET_JSON_parse_free (spec); + return mhd_ret; + } + } + + /* new deposit */ + dc.exchange_timestamp = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&dc.exchange_timestamp); /* check denomination exists and is valid */ { struct TEH_KS_StateHandle *key_state; @@ -408,7 +426,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, enum TALER_ErrorCode ec; unsigned int hc; - key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); + key_state = TEH_KS_acquire (dc.exchange_timestamp); if (NULL == key_state) { TALER_LOG_ERROR ("Lacking keys to operate\n"); @@ -502,7 +520,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, .purpose.size = htonl (sizeof (dr)), .h_contract_terms = deposit.h_contract_terms, .h_wire = deposit.h_wire, - .timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp), + .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (deposit.refund_deadline), .merchant = deposit.merchant_pub, .coin_pub = deposit.coin.coin_pub @@ -528,7 +546,6 @@ TEH_handler_deposit (struct MHD_Connection *connection, } /* execute transaction */ - dc.deposit = &deposit; { MHD_RESULT mhd_ret; @@ -557,7 +574,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, &deposit.coin.coin_pub, &deposit.h_wire, &deposit.h_contract_terms, - deposit.timestamp, + dc.exchange_timestamp, deposit.refund_deadline, &deposit.merchant_pub, &amount_without_fee); diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 7924ad54c..f65951614 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -66,7 +66,7 @@ TEH_RESPONSE_compile_transaction_history ( .purpose.size = htonl (sizeof (dr)), .h_contract_terms = deposit->h_contract_terms, .h_wire = deposit->h_wire, - .timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp), + .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp), .refund_deadline = GNUNET_TIME_absolute_hton ( deposit->refund_deadline), .merchant = deposit->merchant_pub, diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index bec9af5ba..ad05e7797 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -254,7 +254,8 @@ CREATE TABLE IF NOT EXISTS deposits ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE ,amount_with_fee_val INT8 NOT NULL ,amount_with_fee_frac INT4 NOT NULL - ,timestamp INT8 NOT NULL + ,wallet_timestamp INT8 NOT NULL + ,exchange_timestamp INT8 NOT NULL ,refund_deadline INT8 NOT NULL ,wire_deadline INT8 NOT NULL ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32) diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 5bd674b2d..93577feb4 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -796,7 +796,7 @@ postgres_get_session (void *cls) "(coin_pub" ",amount_with_fee_val" ",amount_with_fee_frac" - ",timestamp" + ",wallet_timestamp" ",refund_deadline" ",wire_deadline" ",merchant_pub" @@ -804,22 +804,28 @@ postgres_get_session (void *cls) ",h_wire" ",coin_sig" ",wire" + ",exchange_timestamp" ") VALUES " "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," - " $11);", - 11), + " $11, $12);", + 12), /* Fetch an existing deposit request, used to ensure idempotency during /deposit processing. Used in #postgres_have_deposit(). */ GNUNET_PQ_make_prepare ("get_deposit", "SELECT" " amount_with_fee_val" ",amount_with_fee_frac" - ",timestamp" + ",denominations.fee_deposit_val" + ",denominations.fee_deposit_frac" + ",wallet_timestamp" + ",exchange_timestamp" ",refund_deadline" ",wire_deadline" ",h_contract_terms" ",h_wire" " FROM deposits" + " JOIN known_coins USING (coin_pub)" + " JOIN denominations USING (denom_pub_hash)" " WHERE ((coin_pub=$1)" " AND (merchant_pub=$3)" " AND (h_contract_terms=$2))" @@ -830,7 +836,8 @@ postgres_get_session (void *cls) "SELECT" " amount_with_fee_val" ",amount_with_fee_frac" - ",timestamp" + ",wallet_timestamp" + ",exchange_timestamp" ",merchant_pub" ",denom.denom_pub" ",coin_pub" @@ -881,6 +888,8 @@ postgres_get_session (void *cls) ",wire" ",merchant_pub" ",coin_pub" + ",exchange_timestamp" + ",wallet_timestamp" " FROM deposits" " JOIN known_coins USING (coin_pub)" " JOIN denominations denom USING (denom_pub_hash)" @@ -900,6 +909,8 @@ postgres_get_session (void *cls) ",denom.fee_deposit_val" ",denom.fee_deposit_frac" ",wire_deadline" + ",exchange_timestamp" + ",wallet_timestamp" ",h_contract_terms" ",coin_pub" " FROM deposits" @@ -945,7 +956,7 @@ postgres_get_session (void *cls) ",amount_with_fee_frac" ",denom.fee_deposit_val" ",denom.fee_deposit_frac" - ",timestamp" + ",wallet_timestamp" ",refund_deadline" ",wire_deadline" ",merchant_pub" @@ -2571,6 +2582,8 @@ postgres_get_reserve_history (void *cls, * @param session database connection * @param deposit deposit to search for * @param check_extras whether to check extra fields match or not + * @param[out] deposit_fee set to the deposit fee the exchange charged + * @param[out] exchange_timestamp set to the time when the exchange received the deposit * @return 1 if we know this operation, * 0 if this exact deposit is unknown to us, * otherwise transaction error status @@ -2579,7 +2592,9 @@ static enum GNUNET_DB_QueryStatus postgres_have_deposit (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct TALER_EXCHANGEDB_Deposit *deposit, - int check_extras) + int check_extras, + struct TALER_Amount *deposit_fee, + struct GNUNET_TIME_Absolute *exchange_timestamp) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -2592,12 +2607,16 @@ postgres_have_deposit (void *cls, struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", &deposit2.amount_with_fee), - TALER_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("wallet_timestamp", &deposit2.timestamp), + TALER_PQ_result_spec_absolute_time ("exchange_timestamp", + exchange_timestamp), TALER_PQ_result_spec_absolute_time ("refund_deadline", &deposit2.refund_deadline), TALER_PQ_result_spec_absolute_time ("wire_deadline", &deposit2.wire_deadline), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + deposit_fee), GNUNET_PQ_result_spec_auto_from_type ("h_wire", &deposit2.h_wire), GNUNET_PQ_result_spec_end @@ -2776,6 +2795,8 @@ postgres_get_ready_deposit (void *cls, struct TALER_Amount amount_with_fee; struct TALER_Amount deposit_fee; struct GNUNET_TIME_Absolute wire_deadline; + struct GNUNET_TIME_Absolute wallet_timestamp; + struct GNUNET_TIME_Absolute exchange_timestamp; struct GNUNET_HashCode h_contract_terms; struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_CoinSpendPublicKeyP coin_pub; @@ -2788,6 +2809,10 @@ postgres_get_ready_deposit (void *cls, &amount_with_fee), TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", &deposit_fee), + TALER_PQ_result_spec_absolute_time ("exchange_timestamp", + &exchange_timestamp), + TALER_PQ_result_spec_absolute_time ("wallet_timestamp", + &wallet_timestamp), TALER_PQ_result_spec_absolute_time ("wire_deadline", &wire_deadline), GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", @@ -2817,6 +2842,8 @@ postgres_get_ready_deposit (void *cls, qs = deposit_cb (deposit_cb_cls, serial_id, + exchange_timestamp, + wallet_timestamp, &merchant_pub, &coin_pub, &amount_with_fee, @@ -2898,6 +2925,8 @@ match_deposit_cb (void *cls, { struct TALER_Amount amount_with_fee; struct TALER_Amount deposit_fee; + struct GNUNET_TIME_Absolute exchange_timestamp; + struct GNUNET_TIME_Absolute wallet_timestamp; struct GNUNET_TIME_Absolute wire_deadline; struct GNUNET_HashCode h_contract_terms; struct TALER_CoinSpendPublicKeyP coin_pub; @@ -2912,6 +2941,10 @@ match_deposit_cb (void *cls, &deposit_fee), TALER_PQ_result_spec_absolute_time ("wire_deadline", &wire_deadline), + TALER_PQ_result_spec_absolute_time ("exchange_timestamp", + &exchange_timestamp), + TALER_PQ_result_spec_absolute_time ("wallet_timestamp", + &wallet_timestamp), GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", &h_contract_terms), GNUNET_PQ_result_spec_auto_from_type ("coin_pub", @@ -2930,6 +2963,8 @@ match_deposit_cb (void *cls, } qs = mdc->deposit_cb (mdc->deposit_cb_cls, serial_id, + exchange_timestamp, + wallet_timestamp, mdc->merchant_pub, &coin_pub, &amount_with_fee, @@ -3210,12 +3245,14 @@ postgres_ensure_coin_known (void *cls, * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param session connection to the database + * @param exchange_timestamp time the exchange received the deposit request * @param deposit deposit information to store * @return query result status */ static enum GNUNET_DB_QueryStatus postgres_insert_deposit (void *cls, struct TALER_EXCHANGEDB_Session *session, + struct GNUNET_TIME_Absolute exchange_timestamp, const struct TALER_EXCHANGEDB_Deposit *deposit) { struct GNUNET_PQ_QueryParam params[] = { @@ -3229,6 +3266,7 @@ postgres_insert_deposit (void *cls, GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire), GNUNET_PQ_query_param_auto_from_type (&deposit->csig), TALER_PQ_query_param_json (deposit->receiver_wire_account), + TALER_PQ_query_param_absolute_time (&exchange_timestamp), GNUNET_PQ_query_param_end }; @@ -4042,7 +4080,7 @@ add_coin_deposit (void *cls, &deposit->amount_with_fee), TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", &deposit->deposit_fee), - TALER_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("wallet_timestamp", &deposit->timestamp), TALER_PQ_result_spec_absolute_time ("refund_deadline", &deposit->refund_deadline), @@ -5462,14 +5500,17 @@ deposit_serial_helper_cb (void *cls, for (unsigned int i = 0; icb (dsc->cb_cls, rowid, + exchange_timestamp, deposit.timestamp, &deposit.merchant_pub, &denom_pub, diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index eea484e94..fe3ed7854 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -833,6 +833,8 @@ static uint64_t deposit_rowid; * @param cls closure a `struct TALER_EXCHANGEDB_Deposit *` * @param rowid unique ID for the deposit in our DB, used for marking * it as 'tiny' or 'done' + * @param exchange_timestamp when did the deposit happen + * @param wallet_timestamp when did the wallet sign the contract * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin * @param amount_with_fee amount that was deposited including fee @@ -846,6 +848,8 @@ static uint64_t deposit_rowid; static enum GNUNET_DB_QueryStatus deposit_cb (void *cls, uint64_t rowid, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, @@ -890,7 +894,8 @@ deposit_cb (void *cls, * * @param cls closure * @param rowid unique serial ID for the deposit in our DB - * @param timestamp when did the deposit happen + * @param exchange_timestamp when did the deposit happen + * @param wallet_timestamp when did the wallet sign the contract * @param merchant_pub public key of the merchant * @param denom_pub denomination of the @a coin_pub * @param coin_pub public key of the coin @@ -908,7 +913,8 @@ deposit_cb (void *cls, static int audit_deposit_cb (void *cls, uint64_t rowid, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1878,15 +1884,27 @@ run (void *cls) plugin->ensure_coin_known (plugin->cls, session, &deposit.coin)); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->insert_deposit (plugin->cls, + { + struct GNUNET_TIME_Absolute now; + struct GNUNET_TIME_Absolute r; + struct TALER_Amount deposit_fee; + + now = GNUNET_TIME_absolute_get (); + GNUNET_TIME_round_abs (&now); + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->insert_deposit (plugin->cls, + session, + now, + &deposit)); + FAILIF (1 != + plugin->have_deposit (plugin->cls, session, - &deposit)); - FAILIF (1 != - plugin->have_deposit (plugin->cls, - session, - &deposit, - GNUNET_YES)); + &deposit, + GNUNET_YES, + &deposit_fee, + &r)); + FAILIF (now.abs_value_us != r.abs_value_us); + } { struct GNUNET_TIME_Absolute start_range; struct GNUNET_TIME_Absolute end_range; @@ -1983,18 +2001,27 @@ run (void *cls) session, "test-2")); RND_BLK (&deposit2.merchant_pub); /* should fail if merchant is different */ - FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != - plugin->have_deposit (plugin->cls, - session, - &deposit2, - GNUNET_YES)); - deposit2.merchant_pub = deposit.merchant_pub; - RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ - FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != - plugin->have_deposit (plugin->cls, - session, - &deposit2, - GNUNET_YES)); + { + struct GNUNET_TIME_Absolute r; + struct TALER_Amount deposit_fee; + + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->have_deposit (plugin->cls, + session, + &deposit2, + GNUNET_YES, + &deposit_fee, + &r)); + deposit2.merchant_pub = deposit.merchant_pub; + RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */ + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->have_deposit (plugin->cls, + session, + &deposit2, + GNUNET_YES, + &deposit_fee, + &r)); + } FAILIF (GNUNET_OK != test_melting (session)); FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index 9a7f6ed7a..7c58e654e 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -300,9 +300,9 @@ struct TALER_AUDITORDB_DepositConfirmation struct GNUNET_HashCode h_wire; /** - * Time when this confirmation was generated. + * Time when this deposit confirmation was generated by the exchange. */ - struct GNUNET_TIME_Absolute timestamp; + struct GNUNET_TIME_Absolute exchange_timestamp; /** * How much time does the @e merchant have to issue a refund diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h index 74660303d..eded23339 100644 --- a/src/include/taler_error_codes.h +++ b/src/include/taler_error_codes.h @@ -1542,73 +1542,92 @@ enum TALER_ErrorCode * This response is provided with HTTP status code * #MHD_HTTP_SERVICE_UNAVAILABLE. */ - TALER_EC_TRACK_TRANSFER_EXCHANGE_TIMEOUT = 2400, + TALER_EC_POST_TRANSFERS_EXCHANGE_TIMEOUT = 2400, /** * We failed to obtain an acceptable /keys response from the exchange * for the /track/transfer request. This response is provided with * HTTP status code #MHD_HTTP_FAILED_DEPENDENCY. */ - TALER_EC_TRACK_TRANSFER_EXCHANGE_KEYS_FAILURE = 2401, + TALER_EC_POST_TRANSFERS_EXCHANGE_KEYS_FAILURE = 2401, /** * We failed to persist coin wire transfer information in our merchant * database. The response is provided with HTTP status code * #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_DB_STORE_COIN_ERROR = 2402, + TALER_EC_POST_TRANSFERS_DB_STORE_COIN_ERROR = 2402, /** * We internally failed to execute the /track/transfer request. The * response is provided with HTTP status code * #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_REQUEST_ERROR = 2403, + TALER_EC_POST_TRANSFERS_REQUEST_ERROR = 2403, /** * We failed to persist wire transfer information in our merchant * database. The response is provided with HTTP status code * #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_DB_STORE_TRANSFER_ERROR = 2404, + TALER_EC_POST_TRANSFERS_DB_STORE_TRANSFER_ERROR = 2404, /** * The exchange returned an error from /track/transfer. The response * is provided with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY. */ - TALER_EC_TRACK_TRANSFER_EXCHANGE_ERROR = 2405, + TALER_EC_POST_TRANSFERS_EXCHANGE_ERROR = 2405, /** * We failed to fetch deposit information from our merchant database. * The response is provided with HTTP status code * #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_DB_FETCH_DEPOSIT_ERROR = 2406, + TALER_EC_POST_TRANSFERS_DB_FETCH_DEPOSIT_ERROR = 2406, /** * We encountered an internal logic error. The response is provided * with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR. */ - TALER_EC_TRACK_TRANSFER_DB_INTERNAL_LOGIC_ERROR = 2407, + TALER_EC_POST_TRANSFERS_DB_INTERNAL_LOGIC_ERROR = 2407, /** * The exchange gave conflicting information about a coin which has * been wire transferred. The response is provided with HTTP status * code #MHD_HTTP_FAILED_DEPENDENCY. */ - TALER_EC_TRACK_TRANSFER_CONFLICTING_REPORTS = 2408, + TALER_EC_POST_TRANSFERS_CONFLICTING_REPORTS = 2408, /** * The merchant backend had problems in creating the JSON response. */ - TALER_EC_TRACK_TRANSFER_JSON_RESPONSE_ERROR = 2409, + TALER_EC_POST_TRANSFERS_JSON_RESPONSE_ERROR = 2409, /** * The exchange charged a different wire fee than what it originally - * advertised, and it is higher. The response is provied with an HTTP - * status of #MHD_HTTP_FAILED_DEPENDENCY. + * advertised, and it is higher. The response is provided with an + * HTTP status of #MHD_HTTP_FAILED_DEPENDENCY. */ - TALER_EC_TRACK_TRANSFER_JSON_BAD_WIRE_FEE = 2410, + TALER_EC_POST_TRANSFERS_JSON_BAD_WIRE_FEE = 2410, + + /** + * We did not find the account that the transfer was made to. The + * response is provided with an HTTP status of #MHD_HTTP_NOT_FOUND. + */ + TALER_EC_POST_TRANSFERS_ACCOUNT_NOT_FOUND = 2411, + + /** + * We did failed to store information in our database. The response is + * provided with an HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_POST_TRANSFERS_DB_STORE_ERROR = 2412, + + /** + * We did failed to retrieve information from our database. The + * response is provided with an HTTP status of + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_POST_TRANSFERS_DB_LOOKUP_ERROR = 2413, /** * The merchant backend cannot create an instance under the given diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 82b9b83df..38928dc18 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -756,6 +756,7 @@ struct TALER_EXCHANGE_DepositHandle; * * @param cls closure * @param hr HTTP response data + * @param deposit_timestamp time when the exchange generated the deposit confirmation * @param exchange_sig signature provided by the exchange * @param exchange_pub exchange key used to sign @a obj, or NULL */ @@ -763,6 +764,7 @@ typedef void (*TALER_EXCHANGE_DepositResultCallback) ( void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + struct GNUNET_TIME_Absolute deposit_timestamp, const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangePublicKeyP *exchange_pub); diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 4fd580724..9fb932362 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -975,6 +975,8 @@ struct TALER_EXCHANGEDB_Session; * @param cls closure * @param rowid unique ID for the deposit in our DB, used for marking * it as 'tiny' or 'done' + * @param exchange_timestamp when did the exchange receive the deposit + * @param wallet_timestamp when did the wallet sign the contract * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin * @param amount_with_fee amount that was deposited including fee @@ -990,6 +992,8 @@ typedef enum GNUNET_DB_QueryStatus (*TALER_EXCHANGEDB_DepositIterator)( void *cls, uint64_t rowid, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, @@ -1022,7 +1026,8 @@ typedef void * * @param cls closure * @param rowid unique serial ID for the deposit in our DB - * @param timestamp when did the deposit happen + * @param exchange_timestamp when did the deposit happen + * @param wallet_timestamp when did the contract happen * @param merchant_pub public key of the merchant * @param denom_pub denomination public key of @a coin_pub * @param coin_pub public key of the coin @@ -1042,7 +1047,8 @@ typedef int (*TALER_EXCHANGEDB_DepositCallback)( void *cls, uint64_t rowid, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1841,6 +1847,8 @@ struct TALER_EXCHANGEDB_Plugin * @param session database connection * @param deposit deposit to search for * @param check_extras whether to check extra fields or not + * @param[out] deposit_fee set to the deposit fee the exchange charged + * @param[out] exchange_timestamp set to the time when the exchange received the deposit * @return 1 if we know this operation, * 0 if this exact deposit is unknown to us, * otherwise transaction error status @@ -1849,7 +1857,9 @@ struct TALER_EXCHANGEDB_Plugin (*have_deposit)(void *cls, struct TALER_EXCHANGEDB_Session *session, const struct TALER_EXCHANGEDB_Deposit *deposit, - int check_extras); + int check_extras, + struct TALER_Amount *deposit_fee, + struct GNUNET_TIME_Absolute *exchange_timestamp); /** @@ -1857,12 +1867,14 @@ struct TALER_EXCHANGEDB_Plugin * * @param cls the @e cls of this struct with the plugin-specific state * @param session connection to the database + * @param exchange_timestamp time the exchange received the deposit request * @param deposit deposit information to store * @return query result status */ enum GNUNET_DB_QueryStatus (*insert_deposit)(void *cls, struct TALER_EXCHANGEDB_Session *session, + struct GNUNET_TIME_Absolute exchange_timestamp, const struct TALER_EXCHANGEDB_Deposit *deposit); diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index c346a6cee..38b895d7f 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -363,7 +363,7 @@ struct TALER_DepositRequestPS * deposit request in a timely fashion (so back-dating is not * prevented). */ - struct GNUNET_TIME_AbsoluteNBO timestamp; + struct GNUNET_TIME_AbsoluteNBO wallet_timestamp; /** * How much time does the merchant have to issue a refund request? @@ -429,9 +429,10 @@ struct TALER_DepositConfirmationPS struct GNUNET_HashCode h_wire GNUNET_PACKED; /** - * Time when this confirmation was generated. + * Time when this confirmation was generated / when the exchange received + * the deposit request. */ - struct GNUNET_TIME_AbsoluteNBO timestamp; + struct GNUNET_TIME_AbsoluteNBO exchange_timestamp; /** * How much time does the @e merchant have to issue a refund diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index 9abb0cca7..53a004c8c 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -1917,6 +1917,7 @@ TALER_TESTING_cmd_connect_with_state (const char *label, * @param dbc collects plugin and session handles * @param merchant_name Human-readable name of the merchant. * @param merchant_account merchant's account name (NOT a payto:// URI) + * @param exchange_timestamp when did the exchange receive the deposit * @param wire_deadline point in time where the aggregator should have * wired money to the merchant. * @param amount_with_fee amount to deposit (inclusive of deposit fee) @@ -1924,14 +1925,15 @@ TALER_TESTING_cmd_connect_with_state (const char *label, * @return the command. */ struct TALER_TESTING_Command -TALER_TESTING_cmd_insert_deposit (const char *label, - const struct - TALER_TESTING_DatabaseConnection *dbc, - const char *merchant_name, - const char *merchant_account, - struct GNUNET_TIME_Relative wire_deadline, - const char *amount_with_fee, - const char *deposit_fee); +TALER_TESTING_cmd_insert_deposit ( + const char *label, + const struct TALER_TESTING_DatabaseConnection *dbc, + const char *merchant_name, + const char *merchant_account, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Relative wire_deadline, + const char *amount_with_fee, + const char *deposit_fee); /** diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c index cddfe8b14..1856a89f4 100644 --- a/src/lib/auditor_api_deposit_confirmation.c +++ b/src/lib/auditor_api_deposit_confirmation.c @@ -148,7 +148,7 @@ handle_deposit_confirmation_finished (void *cls, * * @param h_wire hash of merchant wire details * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor) - * @param timestamp timestamp when the contract was finalized, must not be too far in the future + * @param exchange_timestamp timestamp when the deposit was received by the wallet * @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant * @param coin_pub coin’s public key @@ -165,7 +165,7 @@ handle_deposit_confirmation_finished (void *cls, static int verify_signatures (const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract_terms, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_Amount *amount_without_fee, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -184,7 +184,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire, .purpose.size = htonl (sizeof (dc)), .h_contract_terms = *h_contract_terms, .h_wire = *h_wire, - .timestamp = GNUNET_TIME_absolute_hton (timestamp), + .exchange_timestamp = GNUNET_TIME_absolute_hton (exchange_timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .coin_pub = *coin_pub, .merchant = *merchant_pub @@ -256,7 +256,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire, * @param auditor the auditor handle; the auditor must be ready to operate * @param h_wire hash of merchant wire details * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor) - * @param timestamp timestamp when the contract was finalized, must not be too far in the future + * @param exchange_timestamp timestamp when deposit was received by the exchange * @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant * @param coin_pub coin’s public key @@ -278,7 +278,7 @@ TALER_AUDITOR_deposit_confirmation ( struct TALER_AUDITOR_Handle *auditor, const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract_terms, - struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute exchange_timestamp, struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_Amount *amount_without_fee, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -298,7 +298,7 @@ TALER_AUDITOR_deposit_confirmation ( json_t *deposit_confirmation_obj; CURL *eh; - (void) GNUNET_TIME_round_abs (×tamp); + (void) GNUNET_TIME_round_abs (&exchange_timestamp); (void) GNUNET_TIME_round_abs (&refund_deadline); (void) GNUNET_TIME_round_abs (&ep_start); (void) GNUNET_TIME_round_abs (&ep_expire); @@ -308,7 +308,7 @@ TALER_AUDITOR_deposit_confirmation ( if (GNUNET_OK != verify_signatures (h_wire, h_contract_terms, - timestamp, + exchange_timestamp, refund_deadline, amount_without_fee, coin_pub, @@ -336,7 +336,8 @@ TALER_AUDITOR_deposit_confirmation ( "h_wire", GNUNET_JSON_from_data_auto (h_wire), "h_contract_terms", GNUNET_JSON_from_data_auto ( h_contract_terms), - "timestamp", GNUNET_JSON_from_time_abs (timestamp), + "exchange_timestamp", GNUNET_JSON_from_time_abs ( + exchange_timestamp), "refund_deadline", GNUNET_JSON_from_time_abs (refund_deadline), "amount_without_fee", TALER_JSON_from_amount ( amount_without_fee), diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index dc44291d0..bf8eb5376 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -524,7 +524,7 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_JSON_spec_fixed_auto ("h_wire", &dr.h_wire), GNUNET_JSON_spec_absolute_time_nbo ("timestamp", - &dr.timestamp), + &dr.wallet_timestamp), GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline", &dr.refund_deadline), TALER_JSON_spec_amount_nbo ("deposit_fee", diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index a5cf6c36a..276053658 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -160,7 +160,7 @@ auditor_cb (void *cls, ah, &dh->depconf.h_wire, &dh->depconf.h_contract_terms, - GNUNET_TIME_absolute_ntoh (dh->depconf.timestamp), + GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp), GNUNET_TIME_absolute_ntoh (dh->depconf.refund_deadline), &amount_without_fee, &dh->depconf.coin_pub, @@ -198,6 +198,8 @@ verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), + GNUNET_JSON_spec_absolute_time_nbo ("exchange_timestamp", + &dh->depconf.exchange_timestamp), GNUNET_JSON_spec_end () }; @@ -386,6 +388,7 @@ handle_deposit_finished (void *cls, } dh->cb (dh->cb_cls, &hr, + GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp), es, ep); TALER_EXCHANGE_deposit_cancel (dh); @@ -429,7 +432,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, .purpose.size = htonl (sizeof (dr)), .h_contract_terms = *h_contract_terms, .h_wire = *h_wire, - .timestamp = GNUNET_TIME_absolute_hton (timestamp), + .wallet_timestamp = GNUNET_TIME_absolute_hton (timestamp), .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .merchant = *merchant_pub, .coin_pub = *coin_pub @@ -658,7 +661,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT); dh->depconf.h_contract_terms = *h_contract_terms; dh->depconf.h_wire = h_wire; - dh->depconf.timestamp = GNUNET_TIME_absolute_hton (timestamp); + /* dh->depconf.exchange_timestamp; -- initialized later from exchange reply! */ dh->depconf.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline); TALER_amount_hton (&dh->depconf.amount_without_fee, &amount_without_fee); diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index b1ea176bf..6f91389f1 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -148,7 +148,8 @@ handle_refund_finished (void *cls, struct TALER_ExchangeSignatureP exchange_sig; struct TALER_ExchangePublicKeyP *ep = NULL; struct TALER_ExchangeSignatureP *es = NULL; - struct TALER_Amount *rf = NULL; + struct TALER_Amount ra; + const struct TALER_Amount *rf = NULL; const json_t *j = response; struct TALER_EXCHANGE_HttpResponse hr = { .reply = j, @@ -176,7 +177,9 @@ handle_refund_finished (void *cls, { ep = &exchange_pub; es = &exchange_sig; - rf = &rh->depconf.refund_fee; + TALER_amount_ntoh (&ra, + &rh->depconf.refund_fee); + rf = &ra; } break; case MHD_HTTP_BAD_REQUEST: diff --git a/src/testing/test_taler_exchange_aggregator.c b/src/testing/test_taler_exchange_aggregator.c index eaa621cfe..d5c392d3a 100644 --- a/src/testing/test_taler_exchange_aggregator.c +++ b/src/testing/test_taler_exchange_aggregator.c @@ -108,6 +108,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -126,6 +127,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -134,6 +136,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -153,6 +156,7 @@ run (void *cls, &dbc, "bob", "4", + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -160,6 +164,7 @@ run (void *cls, &dbc, "bob", "5", + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -167,6 +172,7 @@ run (void *cls, &dbc, "alice", "4", + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:1", "EUR:0.1"), @@ -195,6 +201,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -204,6 +211,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -229,6 +237,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), @@ -239,6 +248,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -263,6 +273,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.102", "EUR:0.1"), @@ -274,6 +285,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.102", "EUR:0.1"), @@ -281,6 +293,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.102", "EUR:0.1"), @@ -292,6 +305,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.102", "EUR:0.1"), @@ -303,6 +317,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.112", "EUR:0.1"), @@ -319,6 +334,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.109", "EUR:0.1"), @@ -330,6 +346,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.119", "EUR:0.1"), @@ -346,6 +363,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.122", "EUR:0.1"), @@ -362,6 +380,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -375,6 +394,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -390,6 +410,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.122", "EUR:0.1"), @@ -406,6 +427,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -419,6 +441,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), @@ -434,6 +457,7 @@ run (void *cls, &dbc, "bob", USER42_ACCOUNT, + GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_ZERO, "EUR:0.112", "EUR:0.1"), diff --git a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c index 247399a9d..1442380bf 100644 --- a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c +++ b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c @@ -203,6 +203,7 @@ deposit_confirmation_run (void *cls, const struct TALER_TESTING_Command *deposit_cmd; struct GNUNET_HashCode h_wire; struct GNUNET_HashCode h_contract_terms; + const struct GNUNET_TIME_Absolute *exchange_timestamp = NULL; struct GNUNET_TIME_Absolute timestamp; struct GNUNET_TIME_Absolute refund_deadline; struct TALER_Amount amount_without_fee; @@ -238,6 +239,11 @@ deposit_confirmation_run (void *cls, TALER_TESTING_get_trait_exchange_sig (deposit_cmd, dcs->coin_index, &exchange_sig)); + GNUNET_assert (GNUNET_OK == + TALER_TESTING_get_trait_absolute_time (deposit_cmd, + dcs->coin_index, + &exchange_timestamp)); + GNUNET_assert (NULL != exchange_timestamp); keys = TALER_EXCHANGE_get_keys (dcs->is->exchange); GNUNET_assert (NULL != keys); spk = TALER_EXCHANGE_get_signing_key_info (keys, @@ -309,7 +315,7 @@ deposit_confirmation_run (void *cls, dcs->dc = TALER_AUDITOR_deposit_confirmation (dcs->auditor, &h_wire, &h_contract_terms, - timestamp, + *exchange_timestamp, refund_deadline, &amount_without_fee, &coin_pub, diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index 9468e7acb..049f36f25 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -91,9 +91,9 @@ struct DepositState struct TALER_EXCHANGE_DepositHandle *dh; /** - * Timestamp of the /deposit operation. + * Timestamp of the /deposit operation in the wallet (contract signing time). */ - struct GNUNET_TIME_Absolute timestamp; + struct GNUNET_TIME_Absolute wallet_timestamp; /** * Interpreter state. @@ -126,6 +126,11 @@ struct DepositState */ int deposit_succeeded; + /** + * When did the exchange receive the deposit? + */ + struct GNUNET_TIME_Absolute exchange_timestamp; + /** * Signing key used by the exchange to sign the * deposit confirmation. @@ -198,6 +203,7 @@ do_retry (void *cls) * * @param cls closure. * @param hr HTTP response details + * @param exchange_timestamp when did the exchange receive the deposit permission * @param exchange_sig signature provided by the exchange * (NULL on errors) * @param exchange_pub public key of the exchange, @@ -206,6 +212,7 @@ do_retry (void *cls) static void deposit_cb (void *cls, const struct TALER_EXCHANGE_HttpResponse *hr, + const struct GNUNET_TIME_Absolute exchange_timestamp, const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangePublicKeyP *exchange_pub) { @@ -254,6 +261,7 @@ deposit_cb (void *cls, if (MHD_HTTP_OK == hr->http_status) { ds->deposit_succeeded = GNUNET_YES; + ds->exchange_timestamp = exchange_timestamp; ds->exchange_pub = *exchange_pub; ds->exchange_sig = *exchange_sig; } @@ -305,7 +313,7 @@ deposit_run (void *cls, ds->coin_index = ods->coin_index; ds->wire_details = json_incref (ods->wire_details); ds->contract_terms = json_incref (ods->contract_terms); - ds->timestamp = ods->timestamp; + ds->wallet_timestamp = ods->wallet_timestamp; ds->refund_deadline = ods->refund_deadline; ds->amount = ods->amount; ds->merchant_priv = ods->merchant_priv; @@ -379,7 +387,7 @@ deposit_run (void *cls, } else { - ds->refund_deadline = ds->timestamp; + ds->refund_deadline = ds->wallet_timestamp; wire_deadline = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_ZERO); } @@ -388,6 +396,7 @@ deposit_run (void *cls, (void) GNUNET_TIME_round_abs (&wire_deadline); + // FIXME: This should be part of TALER_EXCHANGE_deposit()! { struct TALER_DepositRequestPS dr; @@ -400,7 +409,7 @@ deposit_run (void *cls, GNUNET_assert (GNUNET_OK == TALER_JSON_merchant_wire_signature_hash (ds->wire_details, &dr.h_wire)); - dr.timestamp = GNUNET_TIME_absolute_hton (ds->timestamp); + dr.wallet_timestamp = GNUNET_TIME_absolute_hton (ds->wallet_timestamp); dr.refund_deadline = GNUNET_TIME_absolute_hton (ds->refund_deadline); TALER_amount_hton (&dr.amount_with_fee, @@ -421,7 +430,7 @@ deposit_run (void *cls, &coin_pub, denom_pub_sig, &denom_pub->key, - ds->timestamp, + ds->wallet_timestamp, &merchant_pub, ds->refund_deadline, &coin_sig, @@ -534,6 +543,8 @@ deposit_traits (void *cls, &ds->merchant_priv), TALER_TESTING_make_trait_amount_obj (0, &ds->amount), + TALER_TESTING_make_trait_absolute_time (0, + &ds->exchange_timestamp), TALER_TESTING_trait_end () }; @@ -599,12 +610,12 @@ TALER_TESTING_cmd_deposit (const char *label, label); GNUNET_assert (0); } - ds->timestamp = GNUNET_TIME_absolute_get (); - (void) GNUNET_TIME_round_abs (&ds->timestamp); + ds->wallet_timestamp = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&ds->wallet_timestamp); json_object_set_new (ds->contract_terms, "timestamp", - GNUNET_JSON_from_time_abs (ds->timestamp)); + GNUNET_JSON_from_time_abs (ds->wallet_timestamp)); if (0 != refund_deadline.rel_value_us) { ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline); @@ -687,12 +698,12 @@ TALER_TESTING_cmd_deposit_with_ref (const char *label, label); GNUNET_assert (0); } - ds->timestamp = GNUNET_TIME_absolute_get (); - (void) GNUNET_TIME_round_abs (&ds->timestamp); + ds->wallet_timestamp = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&ds->wallet_timestamp); json_object_set_new (ds->contract_terms, "timestamp", - GNUNET_JSON_from_time_abs (ds->timestamp)); + GNUNET_JSON_from_time_abs (ds->wallet_timestamp)); if (0 != refund_deadline.rel_value_us) { ds->refund_deadline = GNUNET_TIME_relative_to_absolute (refund_deadline); diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c index 356528009..cff2884aa 100644 --- a/src/testing/testing_api_cmd_insert_deposit.c +++ b/src/testing/testing_api_cmd_insert_deposit.c @@ -57,6 +57,11 @@ struct InsertDepositState */ struct GNUNET_TIME_Relative wire_deadline; + /** + * When did the exchange receive the deposit? + */ + struct GNUNET_TIME_Absolute exchange_timestamp; + /** * Amount to deposit, inclusive of deposit fee. */ @@ -210,6 +215,7 @@ insert_deposit_run (void *cls, (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != ids->dbc->plugin->insert_deposit (ids->dbc->plugin->cls, ids->dbc->session, + ids->exchange_timestamp, &deposit)) || (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != ids->dbc->plugin->commit (ids->dbc->plugin->cls, @@ -275,6 +281,7 @@ insert_deposit_traits (void *cls, * @param dbc collects database plugin and session handles. * @param merchant_name Human-readable name of the merchant. * @param merchant_account merchant's account name (NOT a payto:// URI) + * @param exchange_timestamp when did the exchange receive the deposit * @param wire_deadline point in time where the aggregator should have * wired money to the merchant. * @param amount_with_fee amount to deposit (inclusive of deposit fee) @@ -282,21 +289,24 @@ insert_deposit_traits (void *cls, * @return the command. */ struct TALER_TESTING_Command -TALER_TESTING_cmd_insert_deposit (const char *label, - const struct - TALER_TESTING_DatabaseConnection *dbc, - const char *merchant_name, - const char *merchant_account, - struct GNUNET_TIME_Relative wire_deadline, - const char *amount_with_fee, - const char *deposit_fee) +TALER_TESTING_cmd_insert_deposit ( + const char *label, + const struct TALER_TESTING_DatabaseConnection *dbc, + const char *merchant_name, + const char *merchant_account, + struct GNUNET_TIME_Absolute exchange_timestamp, + struct GNUNET_TIME_Relative wire_deadline, + const char *amount_with_fee, + const char *deposit_fee) { struct InsertDepositState *ids; + GNUNET_TIME_round_abs (&exchange_timestamp); ids = GNUNET_new (struct InsertDepositState); ids->dbc = dbc; ids->merchant_name = merchant_name; ids->merchant_account = merchant_account; + ids->exchange_timestamp = exchange_timestamp; ids->wire_deadline = wire_deadline; ids->amount_with_fee = amount_with_fee; ids->deposit_fee = deposit_fee; -- cgit v1.2.3 From e9d80d764a6b9e17e6b37e3d57ea24cb60aae7c5 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 5 May 2020 22:17:16 +0200 Subject: return fee as well --- src/lib/exchange_api_refund.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lib') diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 6f91389f1..1af1f14b9 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -156,6 +156,7 @@ handle_refund_finished (void *cls, .http_status = (unsigned int) response_code }; + rh->job = NULL; switch (response_code) { -- cgit v1.2.3 From 15daa781271387bb0799b59f9da51563b24fa723 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 5 May 2020 22:17:16 +0200 Subject: return fee as well --- src/lib/exchange_api_refund.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/lib') diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 1af1f14b9..687dbdae1 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -178,9 +178,13 @@ handle_refund_finished (void *cls, { ep = &exchange_pub; es = &exchange_sig; +<<<<<<< HEAD TALER_amount_ntoh (&ra, &rh->depconf.refund_fee); rf = &ra; +======= + rf = &rh->depconf.refund_fee; +>>>>>>> return fee as well } break; case MHD_HTTP_BAD_REQUEST: -- cgit v1.2.3 From 44c70269e25b86d3ab995b9fbd3366020b6a3c1c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 31 May 2020 17:39:26 +0200 Subject: update ECs --- src/include/taler_error_codes.h | 55 +++++++++++++++++++++++++++++++++++++++++ src/lib/exchange_api_melt.c | 10 ++++---- 2 files changed, 60 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h index 1e031f4b6..87feea2d3 100644 --- a/src/include/taler_error_codes.h +++ b/src/include/taler_error_codes.h @@ -2165,6 +2165,61 @@ enum TALER_ErrorCode */ TALER_EC_RESERVES_DELETE_NO_SUCH_RESERVE = 2722, + /** + * The backend got an unexpected error trying to lookup reserve + * details from the backend. This response is provided with HTTP + * status code #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_LOOKUP_RESERVE_DB_FAILURE = 2723, + + /** + * The backend repeatedly failed to serialize the transaction to + * authorize the tip. This response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_SERIALIZATION_FAILURE = 2724, + + /** + * The backend failed to start the transaction to authorize the tip. + * This response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_START_FAILURE = 2725, + + /** + * The backend failed looking up the reserve needed to authorize the + * tip. This response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_LOOKUP_RESERVE_FAILURE = 2726, + + /** + * The backend failed to find a reserve needed to authorize the tip. + * This response is provided with HTTP status code + * #MHD_HTTP_SERVICE_UNAVAILABLE. + */ + TALER_EC_TIP_AUTHORIZE_DB_RESERVE_NOT_FOUND = 2727, + + /** + * The backend encountered an internal invariant violation. This + * response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_RESERVE_INVARIANT_FAILURE = 2728, + + /** + * The selected exchange expired. This response is provided with HTTP + * status code #MHD_HTTP_GONE. + */ + TALER_EC_TIP_AUTHORIZE_DB_RESERVE_EXPIRED = 2729, + + /** + * The backend failed updating the reserve needed to authorize the + * tip. This response is provided with HTTP status code + * #MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TIP_AUTHORIZE_DB_UPDATE_RESERVE_FAILURE = 2730, + /** * The backend had trouble accessing the database to persist * information about enabling tips. Returned with an HTTP status code diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index f89036e40..0695f997b 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -445,11 +445,11 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2]; char *end; - end = GNUNET_STRINGS_data_to_string (&melt.coin_pub, - sizeof (struct - TALER_CoinSpendPublicKeyP), - pub_str, - sizeof (pub_str)); + end = GNUNET_STRINGS_data_to_string ( + &melt.coin_pub, + sizeof (struct TALER_CoinSpendPublicKeyP), + pub_str, + sizeof (pub_str)); *end = '\0'; GNUNET_snprintf (arg_str, sizeof (arg_str), -- cgit v1.2.3 From dc9f41a7940a540df9d6f9a1d1b3a01c96176b11 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 23 Jun 2020 10:30:31 +0200 Subject: clarify with/without wire fee issue, sanity checks on currencies --- src/include/taler_exchange_service.h | 2 +- src/lib/exchange_api_transfers_get.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 079987020..e61a07c91 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1611,7 +1611,7 @@ struct TALER_EXCHANGE_TransferData struct GNUNET_TIME_Absolute execution_time; /** - * amount of the wire transfer; FIXME: total wired (without fee), or including @a wire_fee? + * Actual amount of the wire transfer, excluding the wire fee. */ struct TALER_Amount total_amount; diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c index dd9b64467..6b5bba8e8 100644 --- a/src/lib/exchange_api_transfers_get.c +++ b/src/lib/exchange_api_transfers_get.c @@ -155,6 +155,12 @@ check_transfers_get_response_ok ( GNUNET_JSON_parse (detail_j, spec_detail, NULL, NULL)) || + (GNUNET_OK != + TALER_amount_cmp_currency (&total_expected, + &detail->coin_value)) || + (GNUNET_OK != + TALER_amount_cmp_currency (&total_expected, + &detail->coin_fee)) || (0 > TALER_amount_add (&total_expected, &total_expected, -- cgit v1.2.3 From b0311807ff8c7702a87b99da1e21a963eb280633 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 27 Jun 2020 18:49:12 +0200 Subject: fix FIXME by exposing deposit permission signing in API instead of doing it inside of the testing logic --- src/include/taler_exchange_service.h | 26 +++++++++++++++++ src/lib/exchange_api_deposit.c | 53 +++++++++++++++++++++++++++++++++++ src/testing/testing_api_cmd_deposit.c | 39 +++++++++----------------- 3 files changed, 92 insertions(+), 26 deletions(-) (limited to 'src/lib') diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index e61a07c91..02ab182f2 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -744,6 +744,32 @@ TALER_EXCHANGE_wire_cancel (struct TALER_EXCHANGE_WireHandle *wh); /* ********************* /coins/$COIN_PUB/deposit *********************** */ +/** + * Sign a deposit permission. Function for wallets. + * + * @param amount the amount to be deposited + * @param deposit_fee the deposit fee we expect to pay + * @param h_wire hash of the merchant’s account details + * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) + * @param coin_priv coin’s private key + * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future + * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) + * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline + * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT + */ +void +TALER_EXCHANGE_deposit_permission_sign ( + const struct TALER_Amount *amount, + const struct TALER_Amount *deposit_fee, + const struct GNUNET_HashCode *h_wire, + const struct GNUNET_HashCode *h_contract_terms, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct GNUNET_TIME_Absolute wallet_timestamp, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct GNUNET_TIME_Absolute refund_deadline, + struct TALER_CoinSpendSignatureP *coin_sig); + + /** * @brief A Deposit Handle */ diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 276053658..351fa7a10 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -490,6 +490,59 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, } +/** + * Sign a deposit permission. Function for wallets. + * + * @param amount the amount to be deposited + * @param deposit_fee the deposit fee we expect to pay + * @param h_wire hash of the merchant’s account details + * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) + * @param coin_priv coin’s private key + * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future + * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) + * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline + * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT + */ +void +TALER_EXCHANGE_deposit_permission_sign ( + const struct TALER_Amount *amount, + const struct TALER_Amount *deposit_fee, + const struct GNUNET_HashCode *h_wire, + const struct GNUNET_HashCode *h_contract_terms, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct GNUNET_TIME_Absolute wallet_timestamp, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct GNUNET_TIME_Absolute refund_deadline, + struct TALER_CoinSpendSignatureP *coin_sig) +{ + struct TALER_DepositRequestPS dr = { + .purpose.size = htonl + (sizeof (dr)), + .purpose.purpose = htonl + (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), + .h_contract_terms = *h_contract_terms, + .h_wire = *h_wire, + .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp), + .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), + .merchant = *merchant_pub + }; + + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&wallet_timestamp)); + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&refund_deadline)); + GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, + &dr.coin_pub.eddsa_pub); + TALER_amount_hton (&dr.amount_with_fee, + amount); + TALER_amount_hton (&dr.deposit_fee, + deposit_fee); + GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, + &dr, + &coin_sig->eddsa_signature); +} + + /** * Submit a deposit permission to the exchange and get the exchange's response. * Note that while we return the response verbatim to the caller for diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index f302a218b..e7a4c2988 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -394,39 +394,26 @@ deposit_run (void *cls, else { ds->refund_deadline = ds->wallet_timestamp; - wire_deadline = GNUNET_TIME_relative_to_absolute - (GNUNET_TIME_UNIT_ZERO); + wire_deadline = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_ZERO); } GNUNET_CRYPTO_eddsa_key_get_public (&ds->merchant_priv.eddsa_priv, &merchant_pub.eddsa_pub); - (void) GNUNET_TIME_round_abs (&wire_deadline); - - // FIXME: This should be part of TALER_EXCHANGE_deposit()! { - struct TALER_DepositRequestPS dr; - - memset (&dr, 0, sizeof (dr)); - dr.purpose.size = htonl - (sizeof (struct TALER_DepositRequestPS)); - dr.purpose.purpose = htonl - (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); - dr.h_contract_terms = h_contract_terms; + struct GNUNET_HashCode h_wire; + GNUNET_assert (GNUNET_OK == TALER_JSON_merchant_wire_signature_hash (ds->wire_details, - &dr.h_wire)); - dr.wallet_timestamp = GNUNET_TIME_absolute_hton (ds->wallet_timestamp); - dr.refund_deadline = GNUNET_TIME_absolute_hton - (ds->refund_deadline); - TALER_amount_hton (&dr.amount_with_fee, - &ds->amount); - TALER_amount_hton (&dr.deposit_fee, - &denom_pub->fee_deposit); - dr.merchant = merchant_pub; - dr.coin_pub = coin_pub; - GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, - &dr, - &coin_sig.eddsa_signature); + &h_wire)); + TALER_EXCHANGE_deposit_permission_sign (&ds->amount, + &denom_pub->fee_deposit, + &h_wire, + &h_contract_terms, + coin_priv, + ds->wallet_timestamp, + &merchant_pub, + ds->refund_deadline, + &coin_sig); } ds->dh = TALER_EXCHANGE_deposit (is->exchange, &ds->amount, -- cgit v1.2.3 From ed5b98a2c2308fbd44b906a30286d2689fd304dd Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 5 Jul 2020 16:58:43 +0200 Subject: GNUNET_free_non_null is gone, use GNUNET_free --- src/auditor/taler-auditor-exchange.c | 4 ++-- src/auditor/taler-auditor-httpd.c | 4 ++-- src/auditor/taler-auditor-sign.c | 4 ++-- src/auditor/taler-helper-auditor-coins.c | 4 ++-- src/auditor/taler-helper-auditor-reserves.c | 2 +- src/bank-lib/fakebank.c | 2 +- src/benchmark/taler-exchange-benchmark.c | 4 ++-- src/curl/curl.c | 2 +- src/exchange/taler-exchange-httpd.c | 8 ++++---- src/exchange/taler-exchange-httpd_refreshes_reveal.c | 4 ++-- src/exchange/taler-exchange-httpd_transfers_get.c | 2 +- src/exchangedb/exchangedb_accounts.c | 2 +- src/exchangedb/plugin_exchangedb_common.c | 6 +++--- src/exchangedb/plugin_exchangedb_postgres.c | 4 ++-- src/exchangedb/test_exchangedb.c | 4 ++-- src/exchangedb/test_exchangedb_auditors.c | 2 +- src/exchangedb/test_exchangedb_denomkeys.c | 6 +++--- src/lib/auditor_api_handle.c | 2 +- src/lib/exchange_api_common.c | 4 ++-- src/lib/exchange_api_handle.c | 2 +- src/lib/exchange_api_refresh_common.c | 6 +++--- src/testing/testing_api_cmd_bank_history_credit.c | 2 +- src/testing/testing_api_cmd_bank_history_debit.c | 2 +- src/testing/testing_api_cmd_batch.c | 2 +- src/testing/testing_api_cmd_exec_auditor-sign.c | 2 +- src/testing/testing_api_cmd_refresh.c | 8 ++++---- src/testing/testing_api_cmd_revoke.c | 2 +- src/testing/testing_api_cmd_serialize_keys.c | 2 +- src/testing/testing_api_cmd_withdraw.c | 2 +- src/testing/testing_api_loop.c | 4 ++-- 30 files changed, 52 insertions(+), 52 deletions(-) (limited to 'src/lib') diff --git a/src/auditor/taler-auditor-exchange.c b/src/auditor/taler-auditor-exchange.c index 41df335b3..2091031cb 100644 --- a/src/auditor/taler-auditor-exchange.c +++ b/src/auditor/taler-auditor-exchange.c @@ -111,10 +111,10 @@ main (int argc, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed configuration file `%s', exit ...\n", cfgfile); - GNUNET_free_non_null (cfgfile); + GNUNET_free (cfgfile); return 1; } - GNUNET_free_non_null (cfgfile); + GNUNET_free (cfgfile); if (! remove_flag) { diff --git a/src/auditor/taler-auditor-httpd.c b/src/auditor/taler-auditor-httpd.c index d326f0f62..d1e3c2de5 100644 --- a/src/auditor/taler-auditor-httpd.c +++ b/src/auditor/taler-auditor-httpd.c @@ -579,10 +579,10 @@ main (int argc, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed configuration file `%s', exiting ...\n", cfgfile); - GNUNET_free_non_null (cfgfile); + GNUNET_free (cfgfile); return 1; } - GNUNET_free_non_null (cfgfile); + GNUNET_free (cfgfile); if (GNUNET_OK != auditor_serve_process_config ()) diff --git a/src/auditor/taler-auditor-sign.c b/src/auditor/taler-auditor-sign.c index 7dd7605fb..af6cec2c4 100644 --- a/src/auditor/taler-auditor-sign.c +++ b/src/auditor/taler-auditor-sign.c @@ -213,10 +213,10 @@ main (int argc, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed configuration file `%s', exiting ...\n", cfgfile); - GNUNET_free_non_null (cfgfile); + GNUNET_free (cfgfile); return 1; } - GNUNET_free_non_null (cfgfile); + GNUNET_free (cfgfile); if ( (NULL == auditor_key_file) && (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 158baa8b3..1a03ac72d 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1351,7 +1351,7 @@ refresh_session_cb (void *cls, if (GNUNET_OK != reveal_ctx.err) { - GNUNET_free_non_null (reveal_ctx.new_issues); + GNUNET_free (reveal_ctx.new_issues); return (GNUNET_SYSERR == reveal_ctx.err) ? GNUNET_SYSERR : GNUNET_OK; } @@ -1458,7 +1458,7 @@ refresh_session_cb (void *cls, &value); } } - GNUNET_free_non_null (reveal_ctx.new_issues); + GNUNET_free (reveal_ctx.new_issues); } /* update old coin's denomination balance */ diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c index 3460515a2..0b140e740 100644 --- a/src/auditor/taler-helper-auditor-reserves.c +++ b/src/auditor/taler-helper-auditor-reserves.c @@ -1269,7 +1269,7 @@ verify_reserve_balance (void *cls, GNUNET_CONTAINER_multihashmap_remove (rc->reserves, key, rs)); - GNUNET_free_non_null (rs->sender_account); + GNUNET_free (rs->sender_account); GNUNET_free (rs); return ret; } diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c index 6df6cdfad..699acb51b 100644 --- a/src/bank-lib/fakebank.c +++ b/src/bank-lib/fakebank.c @@ -1314,7 +1314,7 @@ handle_mhd_request (void *cls, upload_data, upload_data_size, con_cls); - GNUNET_free_non_null (account); + GNUNET_free (account); return ret; } diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index 57fde4306..7054e01e2 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -993,7 +993,7 @@ main (int argc, argc, argv))) { - GNUNET_free_non_null (cfg_filename); + GNUNET_free (cfg_filename); return BAD_CLI_ARG; } GNUNET_log_setup ("taler-exchange-benchmark", @@ -1010,7 +1010,7 @@ main (int argc, else { TALER_LOG_ERROR ("Unknown mode given: '%s'\n", mode_str); - GNUNET_free_non_null (cfg_filename); + GNUNET_free (cfg_filename); return BAD_CONFIG_FILE; } if (NULL == cfg_filename) diff --git a/src/curl/curl.c b/src/curl/curl.c index dd1194906..9e9de6810 100644 --- a/src/curl/curl.c +++ b/src/curl/curl.c @@ -111,6 +111,6 @@ TALER_curl_easy_post_finished (struct TALER_CURL_PostContext *ctx) { curl_slist_free_all (ctx->headers); ctx->headers = NULL; - GNUNET_free_non_null (ctx->json_enc); + GNUNET_free (ctx->json_enc); ctx->json_enc = NULL; } diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index df01b01be..c614b711e 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -1300,8 +1300,8 @@ main (int argc, GNUNET_log_setup ("taler-exchange-httpd", (NULL == loglev) ? "INFO" : loglev, logfile)); - GNUNET_free_non_null (loglev); - GNUNET_free_non_null (logfile); + GNUNET_free (loglev); + GNUNET_free (logfile); if (NULL == cfgfile) cfgfile = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file); TEH_cfg = GNUNET_CONFIGURATION_create (); @@ -1312,10 +1312,10 @@ main (int argc, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed configuration file `%s', exit ...\n", cfgfile); - GNUNET_free_non_null (cfgfile); + GNUNET_free (cfgfile); return 1; } - GNUNET_free_non_null (cfgfile); + GNUNET_free (cfgfile); if (GNUNET_OK != exchange_serve_process_config ()) return 1; diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index a9c998af0..e752ce969 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -608,7 +608,7 @@ resolve_refreshes_reveal_denominations (struct TEH_KS_StateHandle *key_state, if (GNUNET_OK != res) { for (unsigned int j = 0; jdk = &dkis[i]->denom_pub; @@ -792,7 +792,7 @@ cleanup: rctx->ev_sigs = NULL; /* just to be safe... */ } for (unsigned int i = 0; iwire_method); + GNUNET_free (ctx->wire_method); ctx->wire_method = NULL; } diff --git a/src/exchangedb/exchangedb_accounts.c b/src/exchangedb/exchangedb_accounts.c index b66b1bcc1..986d4ae2d 100644 --- a/src/exchangedb/exchangedb_accounts.c +++ b/src/exchangedb/exchangedb_accounts.c @@ -125,7 +125,7 @@ check_for_account (void *cls, } GNUNET_free (payto_uri); GNUNET_free (method); - GNUNET_free_non_null (wire_response_filename); + GNUNET_free (wire_response_filename); } diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c index ce425f824..6db0c0e02 100644 --- a/src/exchangedb/plugin_exchangedb_common.c +++ b/src/exchangedb/plugin_exchangedb_common.c @@ -40,8 +40,8 @@ common_free_reserve_history (void *cls, struct TALER_EXCHANGEDB_BankTransfer *bt; bt = rh->details.bank; - GNUNET_free_non_null (bt->sender_account_details); - GNUNET_free_non_null (bt->wire_reference); + GNUNET_free (bt->sender_account_details); + GNUNET_free (bt->wire_reference); GNUNET_free (bt); break; } @@ -68,7 +68,7 @@ common_free_reserve_history (void *cls, struct TALER_EXCHANGEDB_ClosingTransfer *closing; closing = rh->details.closing; - GNUNET_free_non_null (closing->receiver_account_details); + GNUNET_free (closing->receiver_account_details); GNUNET_free (closing); break; } diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 641cbbef1..dede901f9 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -3830,9 +3830,9 @@ cleanup: GNUNET_CRYPTO_rsa_public_key_free (rrc->denom_pub.rsa_public_key); if (NULL != rrc->coin_sig.rsa_signature) GNUNET_CRYPTO_rsa_signature_free (rrc->coin_sig.rsa_signature); - GNUNET_free_non_null (rrc->coin_ev); + GNUNET_free (rrc->coin_ev); } - GNUNET_free_non_null (grctx.rrcs); + GNUNET_free (grctx.rrcs); return qs; } diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index fe3ed7854..043095e7b 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -706,12 +706,12 @@ drop: destroy_denom_key_pair (dkp); GNUNET_CRYPTO_rsa_signature_free ( refresh_session.coin.denom_sig.rsa_signature); - GNUNET_free_non_null (new_denom_pubs); + GNUNET_free (new_denom_pubs); for (unsigned int cnt = 0; (NULL != new_dkp) && (cnt < MELT_NEW_COINS) && (NULL != new_dkp[cnt]); cnt++) destroy_denom_key_pair (new_dkp[cnt]); - GNUNET_free_non_null (new_dkp); + GNUNET_free (new_dkp); return ret; } diff --git a/src/exchangedb/test_exchangedb_auditors.c b/src/exchangedb/test_exchangedb_auditors.c index efd3ffe14..2af1776aa 100644 --- a/src/exchangedb/test_exchangedb_auditors.c +++ b/src/exchangedb/test_exchangedb_auditors.c @@ -164,6 +164,6 @@ EXITIF_exit: } if (NULL != cfg) GNUNET_CONFIGURATION_destroy (cfg); - GNUNET_free_non_null (tmpfile); + GNUNET_free (tmpfile); return ret; } diff --git a/src/exchangedb/test_exchangedb_denomkeys.c b/src/exchangedb/test_exchangedb_denomkeys.c index 1acb61dde..b28b2999b 100644 --- a/src/exchangedb/test_exchangedb_denomkeys.c +++ b/src/exchangedb/test_exchangedb_denomkeys.c @@ -194,14 +194,14 @@ main (int argc, ret = 0; EXITIF_exit: - GNUNET_free_non_null (enc); - GNUNET_free_non_null (tmpfile); + GNUNET_free (enc); + GNUNET_free (tmpfile); if (NULL != tmpdir) { (void) GNUNET_DISK_directory_remove (tmpdir); GNUNET_free (tmpdir); } - GNUNET_free_non_null (enc_read); + GNUNET_free (enc_read); if (NULL != dki.denom_priv.rsa_private_key) GNUNET_CRYPTO_rsa_private_key_free (dki.denom_priv.rsa_private_key); if (NULL != dki.denom_pub.rsa_public_key) diff --git a/src/lib/auditor_api_handle.c b/src/lib/auditor_api_handle.c index ccb7cc1eb..731dcf0c3 100644 --- a/src/lib/auditor_api_handle.c +++ b/src/lib/auditor_api_handle.c @@ -525,7 +525,7 @@ TALER_AUDITOR_disconnect (struct TALER_AUDITOR_Handle *auditor) free_version_request (auditor->vr); auditor->vr = NULL; } - GNUNET_free_non_null (auditor->version); + GNUNET_free (auditor->version); if (NULL != auditor->retry_task) { GNUNET_SCHEDULER_cancel (auditor->retry_task); diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index bf8eb5376..e7e87487b 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -425,8 +425,8 @@ TALER_EXCHANGE_free_reserve_history ( switch (rhistory[i].type) { case TALER_EXCHANGE_RTT_CREDIT: - GNUNET_free_non_null (rhistory[i].details.in_details.wire_reference); - GNUNET_free_non_null (rhistory[i].details.in_details.sender_url); + GNUNET_free (rhistory[i].details.in_details.wire_reference); + GNUNET_free (rhistory[i].details.in_details.sender_url); break; case TALER_EXCHANGE_RTT_WITHDRAWAL: break; diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index c9c1b09bd..283f77043 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -1135,7 +1135,7 @@ free_key_data (struct TALER_EXCHANGE_Keys *key_data) GNUNET_array_grow (key_data->auditors, key_data->auditors_size, 0); - GNUNET_free_non_null (key_data->version); + GNUNET_free (key_data->version); key_data->version = NULL; } diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c index 9e9f6e0c0..8ac0bdfc9 100644 --- a/src/lib/exchange_api_refresh_common.c +++ b/src/lib/exchange_api_refresh_common.c @@ -61,7 +61,7 @@ TALER_EXCHANGE_free_melt_data_ (struct MeltData *md) } for (unsigned int i = 0; ifresh_coins[i]); + GNUNET_free (md->fresh_coins[i]); /* Finally, clean up a bit... */ GNUNET_CRYPTO_zero_keys (md, sizeof (struct MeltData)); @@ -613,8 +613,8 @@ TALER_EXCHANGE_refresh_prepare ( for (unsigned int i = 0; i < TALER_CNC_KAPPA; i++) { for (unsigned int j = 0; j < fresh_pks_len; j++) - GNUNET_free_non_null (rce[i].new_coins[j].coin_ev); - GNUNET_free_non_null (rce[i].new_coins); + GNUNET_free (rce[i].new_coins[j].coin_ev); + GNUNET_free (rce[i].new_coins); } TALER_EXCHANGE_free_melt_data_ (&md); return buf; diff --git a/src/testing/testing_api_cmd_bank_history_credit.c b/src/testing/testing_api_cmd_bank_history_credit.c index 0b71c7162..069f62cb0 100644 --- a/src/testing/testing_api_cmd_bank_history_credit.c +++ b/src/testing/testing_api_cmd_bank_history_credit.c @@ -549,7 +549,7 @@ history_cleanup (void *cls, GNUNET_free (hs->account_url); for (unsigned int off = 0; offtotal; off++) GNUNET_free (hs->h[off].url); - GNUNET_free_non_null (hs->h); + GNUNET_free (hs->h); GNUNET_free (hs); } diff --git a/src/testing/testing_api_cmd_bank_history_debit.c b/src/testing/testing_api_cmd_bank_history_debit.c index ebabf8d94..fcc78bfb7 100644 --- a/src/testing/testing_api_cmd_bank_history_debit.c +++ b/src/testing/testing_api_cmd_bank_history_debit.c @@ -552,7 +552,7 @@ history_cleanup (void *cls, GNUNET_free (hs->h[off].c_url); GNUNET_free (hs->h[off].d_url); } - GNUNET_free_non_null (hs->h); + GNUNET_free (hs->h); GNUNET_free (hs); } diff --git a/src/testing/testing_api_cmd_batch.c b/src/testing/testing_api_cmd_batch.c index d81a5c38d..ca23d7fd9 100644 --- a/src/testing/testing_api_cmd_batch.c +++ b/src/testing/testing_api_cmd_batch.c @@ -99,7 +99,7 @@ batch_cleanup (void *cls, i++) bs->batch[i].cleanup (bs->batch[i].cls, &bs->batch[i]); - GNUNET_free_non_null (bs->batch); + GNUNET_free (bs->batch); GNUNET_free (bs); } diff --git a/src/testing/testing_api_cmd_exec_auditor-sign.c b/src/testing/testing_api_cmd_exec_auditor-sign.c index 4c88ccca0..82d7e6669 100644 --- a/src/testing/testing_api_cmd_exec_auditor-sign.c +++ b/src/testing/testing_api_cmd_exec_auditor-sign.c @@ -166,7 +166,7 @@ auditor_sign_cleanup (void *cls, GNUNET_OS_process_destroy (ass->auditor_sign_proc); ass->auditor_sign_proc = NULL; } - GNUNET_free_non_null (ass->signed_keys_out); + GNUNET_free (ass->signed_keys_out); GNUNET_free (ass); } diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c index 92229cc72..9a13c1354 100644 --- a/src/testing/testing_api_cmd_refresh.c +++ b/src/testing/testing_api_cmd_refresh.c @@ -514,7 +514,7 @@ refresh_reveal_cleanup (void *cls, for (unsigned int j = 0; j < rrs->num_fresh_coins; j++) GNUNET_CRYPTO_rsa_signature_free (rrs->fresh_coins[j].sig.rsa_signature); - GNUNET_free_non_null (rrs->fresh_coins); + GNUNET_free (rrs->fresh_coins); rrs->fresh_coins = NULL; rrs->num_fresh_coins = 0; GNUNET_free (rrs); @@ -1128,12 +1128,12 @@ melt_cleanup (void *cls, for (unsigned int i = 0; i < rms->num_fresh_coins; i++) GNUNET_CRYPTO_rsa_public_key_free (rms->fresh_pks[i].key.rsa_public_key); } - GNUNET_free_non_null (rms->fresh_pks); + GNUNET_free (rms->fresh_pks); rms->fresh_pks = NULL; - GNUNET_free_non_null (rms->refresh_data); + GNUNET_free (rms->refresh_data); rms->refresh_data = NULL; rms->refresh_data_length = 0; - GNUNET_free_non_null (rms->melt_fresh_amounts); + GNUNET_free (rms->melt_fresh_amounts); GNUNET_free (rms); } diff --git a/src/testing/testing_api_cmd_revoke.c b/src/testing/testing_api_cmd_revoke.c index 1006fbc34..d9320865a 100644 --- a/src/testing/testing_api_cmd_revoke.c +++ b/src/testing/testing_api_cmd_revoke.c @@ -85,7 +85,7 @@ revoke_cleanup (void *cls, GNUNET_OS_process_destroy (rs->revoke_proc); rs->revoke_proc = NULL; } - GNUNET_free_non_null (rs->dhks); + GNUNET_free (rs->dhks); GNUNET_free (rs); } diff --git a/src/testing/testing_api_cmd_serialize_keys.c b/src/testing/testing_api_cmd_serialize_keys.c index 8a723c5ba..aa39b8a37 100644 --- a/src/testing/testing_api_cmd_serialize_keys.c +++ b/src/testing/testing_api_cmd_serialize_keys.c @@ -117,7 +117,7 @@ serialize_keys_cleanup (void *cls, { json_decref (sks->keys); } - GNUNET_free_non_null (sks->exchange_url); + GNUNET_free (sks->exchange_url); GNUNET_free (sks); } diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index d863e406a..5db97cbff 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -387,7 +387,7 @@ withdraw_cleanup (void *cls, TALER_EXCHANGE_destroy_denomination_key (ws->pk); ws->pk = NULL; } - GNUNET_free_non_null (ws->exchange_url); + GNUNET_free (ws->exchange_url); GNUNET_free (ws); } diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index af4a63c6a..fceff4234 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c @@ -355,7 +355,7 @@ do_shutdown (void *cls) TALER_FAKEBANK_stop (is->fakebank); is->fakebank = NULL; } - GNUNET_free_non_null (is->commands); + GNUNET_free (is->commands); } @@ -813,7 +813,7 @@ TALER_TESTING_setup (TALER_TESTING_Main main_cb, &main_ctx); if (NULL != is.final_cleanup_cb) is.final_cleanup_cb (is.final_cleanup_cb_cls); - GNUNET_free_non_null (main_ctx.exchange_url); + GNUNET_free (main_ctx.exchange_url); GNUNET_SIGNAL_handler_uninstall (shc_chld); GNUNET_DISK_pipe_close (sigpipe); sigpipe = NULL; -- cgit v1.2.3