diff options
Diffstat (limited to 'src/exchange')
-rw-r--r-- | src/exchange/Makefile.am | 1 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_keys.h | 4 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_metrics.h | 3 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_merge.c | 64 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_merge.h | 46 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_wire.c | 16 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_wire.h | 14 |
7 files changed, 123 insertions, 25 deletions
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index c4c1656a..949a1dcb 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -104,6 +104,7 @@ taler_exchange_httpd_SOURCES = \ taler-exchange-httpd_metrics.c taler-exchange-httpd_metrics.h \ taler-exchange-httpd_mhd.c taler-exchange-httpd_mhd.h \ taler-exchange-httpd_purses_create.c taler-exchange-httpd_purses_create.h \ + taler-exchange-httpd_purses_merge.c taler-exchange-httpd_purses_merge.h \ taler-exchange-httpd_recoup.c taler-exchange-httpd_recoup.h \ taler-exchange-httpd_recoup-refresh.c taler-exchange-httpd_recoup-refresh.h \ taler-exchange-httpd_refreshes_reveal.c taler-exchange-httpd_refreshes_reveal.h \ diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index 544906ad..d8fe81e5 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -318,8 +318,8 @@ TEH_keys_denomination_cs_r_pub_melt ( * @param h_denom_pub hash of the public key to revoke */ void -TEH_keys_denomination_revoke (const struct - TALER_DenominationHashP *h_denom_pub); +TEH_keys_denomination_revoke ( + const struct TALER_DenominationHashP *h_denom_pub); /** diff --git a/src/exchange/taler-exchange-httpd_metrics.h b/src/exchange/taler-exchange-httpd_metrics.h index d1d20d9a..4fef6464 100644 --- a/src/exchange/taler-exchange-httpd_metrics.h +++ b/src/exchange/taler-exchange-httpd_metrics.h @@ -36,7 +36,8 @@ enum TEH_MetricTypeRequest TEH_MT_REQUEST_WITHDRAW = 2, TEH_MT_REQUEST_MELT = 3, TEH_MT_REQUEST_PURSE_CREATE = 4, - TEH_MT_REQUEST_COUNT = 5 /* MUST BE LAST! */ + TEH_MT_REQUEST_PURSE_MERGE = 5, + TEH_MT_REQUEST_COUNT = 6 /* MUST BE LAST! */ }; /** diff --git a/src/exchange/taler-exchange-httpd_purses_merge.c b/src/exchange/taler-exchange-httpd_purses_merge.c index 07038cb6..2121169c 100644 --- a/src/exchange/taler-exchange-httpd_purses_merge.c +++ b/src/exchange/taler-exchange-httpd_purses_merge.c @@ -32,6 +32,7 @@ #include "taler-exchange-httpd_responses.h" #include "taler_exchangedb_lib.h" #include "taler-exchange-httpd_keys.h" +#include "taler-exchange-httpd_wire.h" /** @@ -60,6 +61,11 @@ struct PurseMergeContext struct GNUNET_TIME_Timestamp purse_expiration; /** + * When the client signed the merge. + */ + struct GNUNET_TIME_Timestamp merge_timestamp; + + /** * Our current time. */ struct GNUNET_TIME_Timestamp exchange_timestamp; @@ -92,7 +98,7 @@ struct PurseMergeContext /** * Fees that apply to this operation. */ - const struct TEH_GlobalFee *gf; + const struct TALER_WireFeeSet *wf; /** * URI of the account the purse is to be merged into. @@ -101,7 +107,7 @@ struct PurseMergeContext const char *payto_uri; /** - * Base URL of the exchange provider. + * Base URL of the exchange provider hosting the reserve. */ char *provider_url; @@ -138,10 +144,26 @@ reply_merge_success (struct MHD_Connection *connection, TALER_JSON_pack_amount ("balance", &pcc->balance)); } - // FIXME: check return value... - TALER_amount_subtract (&merge_amount, - &pcc->target_amount, - &gf->fees.merge); + if (0 == strcmp (pcc->provider_url, + TEH_base_url)) + { + /* wad fee is always zero if we stay at our own exchange */ + merge_amount = pcc->target_amount; + } + else + { + if (0 > + TALER_amount_subtract (&merge_amount, + &pcc->target_amount, + &pcc->wf->wad)) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_ec ( + connection, + TALER_EC_EXCHANGE_PURSE_MERGE_WAD_FEE_EXCEEDS_PURSE_VALUE, + TALER_amount2s (&pcc->wf->wad)); + } + } if (TALER_EC_NONE != (ec = TALER_exchange_online_purse_merged_sign ( &TEH_keys_exchange_sign_, @@ -149,8 +171,9 @@ reply_merge_success (struct MHD_Connection *connection, pcc->purse_expiration, &merge_amount, pcc->purse_pub, - &pcc->merge_pub, &pcc->h_contract_terms, + &pcc->reserve_pub, + pcc->provider_url, &pub, &sig))) { @@ -200,7 +223,7 @@ merge_transaction (void *cls, &pcc->merge_sig, pcc->merge_timestamp, pcc->provider_url, - &pcc.reserve_pub); + &pcc->reserve_pub); if (qs < 0) { if (GNUNET_DB_STATUS_SOFT_ERROR == qs) @@ -250,7 +273,7 @@ TEH_handler_purses_merge ( }; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("payto_uri", - &pcc.payt_uri), + &pcc.payto_uri), GNUNET_JSON_spec_fixed_auto ("reserve_sig", &pcc.reserve_sig), GNUNET_JSON_spec_fixed_auto ("merge_sig", @@ -281,9 +304,9 @@ TEH_handler_purses_merge ( } } - pcc.gf = TEH_keys_global_fee_by_time (TEH_keys_get_state (), - pcc.exchange_timestamp); - if (NULL == pcc.gf) + pcc.wf = TEH_wire_fees_by_time (pcc.exchange_timestamp, + "sepa"); // FIXME! + if (NULL == pcc.wf) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Cannot create purse: global fees not configured!\n"); @@ -294,13 +317,13 @@ TEH_handler_purses_merge ( } /* Fetch purse details */ qs = TEH_plugin->select_purse_request (TEH_plugin->cls, - pcc->purse_pub, - &pcc->merge_pub, - &pcc->purse_expiration, - &pcc->h_contract_terms, - &pcc->min_age, - &pcc->target_amount, - &pcc->balance, + pcc.purse_pub, + &pcc.merge_pub, + &pcc.purse_expiration, + &pcc.h_contract_terms, + &pcc.min_age, + &pcc.target_amount, + &pcc.balance, &purse_sig); switch (qs) { @@ -395,8 +418,9 @@ TEH_handler_purses_merge ( /* check signatures */ if (GNUNET_OK != TALER_wallet_purse_merge_verify ( - pcc.payto_url, + pcc.payto_uri, pcc.merge_timestamp, + pcc.purse_pub, &pcc.merge_pub, &pcc.merge_sig)) { diff --git a/src/exchange/taler-exchange-httpd_purses_merge.h b/src/exchange/taler-exchange-httpd_purses_merge.h new file mode 100644 index 00000000..3bc6e169 --- /dev/null +++ b/src/exchange/taler-exchange-httpd_purses_merge.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file taler-exchange-httpd_purses_merge.h + * @brief Handle /purses/$PID/merge requests + * @author Christian Grothoff + */ +#ifndef TALER_EXCHANGE_HTTPD_PURSES_MERGE_H +#define TALER_EXCHANGE_HTTPD_PURSES_MERGE_H + +#include <gnunet/gnunet_util_lib.h> +#include <microhttpd.h> +#include "taler-exchange-httpd.h" + + +/** + * Handle a "/purses/$PURSE_PUB/merge" request. Parses the JSON, and, if + * successful, passes the JSON data to #merge_transaction() to further check + * the details of the operation specified. If everything checks out, this + * will ultimately lead to the "purses merge" being executed, or rejected. + * + * @param connection the MHD connection to handle + * @param purse_pub public key of the purse + * @param root uploaded JSON data + * @return MHD result code + */ +MHD_RESULT +TEH_handler_purses_merge (struct MHD_Connection *connection, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const json_t *root); + + +#endif diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c index e1adde22..cbd0f640 100644 --- a/src/exchange/taler-exchange-httpd_wire.c +++ b/src/exchange/taler-exchange-httpd_wire.c @@ -158,11 +158,13 @@ make_ec_reply (enum TALER_ErrorCode ec, const char *detail) { return GNUNET_JSON_PACK ( - GNUNET_JSON_pack_uint64 ("code", ec), + GNUNET_JSON_pack_uint64 ("code", + ec), GNUNET_JSON_pack_string ("hint", TALER_ErrorCode_get_hint (ec)), GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("detail", detail))); + GNUNET_JSON_pack_string ("detail", + detail))); } @@ -421,4 +423,14 @@ TEH_handler_wire (struct TEH_RequestContext *rc, } +const struct TALER_WireFeeSet * +TEH_wire_fees_by_time ( + struct GNUNET_TIME_Timestamp ts, + const char *method) +{ + GNUNET_break (0); // FIXME: implement! + return NULL; +} + + /* end of taler-exchange-httpd_wire.c */ diff --git a/src/exchange/taler-exchange-httpd_wire.h b/src/exchange/taler-exchange-httpd_wire.h index ed815a57..75595fe6 100644 --- a/src/exchange/taler-exchange-httpd_wire.h +++ b/src/exchange/taler-exchange-httpd_wire.h @@ -34,6 +34,20 @@ TEH_wire_done (void); /** + * Look up wire fee structure by @a ts. + * + * @param ts timestamp to lookup wire fees at + * @param method wire method to lookup fees for + * @return the wire fee details, or + * NULL if none are configured for @a ts and @a method + */ +const struct TALER_WireFeeSet * +TEH_wire_fees_by_time ( + struct GNUNET_TIME_Timestamp ts, + const char *method); + + +/** * Initialize wire subsystem. * * @return #GNUNET_OK on success |