commit 9e2795084737fa588a0b0552ca04cbd165aba10b
parent fe973b29bba8a6f46989743e4263a23e473735b8
Author: Marcello Stanisci <marcello.stanisci@inria.fr>
Date: Thu, 13 Oct 2016 00:27:43 +0200
adapting callback for 'find_transaction' DB functions family
Diffstat:
6 files changed, 370 insertions(+), 338 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_history.c b/src/backend/taler-merchant-httpd_history.c
@@ -31,6 +31,7 @@
*
* @param cls closure
* @param transaction_id of the contract
+ * @param merchant_pub merchant's public key
* @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
@@ -42,6 +43,7 @@
static void
history_cb (void *cls,
uint64_t transaction_id,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_wire,
diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c
@@ -786,6 +786,7 @@ check_coin_paid (void *cls,
*
* @param cls closure with the `struct PayContext`
* @param transaction_id of the contract
+ * @param merchant_pub merchant's public key
* @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_xwire hash of our wire details
@@ -794,325 +795,327 @@ check_coin_paid (void *cls,
* @param total_amount total amount we receive for the contract after fees
*/
static void
-check_transaction_exists (void *cls,
- uint64_t transaction_id,
- const char *exchange_uri,
- const struct GNUNET_HashCode *h_contract,
- const struct GNUNET_HashCode *h_xwire,
- struct GNUNET_TIME_Absolute timestamp,
- struct GNUNET_TIME_Absolute refund,
- const struct TALER_Amount *total_amount)
-{
- struct PayContext *pc = cls;
-
- if ( (0 == memcmp (h_contract,
- &pc->h_contract,
- sizeof (struct GNUNET_HashCode))) &&
- (0 == memcmp (h_xwire,
- &pc->mi->h_wire,
- sizeof (struct GNUNET_HashCode))) &&
- (timestamp.abs_value_us == pc->timestamp.abs_value_us) &&
- (refund.abs_value_us == pc->refund_deadline.abs_value_us) &&
- (0 == TALER_amount_cmp (total_amount,
- &pc->amount) ) )
- {
- pc->transaction_exits = GNUNET_YES;
- }
- else
- {
- GNUNET_break_op (0);
- pc->transaction_exits = GNUNET_SYSERR;
- }
-}
-
-extern struct MerchantInstance *
-get_instance (struct json_t *json);
-
-/**
- * Accomplish this payment.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure
- * (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a
- * upload_data
- * @return MHD result code
- */
-int
-MH_handler_pay (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- struct PayContext *pc;
- int res;
- json_t *root;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "In handler for /pay.\n");
- if (NULL == *connection_cls)
- {
- pc = GNUNET_new (struct PayContext);
- pc->hc.cc = &pay_context_cleanup;
- pc->connection = connection;
- *connection_cls = pc;
- }
- else
- {
- /* not the first call, recover state */
- pc = *connection_cls;
- }
- if (0 != pc->response_code)
- {
- /* We are *done* processing the request, just queue the response (!) */
- if (UINT_MAX == pc->response_code)
- {
- GNUNET_break (0);
- return MHD_NO; /* hard error */
- }
- res = MHD_queue_response (connection,
- pc->response_code,
- pc->response);
- if (NULL != pc->response)
- {
- MHD_destroy_response (pc->response);
- pc->response = NULL;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Queueing response (%u) for /pay (%s).\n",
- (unsigned int) pc->response_code,
- res ? "OK" : "FAILED");
- return res;
- }
- if (NULL != pc->chosen_exchange)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Shouldn't be here. Old MHD version?\n");
- return MHD_YES;
- }
- res = TMH_PARSE_post_json (connection,
- &pc->json_parse_context,
- upload_data,
- upload_data_size,
- &root);
- if (GNUNET_SYSERR == res)
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_external_error (connection,
- "failed to parse JSON body");
- }
- if ((GNUNET_NO == res) || (NULL == root))
- return MHD_YES; /* the POST's body has to be further fetched */
-
- mi = get_instance (root);
-
- /* Got the JSON upload, parse it */
- {
- json_t *coins;
- json_t *coin;
- unsigned int coins_index;
- struct TALER_MerchantSignatureP merchant_sig;
- struct TALER_ContractPS cp;
- const char *chosen_exchange;
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount ("amount", &pc->amount),
- GNUNET_JSON_spec_json ("coins", &coins),
- GNUNET_JSON_spec_fixed_auto ("H_contract", &pc->h_contract),
- TALER_JSON_spec_amount ("max_fee", &pc->max_fee),
- GNUNET_JSON_spec_fixed_auto ("merchant_sig", &merchant_sig),
- GNUNET_JSON_spec_string ("exchange", &chosen_exchange),
- GNUNET_JSON_spec_absolute_time ("refund_deadline", &pc->refund_deadline),
- GNUNET_JSON_spec_absolute_time ("timestamp", &pc->timestamp),
- GNUNET_JSON_spec_uint64 ("transaction_id", &pc->transaction_id),
- GNUNET_JSON_spec_end()
- };
-
- res = TMH_PARSE_json_data (connection,
- root,
- spec);
- if (GNUNET_YES != res)
- {
- json_decref (root);
- GNUNET_break (0);
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- }
- pc->mi = get_instance (root);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "/pay: picked instance %s\n",
- pc->mi->id);
-
- if (NULL == pc->mi)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Not able to find the specified receiver\n");
- json_decref (root);
- return TMH_RESPONSE_reply_external_error (connection,
- "Unknown receiver given");
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "The receiver for this deposit is '%s', whose bank details are '%s'\n",
- pc->mi->id,
- json_dumps (pc->mi->j_wire, JSON_COMPACT));
- pc->chosen_exchange = GNUNET_strdup (chosen_exchange);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Parsed JSON for /pay.\n");
- cp.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_CONTRACT);
- cp.purpose.size = htonl (sizeof (struct TALER_ContractPS));
- cp.transaction_id = GNUNET_htonll (pc->transaction_id);
- TALER_amount_hton (&cp.total_amount,
- &pc->amount);
- TALER_amount_hton (&cp.max_fee,
- &pc->max_fee);
- cp.h_contract = pc->h_contract;
- cp.merchant_pub = pc->mi->pubkey;
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_CONTRACT,
- &cp.purpose,
- &merchant_sig.eddsa_sig,
- &pc->mi->pubkey.eddsa_pub))
- {
- GNUNET_break (0);
- GNUNET_JSON_parse_free (spec);
- json_decref (root);
- return TMH_RESPONSE_reply_external_error (connection,
- "invalid merchant signature supplied");
- }
-
- /* 'wire_transfer_deadline' is optional, if it is not present,
- generate it here; it will be timestamp plus the
- wire_transfer_delay supplied in config file */
- if (NULL == json_object_get (root,
- "wire_transfer_deadline"))
- {
- pc->wire_transfer_deadline = GNUNET_TIME_absolute_add (pc->timestamp,
- wire_transfer_delay);
- if (pc->wire_transfer_deadline.abs_value_us < pc->refund_deadline.abs_value_us)
- {
- /* Refund value very large, delay wire transfer accordingly */
- pc->wire_transfer_deadline = pc->refund_deadline;
- }
- }
- else
- {
- struct GNUNET_JSON_Specification espec[] = {
- GNUNET_JSON_spec_absolute_time ("wire_transfer_deadline",
- &pc->wire_transfer_deadline),
- GNUNET_JSON_spec_end()
- };
-
- res = TMH_PARSE_json_data (connection,
- root,
- espec);
- if (GNUNET_YES != res)
- {
- GNUNET_JSON_parse_free (spec);
- json_decref (root);
- GNUNET_break (0);
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- }
- if (pc->wire_transfer_deadline.abs_value_us < pc->refund_deadline.abs_value_us)
- {
- GNUNET_break (0);
- GNUNET_JSON_parse_free (spec);
- json_decref (root);
- return TMH_RESPONSE_reply_external_error (connection,
- "refund deadline after wire transfer deadline");
- }
- }
-
-
- pc->coins_cnt = json_array_size (coins);
- if (0 == pc->coins_cnt)
- {
- GNUNET_JSON_parse_free (spec);
- json_decref (root);
- return TMH_RESPONSE_reply_external_error (connection,
- "no coins given");
- }
- /* note: 1 coin = 1 deposit confirmation expected */
- pc->dc = GNUNET_new_array (pc->coins_cnt,
- struct DepositConfirmation);
-
- /* This loop populates the array 'dc' in 'pc' */
- json_array_foreach (coins, coins_index, coin)
- {
- struct DepositConfirmation *dc = &pc->dc[coins_index];
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_denomination_public_key ("denom_pub", &dc->denom),
- TALER_JSON_spec_amount ("f" /* FIXME */, &dc->amount_with_fee),
- 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 = TMH_PARSE_json_data (connection,
- coin,
- spec);
- if (GNUNET_YES != res)
- {
- GNUNET_JSON_parse_free (spec);
- json_decref (root);
- GNUNET_break (0);
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- }
-
- {
- char *s;
-
- s = TALER_amount_to_string (&dc->amount_with_fee);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Coin #%i has f %s\n",
- coins_index,
- s);
- GNUNET_free (s);
- }
-
- dc->index = coins_index;
- dc->pc = pc;
- }
- GNUNET_JSON_parse_free (spec);
- } /* end of parsing of JSON upload */
- pc->pending = pc->coins_cnt;
-
- /* Check if this payment attempt has already succeeded */
- if (GNUNET_SYSERR ==
- db->find_payments_by_id (db->cls,
- pc->transaction_id,
- &check_coin_paid,
- pc))
- {
- GNUNET_break (0);
- json_decref (root);
- return TMH_RESPONSE_reply_internal_error (connection,
- "Merchant database error");
- }
- if (0 == pc->pending)
- {
- struct MHD_Response *resp;
- int ret;
-
- /* Payment succeeded in the past; take short cut
- and accept immediately */
- resp = MHD_create_response_from_buffer (0,
- NULL,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- resp);
- MHD_destroy_response (resp);
- json_decref (root);
- return ret;
- }
- /* Check if transaction is already known, if not store it. */
- if (GNUNET_SYSERR ==
- db->find_transaction_by_id (db->cls,
- pc->transaction_id,
- &check_transaction_exists,
- pc))
+ check_transaction_exists (void *cls,
+ uint64_t transaction_id,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const char *exchange_uri,
+ const struct GNUNET_HashCode *h_contract,
+ const struct GNUNET_HashCode *h_xwire,
+ struct GNUNET_TIME_Absolute timestamp,
+ struct GNUNET_TIME_Absolute refund,
+ const struct TALER_Amount *total_amount)
+ {
+ struct PayContext *pc = cls;
+
+ if ( (0 == memcmp (h_contract,
+ &pc->h_contract,
+ sizeof (struct GNUNET_HashCode))) &&
+ (0 == memcmp (h_xwire,
+ &pc->mi->h_wire,
+ sizeof (struct GNUNET_HashCode))) &&
+ (timestamp.abs_value_us == pc->timestamp.abs_value_us) &&
+ (refund.abs_value_us == pc->refund_deadline.abs_value_us) &&
+ (0 == TALER_amount_cmp (total_amount,
+ &pc->amount) ) )
+ {
+ pc->transaction_exits = GNUNET_YES;
+ }
+ else
+ {
+ GNUNET_break_op (0);
+ pc->transaction_exits = GNUNET_SYSERR;
+ }
+ }
+
+ extern struct MerchantInstance *
+ get_instance (struct json_t *json);
+
+ /**
+ * Accomplish this payment.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure
+ * (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a
+ * upload_data
+ * @return MHD result code
+ */
+ int
+ MH_handler_pay (struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ void **connection_cls,
+ const char *upload_data,
+ size_t *upload_data_size)
+ {
+ struct PayContext *pc;
+ int res;
+ json_t *root;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "In handler for /pay.\n");
+ if (NULL == *connection_cls)
+ {
+ pc = GNUNET_new (struct PayContext);
+ pc->hc.cc = &pay_context_cleanup;
+ pc->connection = connection;
+ *connection_cls = pc;
+ }
+ else
+ {
+ /* not the first call, recover state */
+ pc = *connection_cls;
+ }
+ if (0 != pc->response_code)
+ {
+ /* We are *done* processing the request, just queue the response (!) */
+ if (UINT_MAX == pc->response_code)
+ {
+ GNUNET_break (0);
+ return MHD_NO; /* hard error */
+ }
+ res = MHD_queue_response (connection,
+ pc->response_code,
+ pc->response);
+ if (NULL != pc->response)
+ {
+ MHD_destroy_response (pc->response);
+ pc->response = NULL;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Queueing response (%u) for /pay (%s).\n",
+ (unsigned int) pc->response_code,
+ res ? "OK" : "FAILED");
+ return res;
+ }
+ if (NULL != pc->chosen_exchange)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Shouldn't be here. Old MHD version?\n");
+ return MHD_YES;
+ }
+ res = TMH_PARSE_post_json (connection,
+ &pc->json_parse_context,
+ upload_data,
+ upload_data_size,
+ &root);
+ if (GNUNET_SYSERR == res)
+ {
+ GNUNET_break (0);
+ return TMH_RESPONSE_reply_external_error (connection,
+ "failed to parse JSON body");
+ }
+ if ((GNUNET_NO == res) || (NULL == root))
+ return MHD_YES; /* the POST's body has to be further fetched */
+
+ mi = get_instance (root);
+
+ /* Got the JSON upload, parse it */
+ {
+ json_t *coins;
+ json_t *coin;
+ unsigned int coins_index;
+ struct TALER_MerchantSignatureP merchant_sig;
+ struct TALER_ContractPS cp;
+ const char *chosen_exchange;
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_amount ("amount", &pc->amount),
+ GNUNET_JSON_spec_json ("coins", &coins),
+ GNUNET_JSON_spec_fixed_auto ("H_contract", &pc->h_contract),
+ TALER_JSON_spec_amount ("max_fee", &pc->max_fee),
+ GNUNET_JSON_spec_fixed_auto ("merchant_sig", &merchant_sig),
+ GNUNET_JSON_spec_string ("exchange", &chosen_exchange),
+ GNUNET_JSON_spec_absolute_time ("refund_deadline", &pc->refund_deadline),
+ GNUNET_JSON_spec_absolute_time ("timestamp", &pc->timestamp),
+ GNUNET_JSON_spec_uint64 ("transaction_id", &pc->transaction_id),
+ GNUNET_JSON_spec_end()
+ };
+
+ res = TMH_PARSE_json_data (connection,
+ root,
+ spec);
+ if (GNUNET_YES != res)
+ {
+ json_decref (root);
+ GNUNET_break (0);
+ return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ }
+ pc->mi = get_instance (root);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "/pay: picked instance %s\n",
+ pc->mi->id);
+
+ if (NULL == pc->mi)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Not able to find the specified receiver\n");
+ json_decref (root);
+ return TMH_RESPONSE_reply_external_error (connection,
+ "Unknown receiver given");
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "The receiver for this deposit is '%s', whose bank details are '%s'\n",
+ pc->mi->id,
+ json_dumps (pc->mi->j_wire, JSON_COMPACT));
+ pc->chosen_exchange = GNUNET_strdup (chosen_exchange);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Parsed JSON for /pay.\n");
+ cp.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_CONTRACT);
+ cp.purpose.size = htonl (sizeof (struct TALER_ContractPS));
+ cp.transaction_id = GNUNET_htonll (pc->transaction_id);
+ TALER_amount_hton (&cp.total_amount,
+ &pc->amount);
+ TALER_amount_hton (&cp.max_fee,
+ &pc->max_fee);
+ cp.h_contract = pc->h_contract;
+ cp.merchant_pub = pc->mi->pubkey;
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_CONTRACT,
+ &cp.purpose,
+ &merchant_sig.eddsa_sig,
+ &pc->mi->pubkey.eddsa_pub))
+ {
+ GNUNET_break (0);
+ GNUNET_JSON_parse_free (spec);
+ json_decref (root);
+ return TMH_RESPONSE_reply_external_error (connection,
+ "invalid merchant signature supplied");
+ }
+
+ /* 'wire_transfer_deadline' is optional, if it is not present,
+ generate it here; it will be timestamp plus the
+ wire_transfer_delay supplied in config file */
+ if (NULL == json_object_get (root,
+ "wire_transfer_deadline"))
+ {
+ pc->wire_transfer_deadline = GNUNET_TIME_absolute_add (pc->timestamp,
+ wire_transfer_delay);
+ if (pc->wire_transfer_deadline.abs_value_us < pc->refund_deadline.abs_value_us)
+ {
+ /* Refund value very large, delay wire transfer accordingly */
+ pc->wire_transfer_deadline = pc->refund_deadline;
+ }
+ }
+ else
+ {
+ struct GNUNET_JSON_Specification espec[] = {
+ GNUNET_JSON_spec_absolute_time ("wire_transfer_deadline",
+ &pc->wire_transfer_deadline),
+ GNUNET_JSON_spec_end()
+ };
+
+ res = TMH_PARSE_json_data (connection,
+ root,
+ espec);
+ if (GNUNET_YES != res)
+ {
+ GNUNET_JSON_parse_free (spec);
+ json_decref (root);
+ GNUNET_break (0);
+ return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ }
+ if (pc->wire_transfer_deadline.abs_value_us < pc->refund_deadline.abs_value_us)
+ {
+ GNUNET_break (0);
+ GNUNET_JSON_parse_free (spec);
+ json_decref (root);
+ return TMH_RESPONSE_reply_external_error (connection,
+ "refund deadline after wire transfer deadline");
+ }
+ }
+
+
+ pc->coins_cnt = json_array_size (coins);
+ if (0 == pc->coins_cnt)
+ {
+ GNUNET_JSON_parse_free (spec);
+ json_decref (root);
+ return TMH_RESPONSE_reply_external_error (connection,
+ "no coins given");
+ }
+ /* note: 1 coin = 1 deposit confirmation expected */
+ pc->dc = GNUNET_new_array (pc->coins_cnt,
+ struct DepositConfirmation);
+
+ /* This loop populates the array 'dc' in 'pc' */
+ json_array_foreach (coins, coins_index, coin)
+ {
+ struct DepositConfirmation *dc = &pc->dc[coins_index];
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_denomination_public_key ("denom_pub", &dc->denom),
+ TALER_JSON_spec_amount ("f" /* FIXME */, &dc->amount_with_fee),
+ 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 = TMH_PARSE_json_data (connection,
+ coin,
+ spec);
+ if (GNUNET_YES != res)
+ {
+ GNUNET_JSON_parse_free (spec);
+ json_decref (root);
+ GNUNET_break (0);
+ return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ }
+
+ {
+ char *s;
+
+ s = TALER_amount_to_string (&dc->amount_with_fee);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Coin #%i has f %s\n",
+ coins_index,
+ s);
+ GNUNET_free (s);
+ }
+
+ dc->index = coins_index;
+ dc->pc = pc;
+ }
+ GNUNET_JSON_parse_free (spec);
+ } /* end of parsing of JSON upload */
+ pc->pending = pc->coins_cnt;
+
+ /* Check if this payment attempt has already succeeded */
+ if (GNUNET_SYSERR ==
+ db->find_payments_by_id (db->cls,
+ pc->transaction_id,
+ &check_coin_paid,
+ pc))
+ {
+ GNUNET_break (0);
+ json_decref (root);
+ return TMH_RESPONSE_reply_internal_error (connection,
+ "Merchant database error");
+ }
+ if (0 == pc->pending)
+ {
+ struct MHD_Response *resp;
+ int ret;
+
+ /* Payment succeeded in the past; take short cut
+ and accept immediately */
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ resp);
+ MHD_destroy_response (resp);
+ json_decref (root);
+ return ret;
+ }
+ /* Check if transaction is already known, if not store it. */
+ if (GNUNET_SYSERR ==
+ db->find_transaction (db->cls,
+ pc->transaction_id,
+ &pc->mi->pubkey,
+ &check_transaction_exists,
+ pc))
{
GNUNET_break (0);
json_decref (root);
diff --git a/src/backend/taler-merchant-httpd_track-transaction.c b/src/backend/taler-merchant-httpd_track-transaction.c
@@ -670,6 +670,7 @@ handle_track_transaction_timeout (void *cls)
*
* @param cls closure
* @param transaction_id of the contract
+ * @param merchant's public key
* @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
@@ -680,6 +681,7 @@ handle_track_transaction_timeout (void *cls)
static void
transaction_cb (void *cls,
uint64_t transaction_id,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_wire,
@@ -865,10 +867,11 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh,
return TMH_RESPONSE_reply_bad_request (connection,
"id argument must be a number");
- ret = db->find_transaction_by_id (db->cls,
- transaction_id,
- &transaction_cb,
- tctx);
+ ret = db->find_transaction (db->cls,
+ transaction_id,
+ &tctx->mi->pubkey,
+ &transaction_cb,
+ tctx);
if (GNUNET_NO == ret)
{
return TMH_RESPONSE_reply_not_found (connection,
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
@@ -262,6 +262,7 @@ postgres_initialize (void *cls)
"find_transactions_by_date",
"SELECT"
" transaction_id"
+ ",merchant_pub"
",exchange_uri"
",h_contract"
",h_wire"
@@ -287,8 +288,9 @@ postgres_initialize (void *cls)
",total_amount_frac"
",total_amount_curr"
" FROM merchant_transactions"
- " WHERE transaction_id=$1",
- 1);
+ " WHERE transaction_id=$1"
+ " AND merchant_pub=$2",
+ 2);
PG_PREPARE (pg,
"find_deposits",
"SELECT"
@@ -589,6 +591,7 @@ postgres_find_transactions_by_date (void *cls,
}
for (i = 0; i < n; i++)
{
+ struct TALER_MerchantPublicKeyP merchant_pub;
char *exchange_uri;
struct GNUNET_HashCode h_contract;
struct GNUNET_HashCode h_wire;
@@ -601,6 +604,8 @@ postgres_find_transactions_by_date (void *cls,
&exchange_uri),
GNUNET_PQ_result_spec_uint64 ("transaction_id",
&transaction_id),
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+ &merchant_pub),
GNUNET_PQ_result_spec_auto_from_type ("h_contract",
&h_contract),
GNUNET_PQ_result_spec_auto_from_type ("h_wire",
@@ -625,6 +630,7 @@ postgres_find_transactions_by_date (void *cls,
}
cb (cb_cls,
transaction_id,
+ &merchant_pub,
exchange_uri,
&h_contract,
&h_wire,
@@ -642,21 +648,25 @@ postgres_find_transactions_by_date (void *cls,
*
* @param cls our plugin handle
* @param transaction_id the transaction id to search
+ * @param merchant_pub merchant's public key. It's AND'd with transaction_id
+ * in order to find the result.
* @param cb function to call with transaction data
* @param cb_cls closure for @a cb
* @return #GNUNET_OK if found, #GNUNET_NO if not, #GNUNET_SYSERR
* upon error
*/
static int
-postgres_find_transaction_by_id (void *cls,
- uint64_t transaction_id,
- TALER_MERCHANTDB_TransactionCallback cb,
- void *cb_cls)
+postgres_find_transaction (void *cls,
+ uint64_t transaction_id,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ TALER_MERCHANTDB_TransactionCallback cb,
+ void *cb_cls)
{
struct PostgresClosure *pg = cls;
PGresult *result;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&transaction_id),
+ GNUNET_PQ_query_param_auto_from_type (merchant_pub),
GNUNET_PQ_query_param_end
};
@@ -715,6 +725,7 @@ postgres_find_transaction_by_id (void *cls,
}
cb (cb_cls,
transaction_id,
+ merchant_pub,
exchange_uri,
&h_contract,
&h_wire,
@@ -1098,7 +1109,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->store_deposit = &postgres_store_deposit;
plugin->store_coin_to_transfer = &postgres_store_coin_to_transfer;
plugin->store_transfer_to_proof = &postgres_store_transfer_to_proof;
- plugin->find_transaction_by_id = &postgres_find_transaction_by_id;
+ plugin->find_transaction = &postgres_find_transaction;
plugin->find_transactions_by_date = &postgres_find_transactions_by_date;
plugin->find_payments_by_id = &postgres_find_payments_by_id;
plugin->find_transfers_by_id = &postgres_find_transfers_by_id;
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
@@ -136,6 +136,7 @@ static json_t *transfer_proof;
*
* @param cls closure
* @param transaction_id of the contract
+ * @param merchant_pub public key of the merchant
* @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
@@ -146,6 +147,7 @@ static json_t *transfer_proof;
static void
transaction_cb (void *cls,
uint64_t atransaction_id,
+ const struct TALER_MerchantPublicKeyP *amerchant_pub,
const char *aexchange_uri,
const struct GNUNET_HashCode *ah_contract,
const struct GNUNET_HashCode *ah_wire,
@@ -155,6 +157,9 @@ transaction_cb (void *cls,
{
#define CHECK(a) do { if (! (a)) { GNUNET_break (0); result = 3; } } while (0)
CHECK (atransaction_id == transaction_id);
+ CHECK (0 == memcmp (amerchant_pub,
+ &merchant_pub,
+ sizeof (struct TALER_MerchantPublicKeyP)));
CHECK (0 == strcmp (aexchange_uri,
EXCHANGE_URI));
CHECK (0 == memcmp (ah_contract,
@@ -176,6 +181,7 @@ transaction_cb (void *cls,
*
* @param cls closure
* @param transaction_id of the contract
+ * @param merchant_pub merchant's public key
* @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
@@ -187,6 +193,7 @@ transaction_cb (void *cls,
static void
history_cb (void *cls,
uint64_t transaction_id,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_wire,
@@ -359,10 +366,11 @@ run (void *cls)
&signkey_pub,
transfer_proof));
FAILIF (GNUNET_OK !=
- plugin->find_transaction_by_id (plugin->cls,
- transaction_id,
- &transaction_cb,
- NULL));
+ plugin->find_transaction (plugin->cls,
+ transaction_id,
+ &merchant_pub,
+ &transaction_cb,
+ NULL));
/* FIXME: put here find_transactions_by_date () */
FAILIF (1 !=
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
@@ -36,6 +36,7 @@ struct TALER_MERCHANTDB_Plugin;
*
* @param cls closure
* @param transaction_id of the contract
+ * @param merchant_pub merchant's public key
* @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
@@ -46,6 +47,7 @@ struct TALER_MERCHANTDB_Plugin;
typedef void
(*TALER_MERCHANTDB_TransactionCallback)(void *cls,
uint64_t transaction_id,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_wire,
@@ -253,15 +255,18 @@ struct TALER_MERCHANTDB_Plugin
*
* @param cls our plugin handle
* @param transaction_id the transaction id to search
+ * @param merchant_pub merchant's public key. It's AND'd with transaction_id
+ * in order to find the result.
* @param cb function to call with transaction data
* @param cb_cls closure for @a cb
* @return number of found tuples, #GNUNET_SYSERR upon error
*/
int
- (*find_transaction_by_id) (void *cls,
- uint64_t transaction_id,
- TALER_MERCHANTDB_TransactionCallback cb,
- void *cb_cls);
+ (*find_transaction) (void *cls,
+ uint64_t transaction_id,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ TALER_MERCHANTDB_TransactionCallback cb,
+ void *cb_cls);
/**