From 3b091cd5dee9338850d5d1052f55d019624221c2 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 29 Jun 2022 08:31:00 +0200 Subject: [PATCH] -fix /keys initialization DB logic --- src/exchange/taler-exchange-httpd_keys.c | 29 +++++-------------- src/exchange/taler-exchange-httpd_keys.h | 16 +++++++++- ...aler-exchange-httpd_management_post_keys.c | 20 ++++++++++++- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 04e9141a6..08c83ddab 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -2604,16 +2604,8 @@ TEH_keys_update_states () } -/** - * Obtain the key state. Should ONLY be used - * directly if @a management_only is true. Otherwise use #TEH_keys_get_state(). - * - * @param management_only if we should NOT run 'finish_keys_response()' - * because we only need the state for the /management/keys API - * @return NULL on error - */ -static struct TEH_KeyStateHandle * -get_key_state (bool management_only) +struct TEH_KeyStateHandle * +TEH_keys_get_state2 (bool management_only) { struct TEH_KeyStateHandle *old_ksh; struct TEH_KeyStateHandle *ksh; @@ -2653,7 +2645,7 @@ TEH_keys_get_state (void) { struct TEH_KeyStateHandle *ksh; - ksh = get_key_state (false); + ksh = TEH_keys_get_state2 (false); if (NULL == ksh) return NULL; if (ksh->management_only) @@ -3247,21 +3239,14 @@ load_extension_data (const char *section_name, enum GNUNET_GenericReturnValue -TEH_keys_load_fees (const struct TALER_DenominationHashP *h_denom_pub, +TEH_keys_load_fees (struct TEH_KeyStateHandle *ksh, + const struct TALER_DenominationHashP *h_denom_pub, struct TALER_DenominationPublicKey *denom_pub, struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta) { - struct TEH_KeyStateHandle *ksh; struct HelperDenomination *hd; enum GNUNET_GenericReturnValue ok; - ksh = get_key_state (true); - if (NULL == ksh) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->denom_keys, &h_denom_pub->hash); if (NULL == hd) @@ -3304,7 +3289,7 @@ TEH_keys_get_timing (const struct TALER_ExchangePublicKeyP *exchange_pub, struct HelperSignkey *hsk; struct GNUNET_PeerIdentity pid; - ksh = get_key_state (true); + ksh = TEH_keys_get_state2 (true); if (NULL == ksh) { GNUNET_break (0); @@ -3474,7 +3459,7 @@ TEH_keys_management_get_keys_handler (const struct TEH_RequestHandler *rh, json_t *reply; (void) rh; - ksh = get_key_state (true); + ksh = TEH_keys_get_state2 (true); if (NULL == ksh) { return TALER_MHD_reply_with_error (connection, diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index 1edf9c46d..6d0cb5b5a 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -174,6 +174,18 @@ struct TEH_KeyStateHandle * TEH_keys_get_state (void); +/** + * Obtain the key state. Should ONLY be used + * directly if @a management_only is true. Otherwise use #TEH_keys_get_state(). + * + * @param management_only if we should NOT run finish_keys_response() + * because we only need the state for the /management/keys API + * @return NULL on error + */ +struct TEH_KeyStateHandle * +TEH_keys_get_state2 (bool management_only); + + /** * Something changed in the database. Rebuild all key states. This function * should be called if the exchange learns about a new signature from an @@ -485,6 +497,7 @@ TEH_keys_management_get_keys_handler (const struct TEH_RequestHandler *rh, * Load fees and expiration times (!) for the denomination type configured for * the denomination matching @a h_denom_pub. * + * @param ksh key state to load fees from * @param h_denom_pub hash of the denomination public key * to use to derive the section name of the configuration to use * @param[out] denom_pub set to the denomination public key (to be freed by caller!) @@ -494,7 +507,8 @@ TEH_keys_management_get_keys_handler (const struct TEH_RequestHandler *rh, * #GNUNET_SYSERR on hard errors */ enum GNUNET_GenericReturnValue -TEH_keys_load_fees (const struct TALER_DenominationHashP *h_denom_pub, +TEH_keys_load_fees (struct TEH_KeyStateHandle *ksh, + const struct TALER_DenominationHashP *h_denom_pub, struct TALER_DenominationPublicKey *denom_pub, struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta); diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c b/src/exchange/taler-exchange-httpd_management_post_keys.c index 1fa09f7eb..7d9853e9b 100644 --- a/src/exchange/taler-exchange-httpd_management_post_keys.c +++ b/src/exchange/taler-exchange-httpd_management_post_keys.c @@ -84,6 +84,11 @@ struct AddKeysContext */ struct SigningSig *s_sigs; + /** + * Our key state. + */ + struct TEH_KeyStateHandle *ksh; + /** * Length of the d_sigs array. */ @@ -150,7 +155,8 @@ add_keys (void *cls, { enum GNUNET_GenericReturnValue rv; - rv = TEH_keys_load_fees (&d->h_denom_pub, + rv = TEH_keys_load_fees (akc->ksh, + &d->h_denom_pub, &denom_pub, &meta); switch (rv) @@ -370,6 +376,18 @@ TEH_handler_management_post_keys ( } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received /management/keys\n"); + akc.ksh = TEH_keys_get_state2 (true); /* may start its own transaction, thus + must be done here, before we run ours! */ + if (NULL == akc.ksh) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, + "no key state (not even for management)"); + } akc.nd_sigs = json_array_size (denom_sigs); akc.d_sigs = GNUNET_new_array (akc.nd_sigs, struct DenomSig);