diff options
-rw-r--r-- | src/exchange/taler-exchange-httpd.c | 56 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd.h | 5 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_config.c | 3 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 5 | ||||
-rw-r--r-- | src/include/taler_exchange_service.h | 11 | ||||
-rw-r--r-- | src/include/taler_json_lib.h | 62 | ||||
-rw-r--r-- | src/include/taler_util.h | 4 | ||||
-rw-r--r-- | src/json/json_helper.c | 129 | ||||
-rw-r--r-- | src/json/json_pack.c | 24 | ||||
-rw-r--r-- | src/lib/exchange_api_handle.c | 11 | ||||
-rw-r--r-- | src/util/amount.c | 1 | ||||
-rw-r--r-- | src/util/config.c | 2 | ||||
-rw-r--r-- | src/util/currencies.conf | 54 |
13 files changed, 177 insertions, 190 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index a9d10cc3f..bcf5b67da 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -253,6 +253,22 @@ static unsigned long long active_connections; static unsigned long long req_max; /** + * Length of the cspecs array. + */ +static unsigned int num_cspecs; + +/** + * Rendering specs for currencies. + */ +static struct TALER_CurrencySpecification *cspecs; + +/** + * Rendering spec for our currency. + */ +const struct TALER_CurrencySpecification *TEH_cspec; + + +/** * Context for all CURL operations (useful to the event loop) */ struct GNUNET_CURL_Context *TEH_curl_ctx; @@ -2039,24 +2055,31 @@ exchange_serve_process_config (void) "CURRENCY"); return GNUNET_SYSERR; } + + if (GNUNET_OK != + TALER_CONFIG_parse_currencies (TEH_cfg, + &num_cspecs, + &cspecs)) + return GNUNET_SYSERR; + for (unsigned int i = 0; i<num_cspecs; i++) { - unsigned long long cfd; + struct TALER_CurrencySpecification *cspec; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (TEH_cfg, - "exchange", - "CURRENCY_FRACTION_DIGITS", - &cfd)) - cfd = 0; - if (cfd > 8) + cspec = &cspecs[i]; + if (0 == strcmp (TEH_currency, + cspec->currency)) { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "taler", - "CURRENCY_FRACTION_DIGITS", - "Value must be below 8"); - return GNUNET_SYSERR; + TEH_cspec = cspec; + break; } - TEH_currency_fraction_digits = (unsigned int) cfd; + } + if (NULL == TEH_cspec) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + "taler", + "CURRENCY", + "Lacking enabled currency specification for the given currency"); + return GNUNET_SYSERR; } if (GNUNET_OK != TALER_config_get_amount (TEH_cfg, @@ -2466,6 +2489,11 @@ do_shutdown (void *cls) exchange_curl_rc = NULL; } TALER_TEMPLATING_done (); + TEH_cspec = NULL; + TALER_CONFIG_free_currencies (num_cspecs, + cspecs); + num_cspecs = 0; + cspecs = NULL; } diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index 9e18f9e69..1ab77291d 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -113,10 +113,9 @@ extern struct TALER_Amount TEH_stefan_log; extern struct TALER_Amount TEH_stefan_lin; /** - * Default number of fractional digits to render - * amounts with. + * Default ways how to render #TEH_currency amounts. */ -extern unsigned int TEH_currency_fraction_digits; +extern const struct TALER_CurrencySpecification *TEH_cspec; /** * Our currency. diff --git a/src/exchange/taler-exchange-httpd_config.c b/src/exchange/taler-exchange-httpd_config.c index da5bf9691..fde1823fc 100644 --- a/src/exchange/taler-exchange-httpd_config.c +++ b/src/exchange/taler-exchange-httpd_config.c @@ -39,6 +39,9 @@ TEH_handler_config (struct TEH_RequestContext *rc, resp = TALER_MHD_MAKE_JSON_PACK ( GNUNET_JSON_pack_array_steal ("supported_kyc_requirements", TALER_KYCLOGIC_get_satisfiable ()), + GNUNET_JSON_pack_object_steal ( + "currency_specification", + TALER_CONFIG_currency_specs_to_json (TEH_cspec)), GNUNET_JSON_pack_string ("currency", TEH_currency), GNUNET_JSON_pack_string ("name", diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 12d50a811..6bdc404d0 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -2490,8 +2490,9 @@ create_krd (struct TEH_KeyStateHandle *ksh, TEH_base_url), GNUNET_JSON_pack_string ("currency", TEH_currency), - GNUNET_JSON_pack_uint64 ("currency_fraction_digits", - TEH_currency_fraction_digits), + GNUNET_JSON_pack_object_steal ( + "currency_specification", + TALER_CONFIG_currency_specs_to_json (TEH_cspec)), TALER_JSON_pack_amount ("stefan_abs", &TEH_stefan_abs), TALER_JSON_pack_amount ("stefan_log", diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index b14d68d6d..bf584036a 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -488,6 +488,11 @@ struct TALER_EXCHANGE_Keys struct TALER_EXCHANGE_WireFeesByMethod *fees; /** + * Currency rendering specification for this exchange. + */ + struct TALER_CurrencySpecification cspec; + + /** * How long after a reserve went idle will the exchange close it? * This is an approximate number, not cryptographically signed by * the exchange (advisory-only, may change anytime). @@ -532,12 +537,6 @@ struct TALER_EXCHANGE_Keys struct TALER_Amount stefan_lin; /** - * Default number of fractional digits to render - * amounts with. - */ - uint32_t currency_fraction_digits; - - /** * Length of @e accounts array. */ unsigned int accounts_len; diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index a6febbbfd..a8da05e4c 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -92,18 +92,6 @@ TALER_JSON_pack_time_abs_human (const char *name, GNUNET_JSON_pack_string ("hint", TALER_ErrorCode_get_hint (ec)), \ GNUNET_JSON_pack_uint64 ("code", ec) -/** - * Generate packer instruction for a JSON field of type - * absolute time creating a human-readable timestamp. - * - * @param name name of the field to add to the object - * @param at absolute time to pack - * @return json pack specification - */ -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_time_abs_nbo_human (const char *name, - struct GNUNET_TIME_AbsoluteNBO at); - /** * Generate packer instruction for a JSON field of type @@ -191,19 +179,6 @@ TALER_JSON_pack_amount (const char *name, /** * Generate packer instruction for a JSON field of type - * amount. - * - * @param name name of the field to add to the object - * @param amount valid amount to pack - * @return json pack specification - */ -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_amount_nbo (const char *name, - const struct TALER_AmountNBO *amount); - - -/** - * Generate packer instruction for a JSON field of type * encrypted contract. * * @param name name of the field to add to the object @@ -239,16 +214,6 @@ TALER_JSON_from_amount (const struct TALER_Amount *amount); /** - * Convert a TALER amount to a JSON object. - * - * @param amount the amount - * @return a json object describing the amount - */ -json_t * -TALER_JSON_from_amount_nbo (const struct TALER_AmountNBO *amount); - - -/** * Provide specification to parse given JSON object to an amount. * The @a currency must be a valid pointer while the * parsing is done, a copy is not made. @@ -265,20 +230,17 @@ TALER_JSON_spec_amount (const char *name, /** - * Provide specification to parse given JSON object to an amount - * in network byte order. - * The @a currency must be a valid pointer while the - * parsing is done, a copy is not made. + * Provide specification to parse given JSON object to + * a currency specification. * * @param name name of the amount field in the JSON - * @param currency the currency the amount must be in - * @param[out] r_amount where the amount has to be written + * @param[out] r_cspec where the currency spec has to be written * @return spec for parsing an amount */ struct GNUNET_JSON_Specification -TALER_JSON_spec_amount_nbo (const char *name, - const char *currency, - struct TALER_AmountNBO *r_amount); +TALER_JSON_spec_currency_specification ( + const char *name, + struct TALER_CurrencySpecification *r_cspec); /** @@ -317,18 +279,6 @@ struct GNUNET_JSON_Specification TALER_JSON_spec_age_commitment (const char *name, struct TALER_AgeCommitment *age_commitment); -/** - * Provide specification to parse given JSON object to an amount - * in any currency in network byte order. - * - * @param name name of the amount field in the JSON - * @param[out] r_amount where the amount has to be written - * @return spec for parsing an amount - */ -struct GNUNET_JSON_Specification -TALER_JSON_spec_amount_any_nbo (const char *name, - struct TALER_AmountNBO *r_amount); - /** * Generate specification to parse all fees for diff --git a/src/include/taler_util.h b/src/include/taler_util.h index 4c3a1c9f2..4dcf6f8f8 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -300,8 +300,8 @@ TALER_CONFIG_free_currencies ( * @return JSON object encoding @a cspec for `/config`. */ json_t * -TALER_CONFIG_currency_specs_to_json (const struct - TALER_CurrencySpecification *cspec); +TALER_CONFIG_currency_specs_to_json ( + const struct TALER_CurrencySpecification *cspec); /** diff --git a/src/json/json_helper.c b/src/json/json_helper.c index ab1ce7876..99d8e5b50 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -64,17 +64,6 @@ TALER_JSON_from_amount (const struct TALER_Amount *amount) } -json_t * -TALER_JSON_from_amount_nbo (const struct TALER_AmountNBO *amount) -{ - struct TALER_Amount a; - - TALER_amount_ntoh (&a, - amount); - return TALER_JSON_from_amount (&a); -} - - /** * Parse given JSON object to Amount * @@ -160,7 +149,7 @@ TALER_JSON_spec_amount_any (const char *name, /** - * Parse given JSON object to Amount in NBO. + * Parse given JSON object to currency spec. * * @param cls closure, NULL * @param root the json object representing data @@ -168,73 +157,111 @@ TALER_JSON_spec_amount_any (const char *name, * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error */ static enum GNUNET_GenericReturnValue -parse_amount_nbo (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) +parse_cspec (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) { - const char *currency = cls; - struct TALER_AmountNBO *r_amount = spec->ptr; - const char *sv; + struct TALER_CurrencySpecification *r_cspec = spec->ptr; + const char *name; + const char *currency; + const char *decimal_separator; + uint32_t fid; + uint32_t fnd; + uint32_t ftzd; + const json_t *map; + struct GNUNET_JSON_Specification gspec[] = { + GNUNET_JSON_spec_string ("currency", + ¤cy), + GNUNET_JSON_spec_string ("name", + &name), + GNUNET_JSON_spec_string ("decimal_separator", + &decimal_separator), + GNUNET_JSON_spec_uint32 ("num_fractional_input_digits", + &fid), + GNUNET_JSON_spec_uint32 ("num_fractional_normal_digits", + &fnd), + GNUNET_JSON_spec_uint32 ("num_fractional_trailing_zero_digits", + &ftzd), + GNUNET_JSON_spec_bool ("is_currency_name_leading", + &r_cspec->is_currency_name_leading), + GNUNET_JSON_spec_object_const ("alt_unit_names", + &map), + GNUNET_JSON_spec_end () + }; + const char *emsg; + unsigned int eline; (void) cls; - if (! json_is_string (root)) + if (GNUNET_OK != + GNUNET_JSON_parse (root, + gspec, + &emsg, + &eline)) { - GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to parse %s at %u: %s\n", + spec[eline].field, + eline, + emsg); + GNUNET_break_op (0); return GNUNET_SYSERR; } - sv = json_string_value (root); - if (GNUNET_OK != - TALER_string_to_amount_nbo (sv, - r_amount)) + if (strlen (currency) >= TALER_CURRENCY_LEN) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "`%s' is not a valid amount\n", - sv); GNUNET_break_op (0); return GNUNET_SYSERR; } - if ( (NULL != currency) && - (0 != - strcasecmp (currency, - r_amount->currency)) ) + if ( (fid > TALER_AMOUNT_FRAC_LEN) || + (fnd > TALER_AMOUNT_FRAC_LEN) || + (ftzd > TALER_AMOUNT_FRAC_LEN) ) { GNUNET_break_op (0); return GNUNET_SYSERR; } + memset (r_cspec->currency, + 0, + sizeof (r_cspec->currency)); + /* FIXME: check currency consists only of legal characters! */ + strcpy (r_cspec->currency, + currency); + /* FIXME: check map is valid! */ + r_cspec->name = GNUNET_strdup (name); + r_cspec->decimal_separator = GNUNET_strdup (decimal_separator); + r_cspec->map_alt_unit_names = json_incref ((json_t *) map); return GNUNET_OK; } -struct GNUNET_JSON_Specification -TALER_JSON_spec_amount_nbo (const char *name, - const char *currency, - struct TALER_AmountNBO *r_amount) +/** + * Cleanup data left from parsing encrypted contract. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_cspec (void *cls, + struct GNUNET_JSON_Specification *spec) { - struct GNUNET_JSON_Specification ret = { - .parser = &parse_amount_nbo, - .cleaner = NULL, - .cls = (void *) currency, - .field = name, - .ptr = r_amount, - .ptr_size = 0, - .size_ptr = NULL - }; + struct TALER_CurrencySpecification *cspec = spec->ptr; - GNUNET_assert (NULL != currency); - return ret; + (void) cls; + GNUNET_free (cspec->name); + GNUNET_free (cspec->decimal_separator); + json_decref (cspec->map_alt_unit_names); } struct GNUNET_JSON_Specification -TALER_JSON_spec_amount_any_nbo (const char *name, - struct TALER_AmountNBO *r_amount) +TALER_JSON_spec_currency_specification ( + const char *name, + struct TALER_CurrencySpecification *r_cspec) { struct GNUNET_JSON_Specification ret = { - .parser = &parse_amount_nbo, - .cleaner = NULL, + .parser = &parse_cspec, + .cleaner = &clean_cspec, .cls = NULL, .field = name, - .ptr = r_amount, + .ptr = r_cspec, .ptr_size = 0, .size_ptr = NULL }; diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 834e8104b..c6844c17b 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -39,15 +39,6 @@ TALER_JSON_pack_time_abs_human (const char *name, struct GNUNET_JSON_PackSpec -TALER_JSON_pack_time_abs_nbo_human (const char *name, - struct GNUNET_TIME_AbsoluteNBO at) -{ - return TALER_JSON_pack_time_abs_human (name, - GNUNET_TIME_absolute_ntoh (at)); -} - - -struct GNUNET_JSON_PackSpec TALER_JSON_pack_econtract ( const char *name, const struct TALER_EncryptedContract *econtract) @@ -314,19 +305,4 @@ TALER_JSON_pack_amount (const char *name, } -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_amount_nbo (const char *name, - const struct TALER_AmountNBO *amount) -{ - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - .object = (NULL != amount) - ? TALER_JSON_from_amount_nbo (amount) - : NULL - }; - - return ps; -} - - /* End of json/json_pack.c */ diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 6009b7c10..811120a85 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -864,9 +864,9 @@ decode_keys_json (const json_t *resp_obj, GNUNET_JSON_spec_string ( "currency", ¤cy), - GNUNET_JSON_spec_uint32 ( - "currency_fraction_digits", - &key_data->currency_fraction_digits), + TALER_JSON_spec_currency_specification ( + "currency_specification", + &key_data->cspec), GNUNET_JSON_spec_string ( "asset_type", &asset_type), @@ -2381,8 +2381,9 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd) kd->version), GNUNET_JSON_pack_string ("currency", kd->currency), - GNUNET_JSON_pack_uint64 ("currency_fraction_digits", - kd->currency_fraction_digits), + GNUNET_JSON_pack_object_steal ("currency_specification", + TALER_CONFIG_currency_specs_to_json ( + &kd->cspec)), TALER_JSON_pack_amount ("stefan_abs", &kd->stefan_abs), TALER_JSON_pack_amount ("stefan_log", diff --git a/src/util/amount.c b/src/util/amount.c index 9cd0739c9..97a1cf46a 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -225,6 +225,7 @@ TALER_amount_set_zero (const char *cur, sizeof (struct TALER_Amount)); for (unsigned int i = 0; i<slen; i++) amount->currency[i] = toupper (cur[i]); + /* FIXME: check currency consists only of legal characters! */ return GNUNET_OK; } diff --git a/src/util/config.c b/src/util/config.c index 9e1156240..cd30221ac 100644 --- a/src/util/config.c +++ b/src/util/config.c @@ -260,6 +260,7 @@ parse_currencies_cb (void *cls, GNUNET_free (str); return; } + /* FIXME: validate str has only legal characters in it! */ strcpy (cspec->currency, str); GNUNET_free (str); @@ -388,6 +389,7 @@ parse_currencies_cb (void *cls, return; } } + /* FIXME: validate map only maps from decimal numbers to strings! */ } diff --git a/src/util/currencies.conf b/src/util/currencies.conf index 4e923943c..3341a9a72 100644 --- a/src/util/currencies.conf +++ b/src/util/currencies.conf @@ -3,9 +3,9 @@ ENABLED = YES name = "Euro" code = "EUR" decimal_separator = "," -num_fractional_input_digits = 2 -num_fractional_normal_digits = 2 -num_fractional_trailing_zero_digits = 2 +fractional_input_digits = 2 +fractional_normal_digits = 2 +fractional_trailing_zero_digits = 2 is_currency_name_leading = NO alt_unit_names = {"0":"€"} @@ -14,9 +14,9 @@ ENABLED = YES name = "Swiss Francs" code = "CHF" decimal_separator = "." -num_fractional_input_digits = 2 -num_fractional_normal_digits = 2 -num_fractional_trailing_zero_digits = 2 +fractional_input_digits = 2 +fractional_normal_digits = 2 +fractional_trailing_zero_digits = 2 is_currency_name_leading = YES alt_unit_names = {"0":"Fr.","-2":"Rp."} @@ -25,9 +25,9 @@ ENABLED = NO name = "Hungarian Forint" code = "HUF" decimal_separator = "," -num_fractional_input_digits = 0 -num_fractional_normal_digits = 0 -num_fractional_trailing_zero_digits = 0 +fractional_input_digits = 0 +fractional_normal_digits = 0 +fractional_trailing_zero_digits = 0 is_currency_name_leading = NO alt_unit_names = {"0":"Ft"} @@ -36,9 +36,9 @@ ENABLED = NO name = "US Dollar" code = "USD" decimal_separator = "." -num_fractional_input_digits = 2 -num_fractional_normal_digits = 2 -num_fractional_trailing_zero_digits = 2 +fractional_input_digits = 2 +fractional_normal_digits = 2 +fractional_trailing_zero_digits = 2 is_currency_name_leading = YES alt_unit_names = {"0":"$"} @@ -47,9 +47,9 @@ ENABLED = YES name = "Kudos (Taler Demonstrator)" code = "KUDOS" decimal_separator = "," -num_fractional_input_digits = 2 -num_fractional_normal_digits = 2 -num_fractional_trailing_zero_digits = 2 +fractional_input_digits = 2 +fractional_normal_digits = 2 +fractional_trailing_zero_digits = 2 is_currency_name_leading = NO alt_unit_names = {"0":"ク"} @@ -58,9 +58,9 @@ ENABLED = YES name = "Test-kudos (Taler Demonstrator)" code = "TESTKUDOS" decimal_separator = "." -num_fractional_input_digits = 2 -num_fractional_normal_digits = 2 -num_fractional_trailing_zero_digits = 2 +fractional_input_digits = 2 +fractional_normal_digits = 2 +fractional_trailing_zero_digits = 2 is_currency_name_leading = NO alt_unit_names = {"0":"テ","3":"kテ","-3":"mテ"} @@ -69,9 +69,9 @@ ENABLED = NO name = "Japanese Yen" code = "JPY" decimal_separator = "." -num_fractional_input_digits = 2 -num_fractional_normal_digits = 0 -num_fractional_trailing_zero_digits = 2 +fractional_input_digits = 2 +fractional_normal_digits = 0 +fractional_trailing_zero_digits = 2 is_currency_name_leading = YES alt_unit_names = {"0":"¥"} @@ -80,9 +80,9 @@ ENABLED = NO name = "Bitcoin (Mainnet)" code = "BITCOINBTC" decimal_separator = "." -num_fractional_input_digits = 8 -num_fractional_normal_digits = 3 -num_fractional_trailing_zero_digits = 0 +fractional_input_digits = 8 +fractional_normal_digits = 3 +fractional_trailing_zero_digits = 0 is_currency_name_leading = NO alt_unit_names = {"0":"BTC","-3":"mBTC"} @@ -91,9 +91,9 @@ ENABLED = NO name = "WAI-ETHER (Ethereum)" code = "EthereumWAI" decimal_separator = "." -num_fractional_input_digits = 0 -num_fractional_normal_digits = 0 -num_fractional_trailing_zero_digits = 0 +fractional_input_digits = 0 +fractional_normal_digits = 0 +fractional_trailing_zero_digits = 0 is_currency_name_leading = NO alt_unit_names = {"0":"WAI","3":"KWAI","6":"MWAI","9":"GWAI","12":"Szabo","15":"Finney","18":"Ether","21":"KEther","24":"MEther"} |