summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-07-22 19:07:42 +0200
committerChristian Grothoff <christian@grothoff.org>2021-07-22 19:07:42 +0200
commitcb6dfdf2100ae0f15d93ad0907f52f67b04ffc98 (patch)
treea684e3dbf034090e48606e7b4869e7576b99cae0 /src/backend/taler-merchant-httpd_post-orders-ID-pay.c
parent334b2f954b029c85244472e2e22d1a84b9b592db (diff)
downloadmerchant-cb6dfdf2100ae0f15d93ad0907f52f67b04ffc98.tar.gz
merchant-cb6dfdf2100ae0f15d93ad0907f52f67b04ffc98.tar.bz2
merchant-cb6dfdf2100ae0f15d93ad0907f52f67b04ffc98.zip
-add double-coin detection logic
Diffstat (limited to 'src/backend/taler-merchant-httpd_post-orders-ID-pay.c')
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c152
1 files changed, 85 insertions, 67 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 94f40158..b72ae0ee 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -691,18 +691,18 @@ deposit_cb (void *cls,
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);
+ 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 */
@@ -715,9 +715,9 @@ deposit_cb (void *cls,
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");
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_STORE_FAILED,
+ "deposit");
return;
}
}
@@ -955,9 +955,9 @@ find_next_exchange (struct PayContext *pc)
{
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");
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED,
+ "Failed to lookup exchange by URL");
return;
}
return;
@@ -1080,7 +1080,7 @@ check_payment_sufficient (struct PayContext *pc)
if (0 == pc->coins_cnt)
{
- return ((0 == pc->amount.value) &&
+ return ((0 == pc->amount.value) &&
(0 == pc->amount.fraction));
}
@@ -1137,19 +1137,19 @@ 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))
+ &dc->wire_fee))
{
GNUNET_break_op (0);
resume_pay_with_error (pc,
- MHD_HTTP_CONFLICT,
- TALER_EC_GENERIC_CURRENCY_MISMATCH,
- total_wire_fee.currency);
+ MHD_HTTP_CONFLICT,
+ TALER_EC_GENERIC_CURRENCY_MISMATCH,
+ total_wire_fee.currency);
return false;
}
if (0 >
@@ -1159,9 +1159,9 @@ check_payment_sufficient (struct PayContext *pc)
{
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");
+ 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;
}
}
@@ -1324,9 +1324,10 @@ check_payment_sufficient (struct PayContext *pc)
return true;
}
+
/**
- *
- *
+ *
+ *
*/
static void
execute_pay_transaction (struct PayContext *pc)
@@ -1379,7 +1380,7 @@ execute_pay_transaction (struct PayContext *pc)
{
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,
@@ -1397,9 +1398,9 @@ execute_pay_transaction (struct PayContext *pc)
/* 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");
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "lookup deposits");
return;
}
}
@@ -1409,10 +1410,10 @@ execute_pay_transaction (struct PayContext *pc)
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);
+ instance_id,
+ &pc->h_contract_terms,
+ &check_coin_refunded,
+ pc);
if (0 > qs)
{
TMH_db->rollback (TMH_db->cls);
@@ -1424,9 +1425,9 @@ execute_pay_transaction (struct PayContext *pc)
/* 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");
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "lookup refunds");
return;
}
refunded = (qs > 0);
@@ -1462,9 +1463,9 @@ execute_pay_transaction (struct PayContext *pc)
enum GNUNET_DB_QueryStatus qs;
qs = TMH_db->mark_contract_paid (TMH_db->cls,
- instance_id,
- &pc->h_contract_terms,
- pc->session_id);
+ instance_id,
+ &pc->h_contract_terms,
+ pc->session_id);
if (qs < 0)
{
TMH_db->rollback (TMH_db->cls);
@@ -1475,9 +1476,9 @@ execute_pay_transaction (struct PayContext *pc)
}
GNUNET_break (0);
resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_STORE_FAILED,
- "mark contract paid");
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_STORE_FAILED,
+ "mark contract paid");
return;
}
}
@@ -1498,9 +1499,9 @@ execute_pay_transaction (struct PayContext *pc)
}
GNUNET_break (0);
resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_COMMIT_FAILED,
- NULL);
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_COMMIT_FAILED,
+ NULL);
return;
}
}
@@ -1615,23 +1616,23 @@ parse_pay (struct MHD_Connection *connection,
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_MISSING,
- "'coins' must be an array"))
- ? GNUNET_NO
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MISSING,
+ "'coins' must be an array"))
+ ? GNUNET_NO
: GNUNET_SYSERR;
}
- pc->coins_cnt = json_array_size (coins);
+ 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
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "'coins' array too long"))
+ ? GNUNET_NO
: GNUNET_SYSERR;
}
@@ -1662,16 +1663,33 @@ parse_pay (struct MHD_Connection *connection,
&exchange_url),
GNUNET_JSON_spec_end ()
};
+ enum GNUNET_GenericReturnValue res;
- enum GNUNET_GenericReturnValue res = TALER_MHD_parse_json_data (connection,
- coin,
- ispec);
+ res = TALER_MHD_parse_json_data (connection,
+ coin,
+ ispec);
if (GNUNET_YES != res)
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return res;
}
+ for (unsigned int j = 0; j<coins_index; j++)
+ {
+ if (0 ==
+ GNUNET_memcmp (&dc->coin_pub,
+ &pc->dc[j].coin_pub))
+ {
+ GNUNET_break_op (0);
+ return (MHD_YES ==
+ TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "duplicate coin in list"))
+ ? GNUNET_NO
+ : GNUNET_SYSERR;
+ }
+ }
dc->exchange_url = GNUNET_strdup (exchange_url);
dc->index = coins_index;
dc->pc = pc;
@@ -1770,7 +1788,7 @@ parse_pay (struct MHD_Connection *connection,
struct GNUNET_JSON_Specification espec[] = {
TALER_JSON_spec_amount ("amount",
&pc->amount),
- GNUNET_JSON_spec_mark_optional(
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("fulfillment_url",
&fulfillment_url)),
TALER_JSON_spec_amount ("max_fee",
@@ -1807,10 +1825,10 @@ parse_pay (struct MHD_Connection *connection,
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))))
+ ((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,