aboutsummaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/Makefile.am1
-rw-r--r--src/exchange/taler-exchange-httpd_keys.h4
-rw-r--r--src/exchange/taler-exchange-httpd_metrics.h3
-rw-r--r--src/exchange/taler-exchange-httpd_purses_merge.c64
-rw-r--r--src/exchange/taler-exchange-httpd_purses_merge.h46
-rw-r--r--src/exchange/taler-exchange-httpd_wire.c16
-rw-r--r--src/exchange/taler-exchange-httpd_wire.h14
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