5198.diff (35,449 bytes)
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 9481e41..94c0ef4 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -12,7 +12,6 @@ arch.jpg: arch.dot
AM_MAKEINFOHTMLFLAGS = --no-split --css-ref=docstyle.css --css-ref=brown-paper.css
man_MANS = \
- taler-merchant-tip-enable.1 \
taler-merchant-generate-payments.1 \
taler-merchant-httpd.1
diff --git a/doc/manual.texi b/doc/manual.texi
index 3c7c3c0..b8e2c6c 100644
--- a/doc/manual.texi
+++ b/doc/manual.texi
@@ -1125,36 +1125,16 @@ Make your wire transfer and (optionally) check at
``https://exchange:443/reserve/status/reserve_pub=QPE24X...''
whether your transfer has arrived at the exchange.
@c FIXME: we should create a nicer tool to do this check!
-Once the funds have arrived, you can now enable tipping using:
-@example
-$ taler-merchant-tip-enable \
- --amount=AMOUNT \
- --backend=BACKEND_URI \
- --credit-uuid=CREDIT_UUID \
- --instance=INSTANCE \
- --expiration=EXPIRATION
-@end example
-For ``AMOUNT'', specify the amount you transferred in the usual Taler
-format of ``CURRENCY:VALUE[.FRACTION]'', i.e. ``EUR:50''. The
-``BACKEND_URI'' should be the URI where your Taler merchant backend is
-running. For ``CREDIT_UUID'', you need to specify a unique number
-that identifies your wire transfer. You may have gotten one from your
-bank, or you can just make one up! The important thing is that you
-must never use the same UUID twice, except to repeat a failed command.
-For INSTANCE, specify the backend instance (i.e. ``default'').
-Finally, for EXPIRATION, pick a date two weeks after the wire
-transfer, unless you know that the exchange that is being used has a
-different period for closing reserves. The format @code{YYYY-MM-DD}
-is accepted.
-
-Note that an exchange will typically close a reserve after two weeks,
+Once the funds have arrived, you can start to use the reserve
+for tipping.
+
+Note that an exchange will typically close a reserve after four weeks,
wiring all remaining funds back to the sender's account. Thus, you
should plan to wire funds corresponding to a campaign of about two
weeks to the exchange initially. If your campaign runs longer, you
-should wire further funds to the reserve every week to prevent it from
-expiring. You need to run the ``taler-merchant-tip-enable'' command
-each time after you wire more funds to the reserve.
+should wire further funds to the reserve every other week to prevent
+it from expiring.
@subsection Authorize a tip
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 648f2af..a83a185 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -23,7 +23,6 @@ taler_merchant_httpd_SOURCES = \
taler-merchant-httpd_pay.c taler-merchant-httpd_pay.h \
taler-merchant-httpd_history.c taler-merchant-httpd_history.h \
taler-merchant-httpd_tip-authorize.c taler-merchant-httpd_tip-authorize.h \
- taler-merchant-httpd_tip-enable.c taler-merchant-httpd_tip-enable.h \
taler-merchant-httpd_tip-pickup.c taler-merchant-httpd_tip-pickup.h \
taler-merchant-httpd_tip-query.c taler-merchant-httpd_tip-query.h \
taler-merchant-httpd_track-transaction.c taler-merchant-httpd_track-transaction.h \
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 2bf927d..af32f27 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -245,12 +245,6 @@ url_handler (void *cls,
{ "/tip-pickup", NULL, "application/json",
"Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED},
- { "/tip-enable", MHD_HTTP_METHOD_POST, "text/plain",
- NULL, 0,
- &MH_handler_tip_enable, MHD_HTTP_OK},
- { "/tip-enable", NULL, "application/json",
- "Only POST is allowed", 0,
- &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED},
{ "/tip-query", MHD_HTTP_METHOD_GET, "text/plain",
NULL, 0,
&MH_handler_tip_query, MHD_HTTP_OK},
diff --git a/src/backend/taler-merchant-httpd_tip-authorize.c b/src/backend/taler-merchant-httpd_tip-authorize.c
index c55b41b..aaa62c4 100644
--- a/src/backend/taler-merchant-httpd_tip-authorize.c
+++ b/src/backend/taler-merchant-httpd_tip-authorize.c
@@ -29,13 +29,8 @@
#include "taler-merchant-httpd_tip-authorize.h"
-/**
- * Information we keep for individual calls
- * to requests that parse JSON, but keep no other state.
- */
-struct TMH_JsonParseContext
+struct TipAuthContext
{
-
/**
* This field MUST be first.
* FIXME: Explain why!
@@ -46,21 +41,218 @@ struct TMH_JsonParseContext
* Placeholder for #TMH_PARSE_post_json() to keep its internal state.
*/
void *json_parse_context;
+
+ /**
+ * HTTP connection we are handling.
+ */
+ struct MHD_Connection *connection;
+
+ /**
+ * Tip amount requested.
+ */
+ struct TALER_Amount amount;
+
+ /**
+ * Merchant instance to use.
+ */
+ const char *instance;
+
+ /**
+ * Justification to use.
+ */
+ const char *justification;
+
+ /**
+ * Pickup URL to use.
+ */
+ const char *pickup_url;
+
+ /**
+ * URL to navigate to after tip.
+ */
+ const char *next_url;
+
+ /**
+ * JSON request received.
+ */
+ json_t *root;
+
+ /**
+ * Handle to pending /reserve/status request.
+ */
+ struct TALER_EXCHANGE_ReserveStatusHandle *rsh;
+
+ /**
+ * Handle for operation to obtain exchange handle.
+ */
+ struct TMH_EXCHANGES_FindOperation *fo;
+
+ /**
+ * Private key used by this merchant for the tipping reserve.
+ */
+ struct TALER_ReservePrivateKeyP reserve_priv;
+
+ /**
+ * Flag set to #GNUNET_YES when we have tried /reserve/status of the
+ * tipping reserve already.
+ */
+ int checked_status;
+
+ /**
+ * Flag set to #GNUNET_YES when we have parsed the incoming JSON already.
+ */
+ int parsed_json;
};
/**
- * Custom cleanup routine for a `struct TMH_JsonParseContext`.
+ * Custom cleanup routine for a `struct TipAuthContext`.
*
* @param hc the `struct TMH_JsonParseContext` to clean up.
*/
static void
-json_parse_cleanup (struct TM_HandlerContext *hc)
+cleanup_tac (struct TM_HandlerContext *hc)
+{
+ struct TipAuthContext *tac = (struct TipAuthContext *) hc;
+
+ if (NULL != tac->root)
+ {
+ json_decref (tac->root);
+ tac->root = NULL;
+ }
+ if (NULL != tac->rsh)
+ {
+ TALER_EXCHANGE_reserve_status_cancel (tac->rsh);
+ tac->rsh = NULL;
+ }
+ if (NULL != tac->fo)
+ {
+ TMH_EXCHANGES_find_exchange_cancel (tac->fo);
+ tac->fo = NULL;
+ }
+ TMH_PARSE_post_cleanup_callback (tac->json_parse_context);
+ GNUNET_free (tac);
+}
+
+
+/**
+ * Function called with the result of the /reserve/status request
+ * for the tipping reserve. Update our database balance with the
+ * result.
+ *
+ * @param cls closure with a `struct TipAuthContext *'
+ * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
+ * 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
+ * @param[in] json original response in JSON format (useful only for diagnostics)
+ * @param balance current balance in the reserve, NULL on error
+ * @param history_length number of entries in the transaction history, 0 on error
+ * @param history detailed transaction history, NULL on error
+ */
+static void
+handle_status (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const json_t *json,
+ const struct TALER_Amount *balance,
+ unsigned int history_length,
+ const struct TALER_EXCHANGE_ReserveHistory *history)
+{
+ struct TipAuthContext *tac = cls;
+ struct GNUNET_TIME_Relative idle_reserve_expiration_time;
+
+ if (MHD_HTTP_OK != http_status)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to obtain tipping reserve status from exchange (%u/%d)\n"),
+ http_status,
+ ec);
+ MHD_resume_connection (tac->connection);
+ return;
+ }
+
+ /* TODO: get this from the exchange! (See #5254.) */
+ idle_reserve_expiration_time = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_WEEKS,
+ 4);
+
+ /* Update DB based on status! */
+ for (unsigned int i=0;i<history_length;i++)
+ {
+ switch (history[i].type)
+ {
+ case TALER_EXCHANGE_RTT_DEPOSIT:
+ {
+ enum GNUNET_DB_QueryStatus qs;
+ struct GNUNET_HashCode uuid;
+ struct GNUNET_TIME_Absolute expiration;
+
+ expiration = GNUNET_TIME_absolute_add (history[i].details.in_details.timestamp,
+ idle_reserve_expiration_time);
+ GNUNET_CRYPTO_hash (history[i].details.in_details.wire_reference,
+ history[i].details.in_details.wire_reference_size,
+ &uuid);
+ qs = db->enable_tip_reserve (db->cls,
+ &tac->reserve_priv,
+ &uuid,
+ &history[i].amount,
+ expiration);
+ if (0 > qs)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Database error updating tipping reserve status: %d\n"),
+ qs);
+ }
+ }
+ case TALER_EXCHANGE_RTT_WITHDRAWAL:
+ /* expected */
+ break;
+ case TALER_EXCHANGE_RTT_PAYBACK:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Encountered unsupported /payback operation on tipping reserve\n"));
+ break;
+ case TALER_EXCHANGE_RTT_CLOSE:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Exchange closed reserve (due to expiration), balance calulation is likely wrong. Please create a fresh reserve.\n"));
+ break;
+ }
+ }
+ /* Finally, resume processing */
+ MHD_resume_connection (tac->connection);
+}
+
+
+/**
+ * Function called with the result of a #TMH_EXCHANGES_find_exchange()
+ * operation.
+ *
+ * @param cls closure with a `struct TipAuthContext *'
+ * @param eh handle to the exchange context
+ * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if not available
+ * @param exchange_trusted #GNUNET_YES if this exchange is trusted by config
+ */
+static void
+exchange_cont (void *cls,
+ struct TALER_EXCHANGE_Handle *eh,
+ const struct TALER_Amount *wire_fee,
+ int exchange_trusted)
{
- struct TMH_JsonParseContext *jpc = (struct TMH_JsonParseContext *) hc;
+ struct TipAuthContext *tac = cls;
+ struct TALER_ReservePublicKeyP reserve_pub;
- TMH_PARSE_post_cleanup_callback (jpc->json_parse_context);
- GNUNET_free (jpc);
+ tac->fo = NULL;
+ if (NULL == eh)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to contact exchange configured for tipping!\n"));
+ MHD_resume_connection (tac->connection);
+ return;
+ }
+ GNUNET_CRYPTO_eddsa_key_get_public (&tac->reserve_priv.eddsa_priv,
+ &reserve_pub.eddsa_pub);
+ tac->rsh = TALER_EXCHANGE_reserve_status (eh,
+ &reserve_pub,
+ &handle_status,
+ tac);
}
@@ -81,66 +273,63 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
const char *upload_data,
size_t *upload_data_size)
{
- struct MerchantInstance *mi;
+ struct TipAuthContext *tac;
int res;
- struct TALER_Amount amount;
- const char *instance;
- const char *justification;
- const char *pickup_url;
- const char *next_url;
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount ("amount", &amount),
- GNUNET_JSON_spec_string ("instance", &instance),
- GNUNET_JSON_spec_string ("justification", &justification),
- GNUNET_JSON_spec_string ("pickup_url", &pickup_url),
- GNUNET_JSON_spec_string ("next_url", &next_url),
- GNUNET_JSON_spec_end()
- };
- json_t *root;
+ struct MerchantInstance *mi;
+ enum TALER_ErrorCode ec;
struct GNUNET_TIME_Absolute expiration;
struct GNUNET_HashCode tip_id;
- struct TMH_JsonParseContext *ctx;
- enum TALER_ErrorCode ec;
if (NULL == *connection_cls)
{
- ctx = GNUNET_new (struct TMH_JsonParseContext);
- ctx->hc.cc = &json_parse_cleanup;
- *connection_cls = ctx;
+ tac = GNUNET_new (struct TipAuthContext);
+ tac->hc.cc = &cleanup_tac;
+ *connection_cls = tac;
}
else
{
- ctx = *connection_cls;
+ tac = *connection_cls;
}
res = TMH_PARSE_post_json (connection,
- &ctx->json_parse_context,
+ &tac->json_parse_context,
upload_data,
upload_data_size,
- &root);
+ &tac->root);
if (GNUNET_SYSERR == res)
return MHD_NO;
/* the POST's body has to be further fetched */
if ( (GNUNET_NO == res) ||
- (NULL == root) )
+ (NULL == tac->root) )
return MHD_YES;
- res = TMH_PARSE_json_data (connection,
- root,
- spec);
- if (GNUNET_YES != res)
+ if (GNUNET_NO == tac->parsed_json)
{
- GNUNET_break_op (0);
- json_decref (root);
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_amount ("amount", &tac->amount),
+ GNUNET_JSON_spec_string ("instance", &tac->instance),
+ GNUNET_JSON_spec_string ("justification", &tac->justification),
+ GNUNET_JSON_spec_string ("pickup_url", &tac->pickup_url),
+ GNUNET_JSON_spec_string ("next_url", &tac->next_url),
+ GNUNET_JSON_spec_end()
+ };
+
+ res = TMH_PARSE_json_data (connection,
+ tac->root,
+ spec);
+ if (GNUNET_YES != res)
+ {
+ GNUNET_break_op (0);
+ return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ }
+ tac->parsed_json = GNUNET_YES;
}
- mi = TMH_lookup_instance (instance);
+ mi = TMH_lookup_instance (tac->instance);
if (NULL == mi)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Instance `%s' not configured\n",
- instance);
- json_decref (root);
+ tac->instance);
return TMH_RESPONSE_reply_not_found (connection,
TALER_EC_TIP_AUTHORIZE_INSTANCE_UNKNOWN,
"unknown instance");
@@ -149,19 +338,35 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Instance `%s' not configured for tipping\n",
- instance);
- json_decref (root);
+ tac->instance);
return TMH_RESPONSE_reply_not_found (connection,
TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP,
"exchange for tipping not configured for the instance");
}
+ tac->reserve_priv = mi->tip_reserve;
ec = db->authorize_tip (db->cls,
- justification,
- &amount,
+ tac->justification,
+ &tac->amount,
&mi->tip_reserve,
mi->tip_exchange,
&expiration,
&tip_id);
+ /* If we have insufficient funds according to OUR database,
+ check with exchange to see if the reserve has been topped up
+ in the meantime (or if tips were not withdrawn yet). */
+ if ( (TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS == ec) &&
+ (GNUNET_NO == tac->checked_status) )
+ {
+ MHD_suspend_connection (connection);
+ tac->checked_status = GNUNET_YES;
+ tac->fo = TMH_EXCHANGES_find_exchange (mi->tip_exchange,
+ NULL,
+ &exchange_cont,
+ tac);
+ return MHD_YES;
+ }
+
+ /* handle irrecoverable errors */
if (TALER_EC_NONE != ec)
{
unsigned int rc;
@@ -184,43 +389,31 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
rc = MHD_HTTP_INTERNAL_SERVER_ERROR;
break;
}
- json_decref (root);
return TMH_RESPONSE_reply_rc (connection,
- rc,
- ec,
- "Database error approving tip");
+ rc,
+ ec,
+ "Database error approving tip");
}
- if (0)
+
+ /* generate success response */
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Insufficient funds to authorize tip over `%s' at instance `%s'\n",
- TALER_amount2s (&amount),
- instance);
- json_decref (root);
- return TMH_RESPONSE_reply_rc (connection,
- MHD_HTTP_PRECONDITION_FAILED,
- TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS,
- "Insufficient funds for tip");
+ json_t *tip_token;
+
+ tip_token = json_pack ("{s:o, s:o, s:o, s:s, s:s, s:s}",
+ "tip_id", GNUNET_JSON_from_data_auto (&tip_id),
+ "expiration", GNUNET_JSON_from_time_abs (expiration),
+ "amount", TALER_JSON_from_amount (&tac->amount),
+ "exchange_url", mi->tip_exchange,
+ "next_url", tac->next_url,
+ "pickup_url", tac->pickup_url);
+ return TMH_RESPONSE_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o, s:s, s:o}",
+ "tip_id", GNUNET_JSON_from_data_auto (&tip_id),
+ "expiration", GNUNET_JSON_from_time_abs (expiration),
+ "exchange_url", mi->tip_exchange,
+ "tip_token", tip_token);
}
- json_t *tip_token = json_pack ("{s:o, s:o, s:o, s:s, s:s, s:s}",
- "tip_id", GNUNET_JSON_from_data_auto (&tip_id),
- "expiration", GNUNET_JSON_from_time_abs (expiration),
- "amount", TALER_JSON_from_amount (&amount),
- "exchange_url", mi->tip_exchange,
- "next_url", next_url,
- "pickup_url", pickup_url);
- char *tip_token_str = json_dumps (tip_token, JSON_ENSURE_ASCII | JSON_COMPACT);
- json_decref (tip_token);
- json_decref (root);
- int ret = TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o, s:s, s:s}",
- "tip_id", GNUNET_JSON_from_data_auto (&tip_id),
- "expiration", GNUNET_JSON_from_time_abs (expiration),
- "exchange_url", mi->tip_exchange,
- "tip_token", tip_token_str);
- GNUNET_free (tip_token_str);
- return ret;
}
/* end of taler-merchant-httpd_tip-authorize.c */
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index 51db135..81f1219 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -309,7 +309,7 @@ struct TALER_MERCHANT_PayCoin
* Amount this coin is to contribute (without fee).
*/
struct TALER_Amount amount_without_fee;
-
+
/**
* Fee the exchange charges for refunds of this coin.
*/
@@ -317,7 +317,7 @@ struct TALER_MERCHANT_PayCoin
/**
* URL of the exchange that issued @e coin_priv.
- */
+ */
const char *exchange_url;
};
@@ -373,12 +373,12 @@ struct TALER_MERCHANT_RefundEntry
{
/**
* Merchant signature affirming the refund.
- */
+ */
struct TALER_MerchantSignatureP merchant_sig;
/**
* Public key of the refunded coin.
- */
+ */
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
@@ -789,71 +789,6 @@ void
TALER_MERCHANT_history_cancel (struct TALER_MERCHANT_HistoryOperation *ho);
-/* ********************** /tip-enable ************************* */
-
-
-/**
- * Handle for a /tip-enable operation.
- */
-struct TALER_MERCHANT_TipEnableOperation;
-
-
-/**
- * Callback for a /tip-enable request. Returns the result of
- * the operation.
- *
- * @param cls closure
- * @param http_status HTTP status returned by the merchant backend
- * @param ec taler-specific error code
- */
-typedef void
-(*TALER_MERCHANT_TipEnableCallback) (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec);
-
-
-/**
- * Issue a /tip-enable request to the backend. Informs the backend
- * that a reserve is now available for tipping. Note that the
- * respective @a reserve_priv must also be bound to one or more
- * instances (together with the URL of the exchange) via the backend's
- * configuration file before it can be used. Usually, the process
- * is that one first configures an exchange and a @a reserve_priv for
- * an instance, and then enables (or re-enables) the reserve by
- * performing wire transfers and informs the backend about it using
- * this API.
- *
- * @param ctx execution context
- * @param backend_url base URL of the merchant backend
- * @param amount amount that was credited to the reserve
- * @param expiration when will the reserve expire
- * @param reserve_priv private key of the reserve
- * @param credit_uuid unique ID of the wire transfer
- * @param enable_cb callback which will work the response gotten from the backend
- * @param enable_cb_cls closure to pass to @a enable_cb
- * @return handle for this operation, NULL upon errors
- */
-struct TALER_MERCHANT_TipEnableOperation *
-TALER_MERCHANT_tip_enable (struct GNUNET_CURL_Context *ctx,
- const char *backend_url,
- const struct TALER_Amount *amount,
- struct GNUNET_TIME_Absolute expiration,
- const struct TALER_ReservePrivateKeyP *reserve_priv,
- const struct GNUNET_HashCode *credit_uuid,
- TALER_MERCHANT_TipEnableCallback enable_cb,
- void *enable_cb_cls);
-
-
-
-/**
- * Cancel a pending /tip-enable request
- *
- * @param teo handle from the operation to cancel
- */
-void
-TALER_MERCHANT_tip_enable_cancel (struct TALER_MERCHANT_TipEnableOperation *teo);
-
-
/* ********************** /tip-authorize ********************** */
/**
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 5f46122..4c6d5f8 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -18,7 +18,6 @@ libtalermerchant_la_SOURCES = \
merchant_api_proposal.c \
merchant_api_pay.c \
merchant_api_tip_authorize.c \
- merchant_api_tip_enable.c \
merchant_api_tip_pickup.c \
merchant_api_track_transaction.c \
merchant_api_track_transfer.c \
diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c
index b09d78a..a51ac2e 100644
--- a/src/lib/test_merchant_api.c
+++ b/src/lib/test_merchant_api.c
@@ -175,14 +175,14 @@ enum OpCode
/**
* Resume pay operation with additional coins.
- */
+ */
OC_PAY_AGAIN,
-
+
/**
* Abort payment with coins, requesting refund.
*/
OC_PAY_ABORT,
-
+
/**
* Abort payment with coins, executing refund.
*/
@@ -233,11 +233,6 @@ enum OpCode
*/
OC_REFUND_LOOKUP,
- /**
- * Start a reserve for tipping.
- */
- OC_TIP_ENABLE,
-
/**
* Authorize a tip.
*/
@@ -551,12 +546,12 @@ struct Command
*/
const char *amount_without_fee;
- /**
+ /**
* Refund fee to use for each coin (only relevant if we
* exercise /pay's abort functionality).
*/
const char *refund_fee;
-
+
/**
* Pay handle while operation is running.
*/
@@ -594,7 +589,7 @@ struct Command
* Pay handle while operation is running.
*/
struct TALER_MERCHANT_Pay *ph;
-
+
} pay_again;
struct {
@@ -609,7 +604,7 @@ struct Command
*/
struct TALER_MERCHANT_Pay *ph;
- /**
+ /**
* Set in #pay_refund_cb to number of refunds obtained.
*/
unsigned int num_refunds;
@@ -621,12 +616,12 @@ struct Command
/**
* Set to the hash of the original contract.
- */
- struct GNUNET_HashCode h_contract;
+ */
+ struct GNUNET_HashCode h_contract;
/**
* Set to the merchant's public key.
- */
+ */
struct TALER_MerchantPublicKeyP merchant_pub;
} pay_abort;
@@ -635,7 +630,7 @@ struct Command
/**
* Reference to the pay_abort command to be refunded.
- */
+ */
const char *abort_ref;
/**
@@ -652,7 +647,7 @@ struct Command
* Refund fee to expect.
*/
const char *refund_fee;
-
+
/**
* Handle to the refund operation.
*/
@@ -1870,7 +1865,7 @@ pay_again_cb (void *cls,
}
GNUNET_assert (NULL != (pref = find_command
(is,
- cmd->details.pay_again.pay_ref)));
+ cmd->details.pay_again.pay_ref)));
if (MHD_HTTP_OK == http_status)
{
struct PaymentResponsePS mr;
@@ -1882,7 +1877,7 @@ pay_again_cb (void *cls,
&mr.h_contract_terms),
GNUNET_JSON_spec_end ()
};
-
+
GNUNET_assert (GNUNET_OK ==
GNUNET_JSON_parse (obj,
spec,
@@ -2056,45 +2051,6 @@ track_transaction_cb (void *cls,
}
-/**
- * Callback for a /tip-enable request. Returns the result of
- * the operation.
- *
- * @param cls closure
- * @param http_status HTTP status returned by the merchant backend
- * @param ec taler-specific error code
- */
-static void
-tip_enable_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec)
-{
- struct InterpreterState *is = cls;
- struct Command *cmd = &is->commands[is->ip];
-
- cmd->details.tip_enable.teo = NULL;
- if (cmd->expected_response_code != http_status)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u to command %s\n",
- http_status,
- cmd->label);
- fail (is);
- return;
- }
- if (cmd->details.tip_enable.expected_ec != ec)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected error code %u to command %s\n",
- ec,
- cmd->label);
- fail (is);
- return;
- }
- next_command (is);
-}
-
-
/**
* Callback for a /tip-authorize request. Returns the result of
* the operation.
@@ -2553,13 +2509,6 @@ cleanup_state (struct InterpreterState *is)
cmd->details.refund_lookup.rlo = NULL;
}
break;
- case OC_TIP_ENABLE:
- if (NULL != cmd->details.tip_enable.teo)
- {
- TALER_MERCHANT_tip_enable_cancel (cmd->details.tip_enable.teo);
- cmd->details.tip_enable.teo = NULL;
- }
- break;
case OC_TIP_AUTHORIZE:
if (NULL != cmd->details.tip_authorize.tao)
{
@@ -2626,7 +2575,7 @@ cleanup_state (struct InterpreterState *is)
* Parse the @a coins specification and grow the @a pc
* array with the coins found, updating @a npc.
*
- * @param[in,out] pc pointer to array of coins found
+ * @param[in,out] pc pointer to array of coins found
* @param[in,out] npc length of array at @a pc
* @param[in] coins string specifying coins to add to @a pc,
* clobbered in the process
@@ -2641,8 +2590,8 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
struct InterpreterState *is,
const struct Command *pref)
{
- char *token;
-
+ char *token;
+
for (token = strtok (coins, ";");
NULL != token;
token = strtok (NULL, ";"))
@@ -2651,7 +2600,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
char *ctok;
unsigned int ci;
struct TALER_MERCHANT_PayCoin *icoin;
-
+
/* Token syntax is "LABEL[/NUMBER]" */
ctok = strchr (token, '/');
ci = 0;
@@ -2692,7 +2641,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
default:
GNUNET_assert (0);
}
-
+
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount (pref->details.pay.amount_with_fee,
&icoin->amount_with_fee));
@@ -2735,7 +2684,7 @@ pay_refund_cb (void *cls,
{
struct InterpreterState *is = cls;
struct Command *cmd = &is->commands[is->ip];
-
+
cmd->details.pay_abort.ph = NULL;
if (cmd->expected_response_code != http_status)
{
@@ -2784,7 +2733,7 @@ abort_refund_cb (void *cls,
{
struct InterpreterState *is = cls;
struct Command *cmd = &is->commands[is->ip];
-
+
cmd->details.pay_abort_refund.rh = NULL;
if (cmd->expected_response_code != http_status)
{
@@ -3289,7 +3238,7 @@ interpreter_run (void *cls)
GNUNET_break (0);
fail (is);
}
- break;
+ break;
case OC_PAY_ABORT:
{
struct TALER_MERCHANT_PayCoin *pc;
@@ -3420,7 +3369,7 @@ interpreter_run (void *cls)
GNUNET_assert (ref->details.pay_abort.num_refunds >
cmd->details.pay_abort_refund.num_coin);
re = &ref->details.pay_abort.res[cmd->details.pay_abort_refund.num_coin];
-
+
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount
(cmd->details.pay_abort_refund.refund_amount,
@@ -3650,83 +3599,6 @@ interpreter_run (void *cls)
}
break;
}
- case OC_TIP_ENABLE:
- {
- const struct Command *uuid_ref;
- struct TALER_ReservePrivateKeyP reserve_priv;
- struct GNUNET_TIME_Absolute expiration;
-
- if (NULL != cmd->details.tip_enable.admin_add_incoming_ref)
- {
- ref = find_command (is,
- cmd->details.tip_enable.admin_add_incoming_ref);
- GNUNET_assert (NULL != ref);
- GNUNET_assert (OC_ADMIN_ADD_INCOMING == ref->oc);
- }
- else
- {
- ref = NULL;
- }
-
- /* Initialize 'credit_uuid' */
- if (NULL != cmd->details.tip_enable.uuid_ref)
- {
- uuid_ref = find_command (is,
- cmd->details.tip_enable.uuid_ref);
- GNUNET_assert (NULL != uuid_ref);
- GNUNET_assert (OC_TIP_ENABLE == uuid_ref->oc);
- cmd->details.tip_enable.credit_uuid
- = uuid_ref->details.tip_enable.credit_uuid;
- }
- else
- {
- uuid_ref = NULL;
- GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
- &cmd->details.tip_enable.credit_uuid,
- sizeof (cmd->details.tip_enable.credit_uuid));
- }
-
- /* Initialize 'amount' */
- if ( (NULL != ref) &&
- (NULL == cmd->details.tip_enable.amount) )
- {
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount (ref->details.admin_add_incoming.amount,
- &amount));
- }
- else
- {
- GNUNET_assert (NULL != cmd->details.tip_enable.amount);
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount (cmd->details.tip_enable.amount,
- &amount));
- }
- if (NULL == ref)
- GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
- &reserve_priv,
- sizeof (reserve_priv));
- /* Simply picked long enough for the test (we do not test expiration
- behavior for now), should be short enough so that the reserve
- expires before the test is run again, so that we avoid old
- state messing up fresh runs. */
- expiration = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
-
- if (NULL == (cmd->details.tip_enable.teo
- = TALER_MERCHANT_tip_enable
- (ctx,
- MERCHANT_URL,
- &amount,
- expiration,
- (ref != NULL) ? &ref->details.admin_add_incoming.reserve_priv : &reserve_priv,
- &cmd->details.tip_enable.credit_uuid,
- &tip_enable_cb,
- is)))
- {
- GNUNET_break (0);
- fail (is);
- }
- break;
- }
case OC_TIP_AUTHORIZE:
{
GNUNET_assert (NULL != cmd->details.tip_authorize.amount);
@@ -4318,17 +4190,6 @@ run (void *cls)
.details.check_bank_transfer.account_debit = 62,
.details.check_bank_transfer.account_credit = EXCHANGE_ACCOUNT_NO
},
- { .oc = OC_TIP_ENABLE,
- .label = "enable-tip-1",
- .expected_response_code = MHD_HTTP_OK,
- .details.tip_enable.admin_add_incoming_ref = "create-reserve-tip-1",
- .details.tip_enable.amount = "EUR:5.01" },
- /* Test incrementing active reserve balance */
- { .oc = OC_TIP_ENABLE,
- .label = "enable-tip-2",
- .expected_response_code = MHD_HTTP_OK,
- .details.tip_enable.admin_add_incoming_ref = "create-reserve-tip-1",
- .details.tip_enable.amount = "EUR:5.01" },
/* Authorize two tips */
{ .oc = OC_TIP_AUTHORIZE,
.label = "authorize-tip-1",
@@ -4519,7 +4380,7 @@ run (void *cls)
.details.pay.refund_fee = "EUR:0.01",
.details.pay_again.pay_ref = "pay-fail-partial-double-10",
.details.pay_again.coin_ref = "withdraw-coin-10a;withdraw-coin-10b" },
-
+
/* Run transfers. */
{ .oc = OC_RUN_AGGREGATOR,
.label = "run-aggregator-10" },
@@ -4632,14 +4493,14 @@ run (void *cls)
.details.pay_abort_refund.num_coin = 0,
.details.pay_abort_refund.refund_amount = "EUR:5",
.details.pay_abort_refund.refund_fee = "EUR:0.01" },
-
+
/* Run transfers. */
{ .oc = OC_RUN_AGGREGATOR,
.label = "run-aggregator-11" },
/* Check that there are no other unusual transfers */
{ .oc = OC_CHECK_BANK_TRANSFERS_EMPTY,
.label = "check_bank_empty-11" },
-
+
/* end of testcase */
{ .oc = OC_END }
};
diff --git a/src/merchant-tools/Makefile.am b/src/merchant-tools/Makefile.am
index 7811d04..4e68837 100644
--- a/src/merchant-tools/Makefile.am
+++ b/src/merchant-tools/Makefile.am
@@ -3,8 +3,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include
bin_PROGRAMS = \
taler-merchant-dbinit \
- taler-merchant-generate-payments \
- taler-merchant-tip-enable
+ taler-merchant-generate-payments
taler_merchant_dbinit_SOURCES = \
taler-merchant-dbinit.c
@@ -16,16 +15,6 @@ taler_merchant_dbinit_LDADD = \
-ltalerutil \
-ltalerpq
-taler_merchant_tip_enable_SOURCES = \
- taler-merchant-tip-enable.c
-
-taler_merchant_tip_enable_LDADD = \
- $(LIBGCRYPT_LIBS) \
- $(top_builddir)/src/lib/libtalermerchant.la \
- -lgnunetcurl \
- -lgnunetutil \
- -ltalerutil
-
taler_merchant_generate_payments_SOURCES = \
taler-merchant-generate-payments.c