summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-07-22 13:42:49 -0300
committerSebastian <sebasjm@gmail.com>2021-07-22 13:43:23 -0300
commit4a008c1e1356535cec84126a31f27d084393bdbd (patch)
tree8c3de1ee3ebbe8f7f79555cd6307c2b2824f738b /src
parent2f4a05e7a2f947372f97d11ac8c08fc705c79e59 (diff)
downloadmerchant-4a008c1e1356535cec84126a31f27d084393bdbd.tar.gz
merchant-4a008c1e1356535cec84126a31f27d084393bdbd.tar.bz2
merchant-4a008c1e1356535cec84126a31f27d084393bdbd.zip
worshop fixes
Diffstat (limited to 'src')
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c439
1 files changed, 248 insertions, 191 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index 31ccbbea..71457c85 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -40,6 +40,11 @@
#define MAX_RETRIES 5
/**
+ * Maximum number of coins that we allow per transaction
+ */
+#define MAX_COIN_ALLOWED_COINS 1024
+
+/**
* Information we keep for an individual call to the pay handler.
*/
struct PayContext;
@@ -196,7 +201,7 @@ struct PayContext
/**
* Transaction ID given in @e root.
*/
- char *order_id;
+ const char *order_id;
/**
* Fulfillment URL from the contract, or NULL if we don't have one.
@@ -342,7 +347,7 @@ struct PayContext
* #GNUNET_SYSERR if @e connection was resumed to as
* part of #MH_force_pc_resume during shutdown.
*/
- int suspended;
+ enum GNUNET_GenericReturnValue suspended;
/**
* true if we already tried a forced /keys download.
@@ -526,7 +531,6 @@ pay_context_cleanup (void *cls)
MHD_destroy_response (pc->response);
pc->response = NULL;
}
- GNUNET_free (pc->order_id);
GNUNET_free (pc->fulfillment_url);
GNUNET_free (pc->session_id);
GNUNET_CONTAINER_DLL_remove (pc_head,
@@ -547,14 +551,14 @@ find_next_exchange (struct PayContext *pc);
/**
- * Begin of the DB transaction. If required (from
+ * Execute the DB transaction. If required (from
* soft/serialization errors), the transaction can be
* restarted here.
*
* @param pc payment context to transact
*/
static void
-begin_transaction (struct PayContext *pc);
+execute_pay_transaction (struct PayContext *pc);
/**
@@ -579,7 +583,6 @@ deposit_cb (void *cls,
{
struct DepositConfirmation *dc = cls;
struct PayContext *pc = dc->pc;
- enum GNUNET_DB_QueryStatus qs;
dc->dh = NULL;
GNUNET_assert (GNUNET_YES == pc->suspended);
@@ -632,6 +635,7 @@ deposit_cb (void *cls,
/* Forward error, adding the "coin_pub" for which the
error was being generated */
if (TALER_EC_EXCHANGE_DEPOSIT_INSUFFICIENT_FUNDS == hr->ec)
+ {
resume_pay_with_response (
pc,
MHD_HTTP_CONFLICT,
@@ -650,7 +654,9 @@ deposit_cb (void *cls,
GNUNET_JSON_from_data_auto (&dc->coin_pub),
"exchange_reply",
hr->reply));
+ }
else
+ {
resume_pay_with_response (
pc,
MHD_HTTP_BAD_GATEWAY,
@@ -669,6 +675,7 @@ deposit_cb (void *cls,
GNUNET_JSON_from_data_auto (&dc->coin_pub),
"exchange_reply",
hr->reply));
+ }
}
return;
}
@@ -680,37 +687,41 @@ deposit_cb (void *cls,
GNUNET_h2s (&pc->h_contract_terms),
pc->hc->instance->settings.id);
TMH_db->preflight (TMH_db->cls);
- qs = TMH_db->insert_deposit (TMH_db->cls,
- pc->hc->instance->settings.id,
- deposit_timestamp,
- &pc->h_contract_terms,
- &dc->coin_pub,
- dc->exchange_url,
- &dc->amount_with_fee,
- &dc->deposit_fee,
- &dc->refund_fee,
- &dc->wire_fee,
- &pc->wm->h_wire,
- exchange_sig,
- exchange_pub);
- if (0 > qs)
{
- /* Special report if retries insufficient */
- abort_deposit (pc);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = TMH_db->insert_deposit (TMH_db->cls,
+ pc->hc->instance->settings.id,
+ deposit_timestamp,
+ &pc->h_contract_terms,
+ &dc->coin_pub,
+ dc->exchange_url,
+ &dc->amount_with_fee,
+ &dc->deposit_fee,
+ &dc->refund_fee,
+ &dc->wire_fee,
+ &pc->wm->h_wire,
+ exchange_sig,
+ exchange_pub);
+ if (0 > qs)
{
- begin_transaction (pc);
+ /* Special report if retries insufficient */
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ {
+ execute_pay_transaction (pc);
+ return;
+ }
+ /* Always report on hard error as well to enable diagnostics */
+ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+ /* Forward error including 'proof' for the body */
+ resume_pay_with_error (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_STORE_FAILED,
+ "deposit");
return;
}
- /* Always report on hard error as well to enable diagnostics */
- GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- /* Forward error including 'proof' for the body */
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_STORE_FAILED,
- "deposit");
- return;
}
+
dc->found_in_db = true; /* well, at least NOW it'd be true ;-) */
pc->pending--;
@@ -764,7 +775,6 @@ process_pay_with_exchange (void *cls,
if ( (MHD_HTTP_OK != hr->http_status) ||
(NULL == exchange_handle) )
{
- GNUNET_break_op (0);
resume_pay_with_response (
pc,
MHD_HTTP_BAD_GATEWAY,
@@ -932,31 +942,31 @@ find_next_exchange (struct PayContext *pc)
{
struct DepositConfirmation *dc = &pc->dc[i];
- if (! dc->found_in_db)
+ if (dc->found_in_db)
+ continue;
+
+ pc->current_exchange = dc->exchange_url;
+ pc->fo = TMH_EXCHANGES_find_exchange (pc->current_exchange,
+ pc->wm->wire_method,
+ GNUNET_NO,
+ &process_pay_with_exchange,
+ pc);
+ if (NULL == pc->fo)
{
- pc->current_exchange = dc->exchange_url;
- pc->fo = TMH_EXCHANGES_find_exchange (pc->current_exchange,
- pc->wm->wire_method,
- GNUNET_NO,
- &process_pay_with_exchange,
- pc);
- if (NULL == pc->fo)
- {
- GNUNET_break (0);
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED,
- "Failed to lookup exchange by URL");
- return;
- }
+ GNUNET_break (0);
+ resume_pay_with_error (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED,
+ "Failed to lookup exchange by URL");
return;
}
+ return;
}
pc->current_exchange = NULL;
/* We are done with all the HTTP requests, go back and try
the 'big' database transaction! (It should work now!) */
GNUNET_assert (0 == pc->pending);
- begin_transaction (pc);
+ execute_pay_transaction (pc);
}
@@ -1097,6 +1107,7 @@ check_payment_sufficient (struct PayContext *pc)
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW,
"Overflow adding up amounts");
+ return false;
}
if (1 ==
TALER_amount_cmp (&dc->deposit_fee,
@@ -1121,34 +1132,35 @@ check_payment_sufficient (struct PayContext *pc)
new_exchange = false;
break;
}
- if (new_exchange)
+
+ if (!new_exchange)
+ continue;
+
+ if (GNUNET_OK !=
+ TALER_amount_cmp_currency (&total_wire_fee,
+ &dc->wire_fee))
{
- if (GNUNET_OK !=
- TALER_amount_cmp_currency (&total_wire_fee,
- &dc->wire_fee))
- {
- GNUNET_break_op (0);
- resume_pay_with_error (pc,
- MHD_HTTP_PRECONDITION_FAILED,
- TALER_EC_GENERIC_CURRENCY_MISMATCH,
- total_wire_fee.currency);
- return false;
- }
- if (0 >
- TALER_amount_add (&total_wire_fee,
- &total_wire_fee,
- &dc->wire_fee))
- {
- GNUNET_break (0);
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED,
- "could not add exchange wire fee to total");
- return false;
- }
+ GNUNET_break_op (0);
+ resume_pay_with_error (pc,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_GENERIC_CURRENCY_MISMATCH,
+ total_wire_fee.currency);
+ return false;
+ }
+ if (0 >
+ TALER_amount_add (&total_wire_fee,
+ &total_wire_fee,
+ &dc->wire_fee))
+ {
+ GNUNET_break (0);
+ resume_pay_with_error (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED,
+ "could not add exchange wire fee to total");
+ return false;
}
}
- }
+ } /* deposit loop */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Amount received from wallet: %s\n",
@@ -1175,8 +1187,9 @@ check_payment_sufficient (struct PayContext *pc)
TALER_amount_cmp_currency (&total_wire_fee,
&pc->max_wire_fee))
{
+ GNUNET_break (0);
resume_pay_with_error (pc,
- MHD_HTTP_PRECONDITION_FAILED,
+ MHD_HTTP_CONFLICT,
TALER_EC_GENERIC_CURRENCY_MISMATCH,
total_wire_fee.currency);
return false;
@@ -1278,6 +1291,7 @@ check_payment_sufficient (struct PayContext *pc)
if (-1 < TALER_amount_cmp (&acc_amount,
&total_needed))
{
+ GNUNET_break_op (0);
resume_pay_with_error (pc,
MHD_HTTP_PAYMENT_REQUIRED,
TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUNDED,
@@ -1305,11 +1319,13 @@ check_payment_sufficient (struct PayContext *pc)
return true;
}
-
+/**
+ *
+ *
+ */
static void
-begin_transaction (struct PayContext *pc)
+execute_pay_transaction (struct PayContext *pc)
{
- enum GNUNET_DB_QueryStatus qs;
struct TMH_HandlerContext *hc = pc->hc;
const char *instance_id = hc->instance->settings.id;
bool refunded;
@@ -1356,53 +1372,60 @@ begin_transaction (struct PayContext *pc)
return;
}
- /* Check if some of these coins already succeeded for _this_ contract. */
- qs = TMH_db->lookup_deposits (TMH_db->cls,
- instance_id,
- &pc->h_contract_terms,
- &check_coin_paid,
- pc);
- if (0 > qs)
{
- TMH_db->rollback (TMH_db->cls);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ enum GNUNET_DB_QueryStatus qs;
+
+ /* Check if some of these coins already succeeded for _this_ contract. */
+ qs = TMH_db->lookup_deposits (TMH_db->cls,
+ instance_id,
+ &pc->h_contract_terms,
+ &check_coin_paid,
+ pc);
+ if (0 > qs)
{
- begin_transaction (pc);
+ TMH_db->rollback (TMH_db->cls);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ {
+ execute_pay_transaction (pc);
+ return;
+ }
+ /* Always report on hard error as well to enable diagnostics */
+ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+ resume_pay_with_error (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "lookup deposits");
return;
}
- /* Always report on hard error as well to enable diagnostics */
- GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "deposits");
- return;
}
- /* Check if we refunded some of the coins */
- qs = TMH_db->lookup_refunds (TMH_db->cls,
- instance_id,
- &pc->h_contract_terms,
- &check_coin_refunded,
- pc);
- if (0 > qs)
+
{
- TMH_db->rollback (TMH_db->cls);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ enum GNUNET_DB_QueryStatus qs;
+ /* Check if we refunded some of the coins */
+ qs = TMH_db->lookup_refunds (TMH_db->cls,
+ instance_id,
+ &pc->h_contract_terms,
+ &check_coin_refunded,
+ pc);
+ if (0 > qs)
{
- begin_transaction (pc);
+ TMH_db->rollback (TMH_db->cls);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ {
+ execute_pay_transaction (pc);
+ return;
+ }
+ /* Always report on hard error as well to enable diagnostics */
+ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+ resume_pay_with_error (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "lookup refunds");
return;
}
- /* Always report on hard error as well to enable diagnostics */
- GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "lookup refunds");
- return;
+ refunded = (qs > 0);
}
- refunded = (qs > 0);
-
/* Check if there are coins that still need to be processed */
if (0 != pc->pending)
@@ -1430,41 +1453,51 @@ begin_transaction (struct PayContext *pc)
"Order `%s' (%s) was fully paid\n",
pc->order_id,
GNUNET_h2s (&pc->h_contract_terms));
- qs = TMH_db->mark_contract_paid (TMH_db->cls,
- instance_id,
- &pc->h_contract_terms,
- pc->session_id);
- if (qs < 0)
{
- TMH_db->rollback (TMH_db->cls);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = TMH_db->mark_contract_paid (TMH_db->cls,
+ instance_id,
+ &pc->h_contract_terms,
+ pc->session_id);
+ if (qs < 0)
{
- begin_transaction (pc);
+ TMH_db->rollback (TMH_db->cls);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ {
+ execute_pay_transaction (pc);
+ return;
+ }
+ GNUNET_break (0);
+ resume_pay_with_error (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_STORE_FAILED,
+ "mark contract paid");
return;
}
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_STORE_FAILED,
- "mark contract paid");
- return;
}
- /* Now commit! */
- qs = TMH_db->commit (TMH_db->cls);
- if (0 > qs)
{
- /* commit failed */
- TMH_db->rollback (TMH_db->cls);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ enum GNUNET_DB_QueryStatus qs;
+
+ /* Now commit! */
+ qs = TMH_db->commit (TMH_db->cls);
+ if (0 > qs)
{
- begin_transaction (pc);
+ /* commit failed */
+ TMH_db->rollback (TMH_db->cls);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ {
+ execute_pay_transaction (pc);
+ return;
+ }
+ GNUNET_break (0);
+ resume_pay_with_error (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_COMMIT_FAILED,
+ NULL);
return;
}
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_COMMIT_FAILED,
- NULL);
- return;
}
/* Notify clients that have been waiting for the payment to succeed */
@@ -1509,15 +1542,7 @@ begin_transaction (struct PayContext *pc)
resp = json_pack ("{s:o}",
"sig",
GNUNET_JSON_from_data_auto (&sig));
- if (NULL == resp)
- {
- GNUNET_break (0);
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_JSON_ALLOCATION_FAILURE,
- "Could not build final response");
- return;
- }
+ GNUNET_assert (NULL != resp);
resume_pay_with_response (pc,
MHD_HTTP_OK,
TALER_MHD_make_json (resp));
@@ -1580,15 +1605,29 @@ parse_pay (struct MHD_Connection *connection,
pc->session_id = GNUNET_strdup ("");
}
- if ( (! json_is_array (coins)) ||
- (0 == (pc->coins_cnt = json_array_size (coins))) )
+ if (! json_is_array (coins))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_with_error (connection,
+ return (MHD_YES == TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_GENERIC_PARAMETER_MISSING,
- "'coins' array is empty or not even an array");
+ "'coins' must be an array"))
+ ? GNUNET_NO
+ : GNUNET_SYSERR;
+ }
+
+ pc->coins_cnt = json_array_size (coins);
+ if (pc->coins_cnt > MAX_COIN_ALLOWED_COINS)
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return (MHD_YES == TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "'coins' array too long"))
+ ? GNUNET_NO
+ : GNUNET_SYSERR;
}
/* note: 1 coin = 1 deposit confirmation expected */
@@ -1603,49 +1642,51 @@ parse_pay (struct MHD_Connection *connection,
{
struct DepositConfirmation *dc = &pc->dc[coins_index];
const char *exchange_url;
- enum GNUNET_GenericReturnValue res;
struct GNUNET_JSON_Specification ispec[] = {
+ GNUNET_JSON_spec_fixed_auto ("coin_sig",
+ &dc->coin_sig),
+ GNUNET_JSON_spec_fixed_auto ("coin_pub",
+ &dc->coin_pub),
+ TALER_JSON_spec_denomination_signature ("ub_sig",
+ &dc->ub_sig),
GNUNET_JSON_spec_fixed_auto ("h_denom",
&dc->h_denom),
TALER_JSON_spec_amount ("contribution",
&dc->amount_with_fee),
GNUNET_JSON_spec_string ("exchange_url",
&exchange_url),
- GNUNET_JSON_spec_fixed_auto ("coin_pub",
- &dc->coin_pub),
- TALER_JSON_spec_denomination_signature ("ub_sig",
- &dc->ub_sig),
- GNUNET_JSON_spec_fixed_auto ("coin_sig",
- &dc->coin_sig),
GNUNET_JSON_spec_end ()
};
- res = TALER_MHD_parse_json_data (connection,
- coin,
- ispec);
+ enum GNUNET_GenericReturnValue res = TALER_MHD_parse_json_data (connection,
+ coin,
+ ispec);
if (GNUNET_YES != res)
{
- GNUNET_JSON_parse_free (spec);
GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
return res;
}
dc->exchange_url = GNUNET_strdup (exchange_url);
dc->index = coins_index;
dc->pc = pc;
+
+ if (0 !=
+ strcasecmp (dc->amount_with_fee.currency,
+ TMH_currency))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_GENERIC_CURRENCY_MISMATCH,
+ TMH_currency);
+ }
}
}
GNUNET_JSON_parse_free (spec);
}
- /* copy order ID */
- {
- const char *order_id = hc->infix;
-
- GNUNET_assert (NULL != order_id);
- GNUNET_assert (NULL == pc->order_id);
- pc->order_id = GNUNET_strdup (order_id);
- }
-
/* obtain contract terms */
{
enum GNUNET_DB_QueryStatus qs;
@@ -1720,36 +1761,36 @@ parse_pay (struct MHD_Connection *connection,
/* Get details from contract and check fundamentals */
{
+ const char *fulfillment_url = NULL;
struct GNUNET_JSON_Specification espec[] = {
+ TALER_JSON_spec_amount ("amount",
+ &pc->amount),
+ GNUNET_JSON_spec_mark_optional(
+ GNUNET_JSON_spec_string ("fulfillment_url",
+ &fulfillment_url)),
+ TALER_JSON_spec_amount ("max_fee",
+ &pc->max_fee),
+ TALER_JSON_spec_amount ("max_wire_fee",
+ &pc->max_wire_fee),
+ GNUNET_JSON_spec_uint32 ("wire_fee_amortization",
+ &pc->wire_fee_amortization),
+ TALER_JSON_spec_absolute_time ("timestamp",
+ &pc->timestamp),
TALER_JSON_spec_absolute_time ("refund_deadline",
&pc->refund_deadline),
TALER_JSON_spec_absolute_time ("pay_deadline",
&pc->pay_deadline),
TALER_JSON_spec_absolute_time ("wire_transfer_deadline",
&pc->wire_transfer_deadline),
- TALER_JSON_spec_absolute_time ("timestamp",
- &pc->timestamp),
- TALER_JSON_spec_amount ("max_fee",
- &pc->max_fee),
- TALER_JSON_spec_amount ("amount",
- &pc->amount),
GNUNET_JSON_spec_fixed_auto ("h_wire",
&pc->h_wire),
- GNUNET_JSON_spec_uint32 ("wire_fee_amortization",
- &pc->wire_fee_amortization),
- TALER_JSON_spec_amount ("max_wire_fee",
- &pc->max_wire_fee),
GNUNET_JSON_spec_end ()
};
enum GNUNET_GenericReturnValue res;
- const char *fulfillment_url;
res = TALER_MHD_parse_internal_json_data (connection,
contract_terms,
espec);
- fulfillment_url
- = json_string_value (json_object_get (contract_terms,
- "fulfillment_url"));
if (NULL != fulfillment_url)
pc->fulfillment_url = GNUNET_strdup (fulfillment_url);
json_decref (contract_terms);
@@ -1758,6 +1799,20 @@ parse_pay (struct MHD_Connection *connection,
GNUNET_break (0);
return res;
}
+
+ if ((0 != strcasecmp (pc->amount.currency,
+ TMH_currency)) ||
+ (0 != strcasecmp (pc->max_fee.currency,
+ TMH_currency) ||
+ (0 != strcasecmp (pc->max_wire_fee.currency,
+ TMH_currency))))
+ {
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_CURRENCY_MISMATCH,
+ TMH_currency);
+ }
}
if (pc->wire_transfer_deadline.abs_value_us <
@@ -1771,8 +1826,7 @@ parse_pay (struct MHD_Connection *connection,
NULL);
}
- if (pc->pay_deadline.abs_value_us <
- GNUNET_TIME_absolute_get ().abs_value_us)
+ if (0 == GNUNET_TIME_absolute_get_remaining (pc->pay_deadline).rel_value_us)
{
/* too late */
return (MHD_YES ==
@@ -1841,6 +1895,8 @@ TMH_post_orders_ID_pay (const struct TMH_RequestHandler *rh,
{
struct PayContext *pc = hc->ctx;
+ GNUNET_assert (NULL != hc->infix);
+
if (NULL == pc)
{
pc = GNUNET_new (struct PayContext);
@@ -1849,11 +1905,13 @@ TMH_post_orders_ID_pay (const struct TMH_RequestHandler *rh,
pc);
pc->connection = connection;
pc->hc = hc;
+ pc->order_id = hc->infix;
hc->ctx = pc;
hc->cc = &pay_context_cleanup;
}
if (GNUNET_SYSERR == pc->suspended)
return MHD_NO; /* during shutdown, we don't generate any more replies */
+ GNUNET_assert (GNUNET_NO == pc->suspended);
if (0 != pc->response_code)
{
MHD_RESULT res;
@@ -1888,7 +1946,6 @@ TMH_post_orders_ID_pay (const struct TMH_RequestHandler *rh,
}
/* Payment not finished, suspend while we interact with the exchange */
- GNUNET_assert (GNUNET_NO == pc->suspended);
MHD_suspend_connection (connection);
pc->suspended = GNUNET_YES;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1898,7 +1955,7 @@ TMH_post_orders_ID_pay (const struct TMH_RequestHandler *rh,
GNUNET_SCHEDULER_add_delayed (get_pay_timeout (pc->coins_cnt),
&handle_pay_timeout,
pc);
- begin_transaction (pc);
+ execute_pay_transaction (pc);
return MHD_YES;
}