diff options
-rw-r--r-- | src/exchange/taler-exchange-httpd.c | 35 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd.h | 9 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 15 | ||||
-rw-r--r-- | src/exchangedb/perf_get_link_data.c | 23 | ||||
-rw-r--r-- | src/include/taler_exchange_service.h | 91 | ||||
-rw-r--r-- | src/include/taler_json_lib.h | 11 | ||||
-rw-r--r-- | src/include/taler_kyclogic_lib.h | 38 | ||||
-rw-r--r-- | src/json/json_helper.c | 4 | ||||
-rw-r--r-- | src/json/json_pack.c | 41 | ||||
-rw-r--r-- | src/kyclogic/Makefile.am | 2 | ||||
-rw-r--r-- | src/kyclogic/kyclogic_api.c | 72 | ||||
-rw-r--r-- | src/lib/Makefile.am | 2 | ||||
-rw-r--r-- | src/lib/exchange_api_add_aml_decision.c | 5 | ||||
-rw-r--r-- | src/lib/exchange_api_handle.c | 82 | ||||
-rw-r--r-- | src/lib/exchange_api_kyc_check.c | 7 |
15 files changed, 272 insertions, 165 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 7fa8885e7..36c567ebd 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -156,16 +156,6 @@ struct TALER_AttributeEncryptionKeyP TEH_attribute_key; struct TALER_EXCHANGEDB_Plugin *TEH_plugin; /** - * Maximum amount per individual transaction. Invalid amount if unlimited. - */ -struct TALER_Amount TEH_transaction_limit; - -/** - * Maximum amount per refund. Invalid amount if unlimited. - */ -struct TALER_Amount TEH_refund_limit; - -/** * Absolute STEFAN parameter. */ struct TALER_Amount TEH_stefan_abs; @@ -181,6 +171,11 @@ struct TALER_Amount TEH_stefan_log; float TEH_stefan_lin; /** + * JSON array with hard limits for /keys response. + */ +json_t *TEH_hard_limits; + +/** * Where to redirect users from "/"? */ static char *toplevel_redirect_url; @@ -2144,6 +2139,8 @@ exchange_serve_process_config (const char *cfg_fn) GNUNET_break (0); return GNUNET_SYSERR; } + TEH_hard_limits + = TALER_KYCLOGIC_get_hard_limits (); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (TEH_cfg, "exchange", @@ -2217,24 +2214,6 @@ exchange_serve_process_config (const char *cfg_fn) } /* currency parser must provide default spec for main currency */ GNUNET_assert (NULL != TEH_cspec); - if (GNUNET_SYSERR == - TALER_config_get_amount (TEH_cfg, - "exchange", - "TRANSACTION_LIMIT", - &TEH_transaction_limit)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (GNUNET_SYSERR == - TALER_config_get_amount (TEH_cfg, - "exchange", - "REFUND_LIMIT", - &TEH_refund_limit)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (TEH_currency, &TEH_stefan_abs)); diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index 6f86fa39c..d6350c897 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -98,14 +98,9 @@ extern struct TALER_AttributeEncryptionKeyP TEH_attribute_key; extern struct TALER_EXCHANGEDB_Plugin *TEH_plugin; /** - * Maximum amount per individual transaction. Invalid amount if unlimited. + * JSON array with hard limits for /keys response. */ -extern struct TALER_Amount TEH_transaction_limit; - -/** - * Maximum amount per refund. Invalid amount if unlimited. - */ -extern struct TALER_Amount TEH_refund_limit; +extern json_t *TEH_hard_limits; /** * Absolute STEFAN parameter. diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 107e77961..e57e7d4f5 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -2413,18 +2413,9 @@ create_krd (struct TEH_KeyStateHandle *ksh, GNUNET_JSON_pack_object_steal ( "currency_specification", TALER_CONFIG_currency_specs_to_json (TEH_cspec)), - GNUNET_JSON_pack_allow_null ( - TALER_JSON_pack_amount ("transaction_amount_limit", - GNUNET_OK == - TALER_amount_is_valid (&TEH_transaction_limit) - ? &TEH_transaction_limit - : NULL)), - GNUNET_JSON_pack_allow_null ( - TALER_JSON_pack_amount ("refund_amount_limit", - GNUNET_OK == - TALER_amount_is_valid (&TEH_refund_limit) - ? &TEH_refund_limit - : NULL)), + GNUNET_JSON_pack_array_incref ( + "hard_limits", + TEH_hard_limits), TALER_JSON_pack_amount ("stefan_abs", &TEH_stefan_abs), TALER_JSON_pack_amount ("stefan_log", diff --git a/src/exchangedb/perf_get_link_data.c b/src/exchangedb/perf_get_link_data.c index 817789afc..f2c612e16 100644 --- a/src/exchangedb/perf_get_link_data.c +++ b/src/exchangedb/perf_get_link_data.c @@ -28,24 +28,25 @@ * Report line of error if @a cond is true, and jump to label "drop". */ #define FAILIF(cond) \ - do { \ - if (! (cond)) {break;} \ - GNUNET_break (0); \ - goto drop; \ - } while (0) + do { \ + if (! (cond)) {break;} \ + GNUNET_break (0); \ + goto drop; \ + } while (0) /** * Initializes @a ptr with random data. */ #define RND_BLK(ptr) \ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr)) + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (* \ + ptr)) /** * Initializes @a ptr with zeros. */ #define ZR_BLK(ptr) \ - memset (ptr, 0, sizeof (*ptr)) + memset (ptr, 0, sizeof (*ptr)) #define CURRENCY "EUR" #define RSA_KEY_SIZE 1024 @@ -58,7 +59,6 @@ * Database plugin under test. */ static struct TALER_EXCHANGEDB_Plugin *plugin; -static struct TALER_DenomFeeSet fees; /** * Denomination keys used for fresh coins in melt test. */ @@ -215,6 +215,7 @@ run (void *cls) struct TALER_ExchangeWithdrawValues alg_values = { .blinding_inputs = &bi }; + struct TALER_DenomFeeSet fees; ref = GNUNET_new_array (ROUNDS + 1, struct TALER_EXCHANGEDB_Refund); @@ -307,10 +308,10 @@ run (void *cls) struct TALER_EXCHANGEDB_RefreshRevealedCoin *revealed_coin = &revealed_coins[p]; struct TALER_BlindedPlanchet *bp = &revealed_coin->blinded_planchet; - bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); - struct GNUNET_CRYPTO_RsaBlindedMessage *rp = - &bp->blinded_message->details.rsa_blinded_message; + struct GNUNET_CRYPTO_RsaBlindedMessage *rp; + bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + rp = &bp->blinded_message->details.rsa_blinded_message; /* h_coin_ev must be unique, but we only have MELT_NEW_COINS created above for NUM_ROWS iterations; instead of making "all new" coins, we simply randomize the hash here as nobody is checking for consistency diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index b778fcceb..e845f5ed8 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -422,6 +422,39 @@ struct TALER_EXCHANGE_WireAccount /** + * Applicable limits for an account (or wallet). Exceeding these limits may + * trigger additional KYC requirements or be categorically verboten. + */ +struct TALER_EXCHANGE_AccountLimit +{ + + /** + * Operation type for which the restriction applies. + */ + enum TALER_KYCLOGIC_KycTriggerEvent operation_type; + + /** + * Timeframe over which the @e threshold is computed. + */ + struct GNUNET_TIME_Relative timeframe; + + /** + * The maximum amount transacted within the given @e timeframe for the + * specified @e operation_type. + */ + struct TALER_Amount threshold; + + /** + * True if this is a soft limit and passing KYC checks + * or AML reviews may raise this limit. False if this + * is a hard limit that the exchange will not permit + * the client to exceed. + */ + bool soft_limit; +}; + + +/** * @brief Information about keys from the exchange. */ struct TALER_EXCHANGE_Keys @@ -502,6 +535,12 @@ struct TALER_EXCHANGE_Keys struct TALER_EXCHANGE_WireAccount *accounts; /** + * Array of hard limits that apply at this exchange. + * All limits in this array will be hard limits. + */ + struct TALER_EXCHANGE_AccountLimit *hard_limits; + + /** * Array of wire fees by wire method. */ struct TALER_EXCHANGE_WireFeesByMethod *fees; @@ -551,20 +590,6 @@ struct TALER_EXCHANGE_Keys struct TALER_Amount stefan_log; /** - * Maximum amount for an individual transaction. - * Set to an invalid amount (see #TALER_amount_is_valid()) - * if there is no limit. - */ - struct TALER_Amount transaction_limit; - - /** - * Maximum amount that can be refunded per individual transaction. - * Set to an invalid amount (see #TALER_amount_is_valid()) - * if there is no limit. - */ - struct TALER_Amount refund_limit; - - /** * Linear STEFAN parameter. */ double stefan_lin; @@ -580,6 +605,11 @@ struct TALER_EXCHANGE_Keys unsigned int fees_len; /** + * Length of @e hard_limits array. + */ + unsigned int hard_limits_length; + + /** * Length of the @e wallet_balance_limit_without_kyc * array. */ @@ -4265,39 +4295,6 @@ struct TALER_EXCHANGE_KycCheckHandle; /** - * Applicable limits for an account. Exceeding these limits may trigger - * additional KYC requirements or be categorically verboten. - */ -struct TALER_EXCHANGE_AccountLimit -{ - - /** - * Operation type for which the restriction applies. - */ - enum TALER_KYCLOGIC_KycTriggerEvent operation_type; - - /** - * Timeframe over which the @e threshold is computed. - */ - struct GNUNET_TIME_Relative timeframe; - - /** - * The maximum amount transacted within the given @e timeframe for the - * specified @e operation_type. - */ - struct TALER_Amount threshold; - - /** - * True if this is a soft limit and passing KYC checks - * or AML reviews may raise this limit. False if this - * is a hard limit that the exchange will not permit - * the client to exceed. - */ - bool soft_limit; -}; - - -/** * KYC/AML status information about an account. */ struct TALER_EXCHANGE_AccountKycStatus diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index 806b39dc1..5e78ab44d 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -209,6 +209,17 @@ TALER_JSON_pack_age_commitment ( /** + * Generate packer instruction of a KYC Trigger Event. + * + * @param name name of the field to add to the object + * @param event event type to add + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +TALER_JSON_pack_kycte (const char *name, + enum TALER_KYCLOGIC_KycTriggerEvent event); + +/** * Convert a TALER amount to a JSON object. * * @param amount the amount diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h index 39256bb1e..17ca2fe04 100644 --- a/src/include/taler_kyclogic_lib.h +++ b/src/include/taler_kyclogic_lib.h @@ -54,7 +54,8 @@ enum TALER_KYCLOGIC_KycTriggerEvent TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE = 3, /** - * Wallet balance exceeds threshold. + * Wallet balance exceeds threshold. The timeframe is + * irrelevant for this limit. */ TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE = 4, @@ -67,7 +68,19 @@ enum TALER_KYCLOGIC_KycTriggerEvent * Deposits have been aggregated, we are wiring a * certain amount into a (merchant) bank account. */ - TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6 + TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6, + + /** + * Limit per transaction. The timeframe is + * irrelevant for this limit. + */ + TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION = 7, + + /** + * Limit per refund. The timeframe is + * irrelevant for this limit. + */ + TALER_KYCLOGIC_KYC_TRIGGER_REFUND = 8 }; @@ -225,16 +238,6 @@ TALER_KYCLOGIC_kyc_trigger_from_string ( /** - * Convert KYC trigger value to human-readable string. - * - * @param trigger value to convert - * @return human-readable representation of the @a trigger - */ -const char * -TALER_KYCLOGIC_kyc_trigger2s (enum TALER_KYCLOGIC_KycTriggerEvent trigger); - - -/** * Initialize KYC subsystem. Loads the KYC configuration. * * @param cfg configuration to parse @@ -356,6 +359,17 @@ TALER_KYCLOGIC_kyc_test_required ( /** + * Return JSON array of AccountLimit objects with hard limits of this exchange + * suitable for the "hard_limits" field of the "/keys" response. + * + * @return the JSON array of AccountLimit objects, + * empty array if there are no hard limits + */ +json_t * +TALER_KYCLOGIC_get_hard_limits (void); + + +/** * Get human-readable name of KYC rule. * * @param r rule to convert diff --git a/src/json/json_helper.c b/src/json/json_helper.c index db0a425db..2d1037ef6 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -1475,6 +1475,10 @@ parse_kycte (void *cls, .val = TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE }, { .name = "AGGREGATE", .val = TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE }, + { .name = "TRANSACTION", + .val = TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION }, + { .name = "REFUND", + .val = TALER_KYCLOGIC_KYC_TRIGGER_REFUND }, { .name = NULL, .val = TALER_KYCLOGIC_KYC_TRIGGER_NONE }, }; diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 85c9c5686..859976acb 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -97,6 +97,47 @@ TALER_JSON_pack_age_commitment ( struct GNUNET_JSON_PackSpec +TALER_JSON_pack_kycte (const char *name, + enum TALER_KYCLOGIC_KycTriggerEvent event) +{ + const char *str = "INVALID"; + + switch (event) + { + case TALER_KYCLOGIC_KYC_TRIGGER_NONE: + str = "NONE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW: + str = "WITHDRAW"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT: + str = "DEPOSIT"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE: + str = "MERGE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE: + str = "BALANCE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE: + str = "CLOSE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE: + str = "AGGREGATE"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION: + str = "TRANSACTION"; + break; + case TALER_KYCLOGIC_KYC_TRIGGER_REFUND: + str = "REFUND"; + break; + } + return GNUNET_JSON_pack_string (name, + str); +} + + +struct GNUNET_JSON_PackSpec TALER_JSON_pack_denom_pub ( const char *name, const struct TALER_DenominationPublicKey *pk) diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am index 7da1f758f..35e68e1a2 100644 --- a/src/kyclogic/Makefile.am +++ b/src/kyclogic/Makefile.am @@ -41,7 +41,7 @@ libtalerkyclogic_la_LIBADD = \ -lgnunetutil \ $(XLIB) libtalerkyclogic_la_LDFLAGS = \ - -version-info 0:0:0 \ + -version-info 1:0:0 \ -no-undefined diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c index 9e37f16f9..7ea6b2b82 100644 --- a/src/kyclogic/kyclogic_api.c +++ b/src/kyclogic/kyclogic_api.c @@ -833,15 +833,16 @@ TALER_KYCLOGIC_rules_to_limits (const json_t *jrules) } limit = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ( + TALER_JSON_pack_kycte ( "operation_type", - TALER_KYCLOGIC_kyc_trigger2s (operation_type)), + operation_type), GNUNET_JSON_pack_time_rel ( "timeframe", timeframe), TALER_JSON_pack_amount ( "threshold", &threshold), + /* optional since v21, defaults to 'false' */ GNUNET_JSON_pack_bool ( "soft_limit", ! forbidden)); @@ -1215,6 +1216,8 @@ TALER_KYCLOGIC_kyc_trigger_from_string ( const char *trigger_s, enum TALER_KYCLOGIC_KycTriggerEvent *trigger) { + /* NOTE: if you change this, also change + the code in src/json/json_helper.c! */ struct { const char *in; @@ -1226,6 +1229,8 @@ TALER_KYCLOGIC_kyc_trigger_from_string ( { "BALANCE", TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE }, { "CLOSE", TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE }, { "AGGREGATE", TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE }, + { "TRANSACTION", TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION }, + { "REFUND", TALER_KYCLOGIC_KYC_TRIGGER_REFUND }, { NULL, 0 } }; @@ -1243,33 +1248,6 @@ TALER_KYCLOGIC_kyc_trigger_from_string ( } -const char * -TALER_KYCLOGIC_kyc_trigger2s ( - enum TALER_KYCLOGIC_KycTriggerEvent trigger) -{ - switch (trigger) - { - case TALER_KYCLOGIC_KYC_TRIGGER_NONE: - GNUNET_break (0); - return NULL; - case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW: - return "WITHDRAW"; - case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT: - return "DEPOSIT"; - case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE: - return "MERGE"; - case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE: - return "BALANCE"; - case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE: - return "CLOSE"; - case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE: - return "AGGREGATE"; - } - GNUNET_break (0); - return NULL; -} - - json_t * TALER_KYCLOGIC_get_wallet_thresholds (void) { @@ -3565,4 +3543,40 @@ TALER_KYCLOGIC_run_aml_program_cancel ( } +json_t * +TALER_KYCLOGIC_get_hard_limits () +{ + const struct TALER_KYCLOGIC_KycRule *rules + = default_rules.kyc_rules; + unsigned int num_rules + = default_rules.num_kyc_rules; + json_t *hard_limits; + + hard_limits = json_array (); + GNUNET_assert (NULL != hard_limits); + for (unsigned int i = 0; i<num_rules; i++) + { + const struct TALER_KYCLOGIC_KycRule *rule = &rules[i]; + json_t *hard_limit; + + if (! rule->verboten) + continue; + if (! rule->exposed) + continue; + hard_limit = GNUNET_JSON_PACK ( + TALER_JSON_pack_kycte ("operation_type", + rule->trigger), + GNUNET_JSON_pack_time_rel ("timeframe", + rule->timeframe), + TALER_JSON_pack_amount ("threshold", + &rule->threshold) + ); + GNUNET_assert (0 == + json_array_append_new (hard_limits, + hard_limit)); + } + return hard_limits; +} + + /* end of kyclogic_api.c */ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 8924ee604..df2c32109 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -18,7 +18,7 @@ lib_LTLIBRARIES = \ libtalerexchange.la libtalerexchange_la_LDFLAGS = \ - -version-info 9:0:0 \ + -version-info 10:0:0 \ -no-undefined libtalerexchange_la_SOURCES = \ exchange_api_add_aml_decision.c \ diff --git a/src/lib/exchange_api_add_aml_decision.c b/src/lib/exchange_api_add_aml_decision.c index 53cd04eb5..a9a41a0aa 100644 --- a/src/lib/exchange_api_add_aml_decision.c +++ b/src/lib/exchange_api_add_aml_decision.c @@ -167,9 +167,8 @@ TALER_EXCHANGE_add_aml_decision ( json_array_append_new (ameasures, json_string (al->measures[j]))); rule = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("operation_type", - TALER_KYCLOGIC_kyc_trigger2s (al->operation_type) - ), + TALER_JSON_pack_kycte ("operation_type", + al->operation_type), TALER_JSON_pack_amount ("threshold", &al->threshold), GNUNET_JSON_pack_time_rel ("timeframe", diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index f614ff3c2..5890fa75e 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -758,6 +758,61 @@ denoms_cmp (const struct TALER_EXCHANGE_DenomPublicKey *denom1, /** + * Decode the JSON array in @a hard_limits from the /keys response + * and store the data in `hard_limits` array the @a key_data. + * + * @param[in] hard_limits JSON array to parse + * @param[out] key_data where to store the results we decoded + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + * (malformed JSON) + */ +static enum GNUNET_GenericReturnValue +parse_hard_limits (const json_t *hard_limits, + struct TALER_EXCHANGE_Keys *key_data) +{ + json_t *obj; + size_t off; + + key_data->hard_limits_length + = (unsigned int) json_array_size (hard_limits); + if ( ((size_t) key_data->hard_limits_length) + != json_array_size (hard_limits)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + key_data->hard_limits + = GNUNET_new_array (key_data->hard_limits_length, + struct TALER_EXCHANGE_AccountLimit); + + json_array_foreach (hard_limits, off, obj) + { + struct TALER_EXCHANGE_AccountLimit *al + = &key_data->hard_limits[off]; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_kycte ("operation_type", + &al->operation_type), + TALER_JSON_spec_amount_any ("threshold", + &al->threshold), + GNUNET_JSON_spec_relative_time ("timeframe", + &al->timeframe), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (obj, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +/** * Decode the JSON in @a resp_obj from the /keys response * and store the data in the @a key_data. * @@ -920,6 +975,7 @@ decode_keys_json (const json_t *resp_obj, EXITIF (1); } { + const json_t *hard_limits; struct GNUNET_JSON_Specification sspec[] = { TALER_JSON_spec_currency_specification ( "currency_specification", @@ -933,18 +989,9 @@ decode_keys_json (const json_t *resp_obj, "stefan_log", currency, &key_data->stefan_log), - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_amount ( - "transaction_amount_limit", - currency, - &key_data->transaction_limit), - NULL), - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_amount ( - "refund_amount_limit", - currency, - &key_data->refund_limit), - NULL), + GNUNET_JSON_spec_array_const ( + "hard_limits", + &hard_limits), GNUNET_JSON_spec_double ( "stefan_lin", &key_data->stefan_lin), @@ -963,6 +1010,14 @@ decode_keys_json (const json_t *resp_obj, eline); EXITIF (1); } + if (GNUNET_OK != + parse_hard_limits (hard_limits, + key_data)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Parsing hard limits of /keys failed\n"); + EXITIF (1); + } } key_data->currency = GNUNET_strdup (currency); @@ -1903,6 +1958,9 @@ TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys) 0); free_fees (keys->fees, keys->fees_len); + GNUNET_array_grow (keys->hard_limits, + keys->hard_limits_length, + 0); json_decref (keys->extensions); GNUNET_free (keys->cspec.name); json_decref (keys->cspec.map_alt_unit_names); diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c index 75f238cca..39a3d9dac 100644 --- a/src/lib/exchange_api_kyc_check.c +++ b/src/lib/exchange_api_kyc_check.c @@ -99,8 +99,10 @@ parse_account_status ( { struct TALER_EXCHANGE_AccountLimit *al = &ala[i]; struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_bool ("soft_limit", - &al->soft_limit), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_bool ("soft_limit", + &al->soft_limit), + NULL), GNUNET_JSON_spec_relative_time ("timeframe", &al->timeframe), TALER_JSON_spec_kycte ("operation_type", @@ -110,6 +112,7 @@ parse_account_status ( GNUNET_JSON_spec_end () }; + al->soft_limit = false; if (GNUNET_OK != GNUNET_JSON_parse (limit, ispec, |