From 166352e87e59f8525b501f87c5ecc3fce182835d Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 7 Jun 2016 15:14:44 +0200 Subject: [PATCH 1/3] add exchange_pub to callbacks --- ChangeLog | 5 +++++ src/benchmark/taler-exchange-benchmark.c | 2 ++ src/exchange-lib/exchange_api_deposit.c | 22 ++++++++++++++----- src/exchange-lib/exchange_api_deposit_wtid.c | 21 +++++++++++++----- src/exchange-lib/exchange_api_refresh.c | 15 ++++++++----- src/exchange-lib/exchange_api_refund.c | 21 +++++++++++++----- src/exchange-lib/exchange_api_wire_deposits.c | 2 ++ src/exchange-lib/test_exchange_api.c | 10 +++++++++ src/include/taler_exchange_service.h | 10 +++++++++ 9 files changed, 85 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index c7ee8017f..24d9badcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,2 +1,7 @@ +Tue Jun 7 15:13:46 CEST 2016 + Adding public key of the exchange that was used to sign replies + to applicable callbacks of libtalerexchange. (This will eventually + be needed by the merchant's backend.) -CG + Wed Jun 1 17:27:36 CEST 2016 Releasing taler-exchange 0.0.0. -CG diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index 7e19d8318..53c49df80 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -222,12 +222,14 @@ fail (const char *msg) * @param cls closure with the interpreter state * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param exchange_pub public key used by the exchange for signing * @param obj the received JSON reply, should be kept as proof (and, in case of errors, * be forwarded to the customer) */ static void deposit_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *obj) { unsigned int coin_index = (unsigned int) (long) cls; diff --git a/src/exchange-lib/exchange_api_deposit.c b/src/exchange-lib/exchange_api_deposit.c index 4d13febf4..e65684acf 100644 --- a/src/exchange-lib/exchange_api_deposit.c +++ b/src/exchange-lib/exchange_api_deposit.c @@ -94,18 +94,20 @@ struct TALER_EXCHANGE_DepositHandle * * @param dh deposit handle * @param json json reply with the signature + * @param exchange_pub set to the exchange's public key * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_deposit_signature_ok (const struct TALER_EXCHANGE_DepositHandle *dh, - const json_t *json) + const json_t *json, + struct TALER_ExchangePublicKeyP *exchange_pub) { struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; + 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 ("pub", exchange_pub), GNUNET_JSON_spec_end() }; @@ -120,7 +122,7 @@ verify_deposit_signature_ok (const struct TALER_EXCHANGE_DepositHandle *dh, key_state = TALER_EXCHANGE_get_keys (dh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) + exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -129,7 +131,7 @@ verify_deposit_signature_ok (const struct TALER_EXCHANGE_DepositHandle *dh, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT, &dh->depconf.purpose, &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -200,6 +202,8 @@ handle_deposit_finished (void *cls, const json_t *json) { struct TALER_EXCHANGE_DepositHandle *dh = cls; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangePublicKeyP *ep = NULL; dh->job = NULL; switch (response_code) @@ -209,11 +213,16 @@ handle_deposit_finished (void *cls, case MHD_HTTP_OK: if (GNUNET_OK != verify_deposit_signature_ok (dh, - json)) + json, + &exchange_pub)) { GNUNET_break_op (0); response_code = 0; } + else + { + ep = &exchange_pub; + } break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy @@ -253,6 +262,7 @@ handle_deposit_finished (void *cls, } dh->cb (dh->cb_cls, response_code, + ep, json); TALER_EXCHANGE_deposit_cancel (dh); } diff --git a/src/exchange-lib/exchange_api_deposit_wtid.c b/src/exchange-lib/exchange_api_deposit_wtid.c index 073ce2b35..66b91413c 100644 --- a/src/exchange-lib/exchange_api_deposit_wtid.c +++ b/src/exchange-lib/exchange_api_deposit_wtid.c @@ -84,18 +84,19 @@ struct TALER_EXCHANGE_DepositWtidHandle * * @param dwh deposit wtid handle * @param json json reply with the signature + * @param[out] exchange_pub set to the exchange's public key * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_deposit_wtid_signature_ok (const struct TALER_EXCHANGE_DepositWtidHandle *dwh, - const json_t *json) + const json_t *json, + struct TALER_ExchangePublicKeyP *exchange_pub) { struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; 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_fixed_auto ("exchange_pub", exchange_pub), GNUNET_JSON_spec_end() }; @@ -110,7 +111,7 @@ verify_deposit_wtid_signature_ok (const struct TALER_EXCHANGE_DepositWtidHandle key_state = TALER_EXCHANGE_get_keys (dwh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) + exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -119,7 +120,7 @@ verify_deposit_wtid_signature_ok (const struct TALER_EXCHANGE_DepositWtidHandle GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE, &dwh->depconf.purpose, &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -146,6 +147,8 @@ handle_deposit_wtid_finished (void *cls, 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; dwh->job = NULL; switch (response_code) @@ -177,11 +180,16 @@ handle_deposit_wtid_finished (void *cls, coin_contribution = &coin_contribution_s; if (GNUNET_OK != verify_deposit_wtid_signature_ok (dwh, - json)) + json, + &exchange_pub)) { GNUNET_break_op (0); response_code = 0; } + else + { + ep = &exchange_pub; + } } break; case MHD_HTTP_ACCEPTED: @@ -231,6 +239,7 @@ handle_deposit_wtid_finished (void *cls, } dwh->cb (dwh->cb_cls, response_code, + ep, json, wtid, execution_time, diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c index 7e207d795..b86e58362 100644 --- a/src/exchange-lib/exchange_api_refresh.c +++ b/src/exchange-lib/exchange_api_refresh.c @@ -951,20 +951,21 @@ struct TALER_EXCHANGE_RefreshMeltHandle * * @param rmh melt handle * @param json json reply with the signature + * @param[out] exchange_pub public key of the exchange used for the signature * @param[out] noreveal_index set to the noreveal index selected by the exchange * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_refresh_melt_signature_ok (struct TALER_EXCHANGE_RefreshMeltHandle *rmh, const json_t *json, + struct TALER_ExchangePublicKeyP *exchange_pub, uint16_t *noreveal_index) { struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; 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_fixed_auto ("exchange_pub", exchange_pub), GNUNET_JSON_spec_uint16 ("noreveal_index", noreveal_index), GNUNET_JSON_spec_end() }; @@ -983,7 +984,7 @@ verify_refresh_melt_signature_ok (struct TALER_EXCHANGE_RefreshMeltHandle *rmh, key_state = TALER_EXCHANGE_get_keys (rmh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) + exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -1006,7 +1007,7 @@ verify_refresh_melt_signature_ok (struct TALER_EXCHANGE_RefreshMeltHandle *rmh, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT, &confirm.purpose, &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -1126,6 +1127,7 @@ handle_refresh_melt_finished (void *cls, { struct TALER_EXCHANGE_RefreshMeltHandle *rmh = cls; uint16_t noreveal_index = TALER_CNC_KAPPA; /* invalid value */ + struct TALER_ExchangePublicKeyP exchange_pub; rmh->job = NULL; switch (response_code) @@ -1136,6 +1138,7 @@ handle_refresh_melt_finished (void *cls, if (GNUNET_OK != verify_refresh_melt_signature_ok (rmh, json, + &exchange_pub, &noreveal_index)) { GNUNET_break_op (0); @@ -1146,6 +1149,7 @@ handle_refresh_melt_finished (void *cls, rmh->melt_cb (rmh->melt_cb_cls, response_code, noreveal_index, + (0 == response_code) ? NULL : &exchange_pub, json); rmh->melt_cb = NULL; } @@ -1190,6 +1194,7 @@ handle_refresh_melt_finished (void *cls, rmh->melt_cb (rmh->melt_cb_cls, response_code, UINT16_MAX, + NULL, json); TALER_EXCHANGE_refresh_melt_cancel (rmh); } @@ -1731,7 +1736,7 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *ctx; struct MeltData *md; unsigned int j; - + GNUNET_assert (GNUNET_YES == MAH_handle_is_ready (exchange)); md = deserialize_melt_data (refresh_data, diff --git a/src/exchange-lib/exchange_api_refund.c b/src/exchange-lib/exchange_api_refund.c index d622ddc75..fff03acf9 100644 --- a/src/exchange-lib/exchange_api_refund.c +++ b/src/exchange-lib/exchange_api_refund.c @@ -83,18 +83,19 @@ struct TALER_EXCHANGE_RefundHandle * * @param rh refund handle * @param json json reply with the signature + * @param[out] exchange_pub set to the exchange's public key * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, - const json_t *json) + const json_t *json, + struct TALER_ExchangePublicKeyP *exchange_pub) { struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; 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 ("pub", exchange_pub), GNUNET_JSON_spec_end() }; @@ -109,7 +110,7 @@ verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, key_state = TALER_EXCHANGE_get_keys (rh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) + exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -118,7 +119,7 @@ verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND, &rh->depconf.purpose, &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -141,6 +142,8 @@ handle_refund_finished (void *cls, const json_t *json) { struct TALER_EXCHANGE_RefundHandle *rh = cls; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangePublicKeyP *ep = NULL; rh->job = NULL; switch (response_code) @@ -150,11 +153,16 @@ handle_refund_finished (void *cls, case MHD_HTTP_OK: if (GNUNET_OK != verify_refund_signature_ok (rh, - json)) + json, + &exchange_pub)) { GNUNET_break_op (0); response_code = 0; } + else + { + ep = &exchange_pub; + } break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy @@ -188,6 +196,7 @@ handle_refund_finished (void *cls, } rh->cb (rh->cb_cls, response_code, + ep, json); TALER_EXCHANGE_refund_cancel (rh); } diff --git a/src/exchange-lib/exchange_api_wire_deposits.c b/src/exchange-lib/exchange_api_wire_deposits.c index 0601f9b4a..91e2aef7b 100644 --- a/src/exchange-lib/exchange_api_wire_deposits.c +++ b/src/exchange-lib/exchange_api_wire_deposits.c @@ -186,6 +186,7 @@ handle_wire_deposits_finished (void *cls, break; wdh->cb (wdh->cb_cls, response_code, + &exchange_pub, json, &h_wire, &total_amount, @@ -224,6 +225,7 @@ handle_wire_deposits_finished (void *cls, } wdh->cb (wdh->cb_cls, response_code, + NULL, json, NULL, NULL, 0, NULL); TALER_EXCHANGE_wire_deposits_cancel (wdh); diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 75a9cfbd9..83fb0eb32 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -1028,12 +1028,14 @@ reserve_withdraw_cb (void *cls, * @param cls closure with the interpreter state * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param exchange_pub public key the exchange used for signing * @param obj the received JSON reply, should be kept as proof (and, in case of errors, * be forwarded to the customer) */ static void deposit_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *obj) { struct InterpreterState *is = cls; @@ -1062,12 +1064,14 @@ deposit_cb (void *cls, * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param noreveal_index choice by the exchange in the cut-and-choose protocol, * UINT16_MAX on error + * @param exchange_pub public key the exchange used for signing * @param full_response full response from the exchange (for logging, in case of errors) */ static void melt_cb (void *cls, unsigned int http_status, uint16_t noreveal_index, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *full_response) { struct InterpreterState *is = cls; @@ -1388,6 +1392,7 @@ wire_cb (void *cls, * * @param cls closure * @param http_status HTTP status code we got, 0 on exchange protocol violation + * @param exchange_pub public key the exchange used for signing * @param json original json reply (may include signatures, those have then been * validated already) * @param wtid extracted wire transfer identifier, or NULL if the exchange could @@ -1400,6 +1405,7 @@ wire_cb (void *cls, static void wire_deposits_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *json, const struct GNUNET_HashCode *h_wire, const struct TALER_Amount *total_amount, @@ -1515,6 +1521,7 @@ wire_deposits_cb (void *cls, * * @param cls closure * @param http_status HTTP status code we got, 0 on exchange protocol violation + * @param exchange_pub public key the exchange used for signing * @param json original json reply (may include signatures, those have then been * validated already) * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not @@ -1527,6 +1534,7 @@ wire_deposits_cb (void *cls, static void deposit_wtid_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *json, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute execution_time, @@ -1580,12 +1588,14 @@ deposit_wtid_cb (void *cls, * @param cls closure * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param exchange_pub public key the exchange used for signing @a obj * @param obj the received JSON reply, should be kept as proof (and, in particular, * be forwarded to the customer) */ static void refund_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *obj) { struct InterpreterState *is = cls; diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index e65a9faee..5f79b9bee 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -416,12 +416,14 @@ struct TALER_EXCHANGE_DepositHandle; * @param cls closure * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param sign_key exchange key used to sign @a obj, or NULL * @param obj the received JSON reply, should be kept as proof (and, in case of errors, * be forwarded to the customer) */ typedef void (*TALER_EXCHANGE_DepositResultCallback) (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *obj); @@ -502,12 +504,14 @@ struct TALER_EXCHANGE_RefundHandle; * @param cls closure * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param sign_key exchange key used to sign @a obj, or NULL * @param obj the received JSON reply, should be kept as proof (and, in particular, * be forwarded to the customer) */ typedef void (*TALER_EXCHANGE_RefundResultCallback) (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *obj); @@ -833,12 +837,14 @@ struct TALER_EXCHANGE_RefreshMeltHandle; * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param noreveal_index choice by the exchange in the cut-and-choose protocol, * UINT16_MAX on error + * @param sign_key exchange key used to sign @a full_response, or NULL * @param full_response full response from the exchange (for logging, in case of errors) */ typedef void (*TALER_EXCHANGE_RefreshMeltCallback) (void *cls, unsigned int http_status, uint16_t noreveal_index, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *full_response); @@ -1135,6 +1141,7 @@ struct TALER_WireDepositDetails * * @param cls closure * @param http_status HTTP status code we got, 0 on exchange protocol violation + * @param sign_key exchange key used to sign @a json, or NULL * @param json original json reply (may include signatures, those have then been * validated already) * @param wtid extracted wire transfer identifier, or NULL if the exchange could @@ -1147,6 +1154,7 @@ struct TALER_WireDepositDetails typedef void (*TALER_EXCHANGE_WireDepositsCallback)(void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *json, const struct GNUNET_HashCode *h_wire, const struct TALER_Amount *total_amount, @@ -1195,6 +1203,7 @@ struct TALER_EXCHANGE_DepositWtidHandle; * * @param cls closure * @param http_status HTTP status code we got, 0 on exchange protocol violation + * @param sign_key exchange key used to sign @a json, or NULL * @param json original json reply (may include signatures, those have then been * validated already) * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not @@ -1205,6 +1214,7 @@ struct TALER_EXCHANGE_DepositWtidHandle; typedef void (*TALER_EXCHANGE_DepositWtidCallback)(void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *json, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute execution_time, From ca8e309877af153b14e50f8852197294886643e6 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Tue, 7 Jun 2016 16:58:55 +0200 Subject: [PATCH 2/3] adding find_pk() to benchmark --- src/benchmark/taler-exchange-benchmark.c | 119 ++++++++++++++++++++--- 1 file changed, 108 insertions(+), 11 deletions(-) diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index 7e19d8318..ff9768697 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -75,7 +75,7 @@ struct Coin { * use. Otherwise, this will be set (by the interpreter) to the * denomination PK matching @e amount. */ - struct TALER_EXCHANGE_DenomPublicKey *pk; + const struct TALER_EXCHANGE_DenomPublicKey *pk; /** * Set (by the interpreter) to the exchange's signature over the @@ -103,6 +103,16 @@ struct Coin { */ struct TALER_EXCHANGE_DepositHandle *dh; + /** + * Refresh melt handle + */ + struct TALER_EXCHANGE_RefreshMeltHandle *rmh; + + /** + * Refresh reveal handle + */ + struct TALER_EXCHANGE_RefreshRevealHandle *rrh; + }; /** @@ -173,17 +183,34 @@ static struct TALER_MerchantPrivateKeyP merchant_priv; */ #define COINS_PER_RESERVE 12 +/** + * Used currency (to be preferably gotten via config file, together + * exchange URI and other needed values) + */ +#define CURRENCY "KUDOS" + + /** * Large enough value to allow having 12 coins per reserve without parsing * /keys in the first place */ -#define RESERVE_AMOUNT "PUDOS:1000" +#define RESERVE_AMOUNT CURRENCY":1000" /** * Probability a coin can be spent */ #define SPEND_PROBABILITY 0.1 +/** + * Probability a coin can be refreshed + */ +#define REFRESH_PROBABILITY 0.1 + +/** + * Refreshed once. For each batch of deposits, only one + * coin will be refreshed, according to #REFRESH_PROBABILITY + */ +static unsigned int refreshed_once = GNUNET_NO; static unsigned int eval_probability (float probability) @@ -216,6 +243,60 @@ fail (const char *msg) } +/** + * Find denomination key matching the given amount. + * + * @param keys array of keys to search + * @param amount coin value to look for + * @return NULL if no matching key was found + */ +static const struct TALER_EXCHANGE_DenomPublicKey * +find_pk (const struct TALER_EXCHANGE_Keys *keys, + const struct TALER_Amount *amount) +{ + unsigned int i; + struct GNUNET_TIME_Absolute now; + struct TALER_EXCHANGE_DenomPublicKey *pk; + char *str; + + now = GNUNET_TIME_absolute_get (); + for (i=0;inum_denom_keys;i++) + { + pk = &keys->denom_keys[i]; + if ( (0 == TALER_amount_cmp (amount, + &pk->value)) && + (now.abs_value_us >= pk->valid_from.abs_value_us) && + (now.abs_value_us < pk->withdraw_valid_until.abs_value_us) ) + return pk; + } + /* do 2nd pass to check if expiration times are to blame for failure */ + str = TALER_amount_to_string (amount); + for (i=0;inum_denom_keys;i++) + { + pk = &keys->denom_keys[i]; + if ( (0 == TALER_amount_cmp (amount, + &pk->value)) && + ( (now.abs_value_us < pk->valid_from.abs_value_us) || + (now.abs_value_us > pk->withdraw_valid_until.abs_value_us) ) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Have denomination key for `%s', but with wrong expiration range %llu vs [%llu,%llu)\n", + str, + (unsigned long long) now.abs_value_us, + (unsigned long long) pk->valid_from.abs_value_us, + (unsigned long long) pk->withdraw_valid_until.abs_value_us); + GNUNET_free (str); + return NULL; + } + } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "No denomination key for amount %s found\n", + str); + GNUNET_free (str); + return NULL; +} + + /** * Function called with the result of a /deposit operation. * @@ -241,6 +322,13 @@ deposit_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Coin #%d correctly spent!\n", coin_index); GNUNET_array_append (spent_coins, spent_coins_size, coin_index); spent_coins_size++; + if (GNUNET_YES == eval_probability (REFRESH_PROBABILITY) + && GNUNET_NO == refreshed_once) + { + /* TODO: all the refresh logic here */ + refreshed_once = GNUNET_YES; + + } } /** @@ -294,7 +382,7 @@ reserve_withdraw_cb (void *cls, GNUNET_TIME_round_abs (×tamp); GNUNET_TIME_round_abs (&wire_deadline); GNUNET_TIME_round_abs (&refund_deadline); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Spending %d-th coin\n", coin_index); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Spending %d-th coin\n", coin_index); TALER_amount_subtract (&amount, &coins[coin_index].pk->value, &coins[coin_index].pk->fee_deposit); @@ -355,6 +443,7 @@ reserve_withdraw_cb (void *cls, /** * Function called upon completion of our /admin/add/incoming request. + * Its duty is withdrawing coins on the freshly created reserve. * * @param cls closure with the interpreter state * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request @@ -370,6 +459,7 @@ add_incoming_cb (void *cls, struct GNUNET_CRYPTO_EddsaPrivateKey *coin_priv; unsigned int i; unsigned int coin_index; + struct TALER_Amount amount; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "/admin/add/incoming callback called on %d-th reserve\n", @@ -384,8 +474,8 @@ add_incoming_cb (void *cls, coin_index = reserve_index * COINS_PER_RESERVE + i; coins[coin_index].coin_priv.eddsa_priv = *coin_priv; coins[coin_index].reserve_index = reserve_index; - /* Just pick the first denom key (the reserve is rich enough) */ - coins[coin_index].pk = &keys->denom_keys[0]; + TALER_string_to_amount (CURRENCY":5", &amount); + GNUNET_assert (NULL != (coins[coin_index].pk = find_pk (keys, &amount))); GNUNET_free (coin_priv); coins[coin_index].wsh = TALER_EXCHANGE_reserve_withdraw (exchange, @@ -400,7 +490,7 @@ add_incoming_cb (void *cls, /** - * Run the main interpreter loop that performs exchange operations. + * Benchmark runner. * * @param cls closure for benchmark_run() */ @@ -445,7 +535,6 @@ benchmark_run (void *cls) coins = GNUNET_new_array (COINS_PER_RESERVE * nreserves, struct Coin); - /* reserves */ for (i=0;i < nreserves && 0 < nreserves;i++) { priv = GNUNET_CRYPTO_eddsa_key_create (); @@ -500,7 +589,6 @@ cert_cb (void *cls, _keys->num_denom_keys); #undef ERR - /* run actual tests via interpreter-loop */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Certificate callback invoked, invoking benchmark_run()\n"); keys = _keys; @@ -510,7 +598,7 @@ cert_cb (void *cls, /** - * Function run when the test terminates (good or bad). + * Function run when the benchmark terminates (good or bad). * Cleans up our state. * * @param cls the interpreter state. @@ -549,6 +637,17 @@ do_shutdown (void *cls) TALER_EXCHANGE_deposit_cancel(coins[i].dh); coins[i].dh = NULL; } + if (NULL != coins[i].rmh) + { + TALER_EXCHANGE_refresh_melt_cancel(coins[i].rmh); + coins[i].rmh = NULL; + } + if (NULL != coins[i].rrh) + { + TALER_EXCHANGE_refresh_reveal_cancel(coins[i].rrh); + coins[i].rmh = NULL; + } + } GNUNET_free_non_null (reserves); @@ -570,8 +669,6 @@ do_shutdown (void *cls) GNUNET_CURL_gnunet_rc_destroy (rc); rc = NULL; } - - } From 77143566119591e86c8919b021d11bfe22fb32c7 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Tue, 7 Jun 2016 17:41:16 +0200 Subject: [PATCH 3/3] first steps in refreshing in benchmark --- src/benchmark/taler-exchange-benchmark.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index d9c0a3f1c..939fc58ec 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -77,6 +77,12 @@ struct Coin { */ const struct TALER_EXCHANGE_DenomPublicKey *pk; + /** + * Array of denomination keys needed in case this coin is to be + * refreshed + */ + const struct TALER_EXCHANGE_DenomPublicKey **refresh_pk; + /** * Set (by the interpreter) to the exchange's signature over the * coin's public key. @@ -187,7 +193,7 @@ static struct TALER_MerchantPrivateKeyP merchant_priv; * Used currency (to be preferably gotten via config file, together * exchange URI and other needed values) */ -#define CURRENCY "KUDOS" +#define CURRENCY "PUDOS" /** @@ -649,6 +655,10 @@ do_shutdown (void *cls) TALER_EXCHANGE_refresh_reveal_cancel(coins[i].rrh); coins[i].rmh = NULL; } + if (NULL != coins[i].refresh_pk) + { + GNUNET_free (coins[i].refresh_pk); + } }