summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/taler-merchant-httpd_check-payment.c49
-rw-r--r--src/backend/taler-merchant-httpd_pay.c157
-rw-r--r--src/backend/taler-merchant-httpd_proposal.c3
-rw-r--r--src/backend/taler-merchant-httpd_refund.c8
-rw-r--r--src/backend/taler-merchant-httpd_track-transaction.c54
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c154
-rw-r--r--src/backenddb/test_merchantdb.c70
-rw-r--r--src/include/taler_merchantdb_plugin.h66
8 files changed, 133 insertions, 428 deletions
diff --git a/src/backend/taler-merchant-httpd_check-payment.c b/src/backend/taler-merchant-httpd_check-payment.c
index 247f7982..8366186c 100644
--- a/src/backend/taler-merchant-httpd_check-payment.c
+++ b/src/backend/taler-merchant-httpd_check-payment.c
@@ -94,6 +94,7 @@ MH_handler_check_payment (struct TMH_RequestHandler *rh,
json_t *contract_terms;
struct GNUNET_HashCode h_contract_terms;
struct TALER_Amount refund_amount;
+ char *last_session_id;
order_id = MHD_lookup_connection_value (connection,
MHD_GET_ARGUMENT_KIND,
@@ -186,10 +187,9 @@ MH_handler_check_payment (struct TMH_RequestHandler *rh,
GNUNET_assert (NULL != order_id);
-
-
qs = db->find_contract_terms (db->cls,
&contract_terms,
+ &last_session_id,
order_id,
&mi->pubkey);
if (0 > qs)
@@ -230,6 +230,9 @@ MH_handler_check_payment (struct TMH_RequestHandler *rh,
goto do_pay;
}
+ GNUNET_assert (NULL != contract_terms);
+ GNUNET_assert (NULL != last_session_id);
+
if (GNUNET_OK !=
TALER_JSON_hash (contract_terms,
&h_contract_terms))
@@ -244,20 +247,14 @@ MH_handler_check_payment (struct TMH_RequestHandler *rh,
sizeof (struct GNUNET_HashCode));
- /* Check if transaction is already known */
+ /* Check if paid */
{
- struct GNUNET_HashCode h_xwire;
- struct GNUNET_TIME_Absolute xtimestamp;
- struct GNUNET_TIME_Absolute xrefund;
- struct TALER_Amount xtotal_amount;
+ json_t *xcontract_terms = NULL;
- qs = db->find_transaction (db->cls,
- &h_contract_terms,
- &mi->pubkey,
- &h_xwire,
- &xtimestamp,
- &xrefund,
- &xtotal_amount);
+ qs = db->find_paid_contract_terms_from_hash (db->cls,
+ &xcontract_terms,
+ &h_contract_terms,
+ &mi->pubkey);
if (0 > qs)
{
/* Always report on hard error as well to enable diagnostics */
@@ -273,10 +270,22 @@ MH_handler_check_payment (struct TMH_RequestHandler *rh,
goto do_pay;
}
GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
-
- TALER_amount_get_zero (xtotal_amount.currency, &refund_amount);
+ GNUNET_assert (NULL != xcontract_terms);
+ json_decref (xcontract_terms);
}
+ {
+ struct TALER_Amount amount;
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_amount ("amount", &amount),
+ GNUNET_JSON_spec_end ()
+ };
+ if (GNUNET_OK != GNUNET_JSON_parse (contract_terms, spec, NULL, NULL))
+ return TMH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_CHECK_PAYMENT_DB_FETCH_CONTRACT_TERMS_ERROR,
+ "Merchant database error (contract terms corrupted)");
+ TALER_amount_get_zero (amount.currency, &refund_amount);
+ }
for (unsigned int i=0;i<MAX_RETRIES;i++)
{
@@ -301,15 +310,16 @@ MH_handler_check_payment (struct TMH_RequestHandler *rh,
GNUNET_free_non_null (h_contract_terms_str);
{
- int refunded = 0 != refund_amount.value || 0 != refund_amount.fraction;
+ int refunded = (0 != refund_amount.value) || (0 != refund_amount.fraction);
int res;
res = TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
- "{s:o s:b, s:b, s:o}",
+ "{s:o s:b, s:b, s:o, s:s}",
"contract_terms", contract_terms,
"paid", 1,
"refunded", refunded,
- "refund_amount", TALER_JSON_from_amount (&refund_amount));
+ "refund_amount", TALER_JSON_from_amount (&refund_amount),
+ "last_session_id", last_session_id);
return res;
}
@@ -331,6 +341,7 @@ do_pay:
0);
GNUNET_free_non_null (h_contract_terms_str);
GNUNET_free_non_null (final_contract_url);
+ json_decref (contract_terms);
GNUNET_free (url);
return ret;
}
diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c
index 442c8364..b112edf5 100644
--- a/src/backend/taler-merchant-httpd_pay.c
+++ b/src/backend/taler-merchant-httpd_pay.c
@@ -1292,6 +1292,7 @@ parse_pay (struct MHD_Connection *connection,
const char *mode;
struct TALER_MerchantPublicKeyP merchant_pub;
int res;
+ char *last_session_id;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("mode",
&mode),
@@ -1323,6 +1324,7 @@ parse_pay (struct MHD_Connection *connection,
GNUNET_assert (NULL == pc->contract_terms);
qs = db->find_contract_terms (db->cls,
&pc->contract_terms,
+ &last_session_id,
order_id,
&merchant_pub);
if (0 > qs)
@@ -1351,6 +1353,8 @@ parse_pay (struct MHD_Connection *connection,
return GNUNET_NO;
}
+ GNUNET_free (last_session_id);
+
if (GNUNET_OK !=
TALER_JSON_hash (pc->contract_terms,
&pc->h_contract_terms))
@@ -1858,7 +1862,8 @@ begin_transaction (struct PayContext *pc)
/* Payment succeeded, commit! */
qs = db->mark_proposal_paid (db->cls,
&pc->h_contract_terms,
- &pc->mi->pubkey);
+ &pc->mi->pubkey,
+ pc->session_id);
if (0 <= qs)
qs = db->commit (db->cls);
if (0 > qs)
@@ -1885,153 +1890,9 @@ begin_transaction (struct PayContext *pc)
}
- /* Check if transaction is already known, if not store it. */
- {
- struct GNUNET_HashCode h_xwire;
- struct GNUNET_TIME_Absolute xtimestamp;
- struct GNUNET_TIME_Absolute xrefund;
- struct TALER_Amount xtotal_amount;
-
- qs = db->find_transaction (db->cls,
- &pc->h_contract_terms,
- &pc->mi->pubkey,
- &h_xwire,
- &xtimestamp,
- &xrefund,
- &xtotal_amount);
- if (0 > qs)
- {
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- {
- db->rollback (db->cls);
- begin_transaction (pc);
- return;
- }
- /* Always report on hard error as well to enable diagnostics */
- GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- db->rollback (db->cls);
- resume_pay_with_response (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TMH_RESPONSE_make_json_pack ("{s:I, s:s}",
- "code", (json_int_t) TALER_EC_PAY_DB_FETCH_TRANSACTION_ERROR,
- "hint", "Merchant database error"));
- return;
- }
-
- if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) &&
- ( (xtimestamp.abs_value_us != pc->timestamp.abs_value_us) ||
- (xrefund.abs_value_us != pc->refund_deadline.abs_value_us) ||
- (0 != memcmp (&h_xwire,
- &pc->h_wire,
- sizeof (struct GNUNET_HashCode))) ||
- (0 != TALER_amount_cmp (&xtotal_amount,
- &pc->amount) ) ) )
- {
- GNUNET_break (0);
- db->rollback (db->cls);
- resume_pay_with_response (pc,
- MHD_HTTP_BAD_REQUEST,
- TMH_RESPONSE_make_json_pack ("{s:I, s:s}",
- "code", (json_int_t) TALER_EC_PAY_DB_TRANSACTION_ID_CONFLICT,
- "hint", "Transaction ID reused with different transaction details"));
- return;
- }
- }
-
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- {
- struct GNUNET_TIME_Absolute now;
- enum GNUNET_DB_QueryStatus qs_st;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Dealing with new transaction `%s'\n",
- GNUNET_h2s (&pc->h_contract_terms));
-
- now = GNUNET_TIME_absolute_get ();
- if (now.abs_value_us > pc->pay_deadline.abs_value_us)
- {
- /* Time expired, we don't accept this payment now! */
- const char *pd_str;
-
- pd_str = GNUNET_STRINGS_absolute_time_to_string (pc->pay_deadline);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Attempt to pay coins for expired contract. Deadline: `%s'\n",
- pd_str);
- db->rollback (db->cls);
- resume_pay_with_response (pc,
- MHD_HTTP_BAD_REQUEST,
- TMH_RESPONSE_make_json_pack ("{s:I, s:s}",
- "code", (json_int_t) TALER_EC_PAY_OFFER_EXPIRED,
- "hint", "The time to pay for this contract has expired."));
- return;
- }
-
- qs_st = db->store_transaction (db->cls,
- &pc->h_contract_terms,
- &pc->mi->pubkey,
- &pc->h_wire,
- pc->timestamp,
- pc->refund_deadline,
- &pc->amount);
- /* Only retry if SOFT error occurred. Exit in case of OK or HARD failure */
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs_st)
- {
- db->rollback (db->cls);
- begin_transaction (pc);
- return;
- }
- /* Exit in case of HARD failure */
- if (GNUNET_DB_STATUS_HARD_ERROR == qs_st)
- {
- GNUNET_break (0);
- db->rollback (db->cls);
- resume_pay_with_response (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TMH_RESPONSE_make_json_pack ("{s:I, s:s}",
- "code", (json_int_t) TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR,
- "hint", "Merchant database error: hard error while storing transaction"));
- }
-
- /**
- * Break if we couldn't modify one, and only one line; this
- * includes hard errors.
- */
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs_st)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected query status %d while storing /pay transaction!\n",
- (int) qs_st);
- db->rollback (db->cls);
- resume_pay_with_response (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TMH_RESPONSE_make_json_pack ("{s:I, s:s}",
- "code", (json_int_t) TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR,
- "hint", "Merchant database error: failed to store transaction"));
- return;
- }
-
- qs = db->commit (db->cls);
- if (0 > qs)
- {
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- {
- db->rollback (db->cls);
- begin_transaction (pc);
- return;
- }
- resume_pay_with_error (pc,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_PAY_DB_STORE_PAYMENTS_ERROR,
- "Merchant database error: could not commit");
- return;
- }
- } /* end of if (GNUNET_NO == qs) */
- else
- {
- /* transaction record already existed, we made no DB changes,
- so we can just rollback */
- db->rollback (db->cls);
- }
+ /* we made no DB changes,
+ so we can just rollback */
+ db->rollback (db->cls);
/* Ok, we need to first go to the network.
Do that interaction in *tiny* transactions. */
diff --git a/src/backend/taler-merchant-httpd_proposal.c b/src/backend/taler-merchant-httpd_proposal.c
index 4026625b..64bd5e99 100644
--- a/src/backend/taler-merchant-httpd_proposal.c
+++ b/src/backend/taler-merchant-httpd_proposal.c
@@ -567,6 +567,7 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
enum GNUNET_DB_QueryStatus qs;
json_t *contract_terms;
struct MerchantInstance *mi;
+ char *last_session_id;
instance = MHD_lookup_connection_value (connection,
MHD_GET_ARGUMENT_KIND,
@@ -599,6 +600,7 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
qs = db->find_contract_terms (db->cls,
&contract_terms,
+ &last_session_id,
order_id,
&mi->pubkey);
if (0 > qs)
@@ -669,6 +671,7 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
}
GNUNET_assert (NULL != contract_terms);
+ GNUNET_free_non_null (last_session_id);
const char *stored_nonce = json_string_value (json_object_get (contract_terms, "nonce"));
diff --git a/src/backend/taler-merchant-httpd_refund.c b/src/backend/taler-merchant-httpd_refund.c
index a9f54279..8a6060c3 100644
--- a/src/backend/taler-merchant-httpd_refund.c
+++ b/src/backend/taler-merchant-httpd_refund.c
@@ -117,6 +117,7 @@ MH_handler_refund_increase (struct TMH_RequestHandler *rh,
const char *order_id;
const char *reason;
const char *merchant;
+ char *last_session_id;
struct MerchantInstance *mi;
struct GNUNET_HashCode h_contract_terms;
struct TALER_MerchantRefundConfirmationPS confirmation;
@@ -183,6 +184,7 @@ MH_handler_refund_increase (struct TMH_RequestHandler *rh,
/* Convert order id to h_contract_terms */
qs = db->find_contract_terms (db->cls,
&contract_terms,
+ &last_session_id,
order_id,
&mi->pubkey);
if (0 > qs)
@@ -206,6 +208,8 @@ MH_handler_refund_increase (struct TMH_RequestHandler *rh,
"Order id not found in database");
}
+ GNUNET_free (last_session_id);
+
if (GNUNET_OK !=
TALER_JSON_hash (contract_terms,
&h_contract_terms))
@@ -418,6 +422,7 @@ MH_handler_refund_lookup (struct TMH_RequestHandler *rh,
json_t *contract_terms;
struct MerchantInstance *mi;
enum GNUNET_DB_QueryStatus qs;
+ char *last_session_id;
instance = MHD_lookup_connection_value (connection,
MHD_GET_ARGUMENT_KIND,
@@ -459,6 +464,7 @@ MH_handler_refund_lookup (struct TMH_RequestHandler *rh,
contract_terms = NULL;
qs = db->find_contract_terms (db->cls,
&contract_terms,
+ &last_session_id,
order_id,
&mi->pubkey);
if (0 > qs)
@@ -483,6 +489,8 @@ MH_handler_refund_lookup (struct TMH_RequestHandler *rh,
"Order id not found in database");
}
+ GNUNET_free (last_session_id);
+
if (GNUNET_OK !=
TALER_JSON_hash (contract_terms,
&h_contract_terms))
diff --git a/src/backend/taler-merchant-httpd_track-transaction.c b/src/backend/taler-merchant-httpd_track-transaction.c
index e59e89ae..99bd33b4 100644
--- a/src/backend/taler-merchant-httpd_track-transaction.c
+++ b/src/backend/taler-merchant-httpd_track-transaction.c
@@ -1022,6 +1022,7 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh,
enum GNUNET_DB_QueryStatus qs;
struct GNUNET_HashCode h_instance;
struct json_t *contract_terms;
+ char *last_session_id;
if (NULL == *connection_cls)
{
@@ -1096,6 +1097,7 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh,
qs = db->find_contract_terms (db->cls,
&contract_terms,
+ &last_session_id,
order_id,
&tctx->mi->pubkey);
if (0 > qs)
@@ -1109,6 +1111,9 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh,
return TMH_RESPONSE_reply_not_found (connection,
TALER_EC_PROPOSAL_LOOKUP_NOT_FOUND,
"Given order_id doesn't map to any proposal");
+
+ GNUNET_free (last_session_id);
+
if (GNUNET_OK !=
TALER_JSON_hash (contract_terms,
&tctx->h_contract_terms))
@@ -1118,33 +1123,34 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh,
TALER_EC_INTERNAL_LOGIC_ERROR,
"Failed to hash contract terms");
}
- json_decref (contract_terms);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Trying to track h_contract_terms '%s'\n",
- GNUNET_h2s (&tctx->h_contract_terms));
- qs = db->find_transaction (db->cls,
- &tctx->h_contract_terms,
- &tctx->mi->pubkey,
- &tctx->h_wire,
- &tctx->timestamp,
- &tctx->refund_deadline,
- &tctx->total_amount);
- if (0 > qs)
{
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
- return TMH_RESPONSE_reply_internal_error (connection,
- TALER_EC_TRACK_TRANSACTION_DB_FETCH_TRANSACTION_ERROR,
- "Database error finding transaction");
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "h_contract_terms not found\n");
- return TMH_RESPONSE_reply_not_found (connection,
- TALER_EC_TRACK_TRANSACTION_TRANSACTION_UNKNOWN,
- "h_contract_terms is unknown");
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_absolute_time ("refund_deadline",
+ &tctx->refund_deadline),
+ GNUNET_JSON_spec_absolute_time ("timestamp",
+ &tctx->timestamp),
+ TALER_JSON_spec_amount ("amount",
+ &tctx->total_amount),
+ GNUNET_JSON_spec_fixed_auto ("H_wire",
+ &tctx->h_wire),
+ GNUNET_JSON_spec_end()
+ };
+
+ if (GNUNET_YES != GNUNET_JSON_parse (contract_terms,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break (0);
+ GNUNET_JSON_parse_free (spec);
+ json_decref (contract_terms);
+ return TMH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_INTERNAL_LOGIC_ERROR,
+ "Failed to parse contract terms from DB");
+ }
+ json_decref (contract_terms);
}
+
tctx->qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
qs = db->find_payments (db->cls,
&tctx->h_contract_terms,
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index a160ae0e..881f682d 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -115,22 +115,10 @@ postgres_initialize (void *cls)
",timestamp INT8 NOT NULL"
",row_id BIGSERIAL UNIQUE"
",paid boolean DEFAULT FALSE NOT NULL"
+ ",last_session_id VARCHAR DEFAULT '' NOT NULL"
",PRIMARY KEY (order_id, merchant_pub)"
",UNIQUE (h_contract_terms, merchant_pub)"
");"),
- /* Contracts that were paid */
- GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS merchant_transactions ("
- " h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)"
- ",merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)"
- ",h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64)"
- ",timestamp INT8 NOT NULL"
- ",refund_deadline INT8 NOT NULL"
- ",total_amount_val INT8 NOT NULL"
- ",total_amount_frac INT4 NOT NULL"
- ",total_amount_curr VARCHAR(" TALER_CURRENCY_LEN_STR ") NOT NULL"
- ",PRIMARY KEY (h_contract_terms, merchant_pub)"
- ",FOREIGN KEY (h_contract_terms, merchant_pub) REFERENCES merchant_contract_terms (h_contract_terms, merchant_pub)"
- ");"),
/* Table with the proofs for each coin we deposited at the exchange */
GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS merchant_deposits ("
" h_contract_terms BYTEA NOT NULL"
@@ -152,7 +140,7 @@ postgres_initialize (void *cls)
",signkey_pub BYTEA NOT NULL CHECK (LENGTH(signkey_pub)=32)"
",exchange_proof BYTEA NOT NULL"
",PRIMARY KEY (h_contract_terms, coin_pub)"
- ",FOREIGN KEY (h_contract_terms, merchant_pub) REFERENCES merchant_transactions (h_contract_terms, merchant_pub)"
+ ",FOREIGN KEY (h_contract_terms, merchant_pub) REFERENCES merchant_contract_terms (h_contract_terms, merchant_pub)"
");"),
GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS merchant_proofs ("
" exchange_url VARCHAR NOT NULL"
@@ -248,19 +236,6 @@ postgres_initialize (void *cls)
GNUNET_PQ_EXECUTE_STATEMENT_END
};
struct GNUNET_PQ_PreparedStatement ps[] = {
- GNUNET_PQ_make_prepare ("insert_transaction",
- "INSERT INTO merchant_transactions"
- "(h_contract_terms"
- ",merchant_pub"
- ",h_wire"
- ",timestamp"
- ",refund_deadline"
- ",total_amount_val"
- ",total_amount_frac"
- ",total_amount_curr"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8)",
- 8),
GNUNET_PQ_make_prepare ("insert_deposit",
"INSERT INTO merchant_deposits"
"(h_contract_terms"
@@ -335,7 +310,8 @@ postgres_initialize (void *cls)
4),
GNUNET_PQ_make_prepare ("mark_proposal_paid",
"UPDATE merchant_contract_terms SET"
- " paid=TRUE WHERE h_contract_terms=$1"
+ " paid=TRUE, last_session_id=$3"
+ " WHERE h_contract_terms=$1"
" AND merchant_pub=$2",
2),
GNUNET_PQ_make_prepare ("insert_wire_fee",
@@ -411,6 +387,7 @@ postgres_initialize (void *cls)
GNUNET_PQ_make_prepare ("find_contract_terms",
"SELECT"
" contract_terms"
+ ",last_session_id"
" FROM merchant_contract_terms"
" WHERE"
" order_id=$1"
@@ -480,18 +457,6 @@ postgres_initialize (void *cls)
" ORDER BY row_id DESC, timestamp DESC"
" LIMIT $4",
4),
- GNUNET_PQ_make_prepare ("find_transaction",
- "SELECT"
- " h_wire"
- ",timestamp"
- ",refund_deadline"
- ",total_amount_val"
- ",total_amount_frac"
- ",total_amount_curr"
- " FROM merchant_transactions"
- " WHERE h_contract_terms=$1"
- " AND merchant_pub=$2",
- 2),
GNUNET_PQ_make_prepare ("find_deposits",
"SELECT"
" coin_pub"
@@ -884,12 +849,14 @@ postgres_find_paid_contract_terms_from_hash (void *cls,
*
* @param cls closure
* @param[out] contract_terms where to store the retrieved contract terms
+ * @param[out] last_session_id where to store the result
* @param order id order id used to perform the lookup
* @return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_find_contract_terms (void *cls,
json_t **contract_terms,
+ char **last_session_id,
const char *order_id,
const struct TALER_MerchantPublicKeyP *merchant_pub)
{
@@ -903,6 +870,8 @@ postgres_find_contract_terms (void *cls,
struct GNUNET_PQ_ResultSpec rs[] = {
TALER_PQ_result_spec_json ("contract_terms",
contract_terms),
+ GNUNET_PQ_result_spec_string ("last_session_id",
+ last_session_id),
GNUNET_PQ_result_spec_end
};
@@ -1057,17 +1026,21 @@ postgres_insert_order (void *cls,
* @param cls closure
* @param h_contract_terms hash of the contract that is now paid
* @param merchant_pub merchant's public key
+ * @param last_session_id session id used for the payment, NULL
+ * if payment was not session-bound
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
postgres_mark_proposal_paid (void *cls,
const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_MerchantPublicKeyP *merchant_pub)
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const char *last_session_id)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
GNUNET_PQ_query_param_auto_from_type (merchant_pub),
+ GNUNET_PQ_query_param_string ((last_session_id == NULL) ? "" : last_session_id),
GNUNET_PQ_query_param_end
};
@@ -1082,51 +1055,6 @@ postgres_mark_proposal_paid (void *cls,
/**
- * Insert transaction data into the database.
- *
- * @param cls closure
- * @param h_contract_terms hashcode of the proposal data associated with the
- * transaction being stored
- * @param merchant_pub merchant's public key
- * @param exchange_url URL of the exchange
- * @param h_wire hash of our wire details
- * @param timestamp time of the confirmation
- * @param refund refund deadline
- * @param total_amount total amount we receive for the contract after fees
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_store_transaction (void *cls,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_wire,
- struct GNUNET_TIME_Absolute timestamp,
- struct GNUNET_TIME_Absolute refund,
- const struct TALER_Amount *total_amount)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (h_wire),
- GNUNET_PQ_query_param_absolute_time (&timestamp),
- GNUNET_PQ_query_param_absolute_time (&refund),
- TALER_PQ_query_param_amount (total_amount),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Storing transaction with h_contract_terms '%s', merchant_pub '%s'.\n",
- GNUNET_h2s (h_contract_terms),
- TALER_B2S (merchant_pub));
- check_connection (pg);
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_transaction",
- params);
-}
-
-
-/**
* Insert payment confirmation from the exchange into the database.
*
* @param cls closure
@@ -1608,58 +1536,6 @@ postgres_find_contract_terms_by_date (void *cls,
/**
- * Find information about a transaction.
- *
- * @param cls our plugin handle
- * @param h_contract_terms value used to perform the lookup
- * @param merchant_pub merchant's public key
- * @param[out] h_wire set to hash of wire details
- * @param[out] timestamp set to timestamp
- * @param[out] refund_deadline set to refund deadline
- * @param[out] total_amount set to total amount
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_find_transaction (void *cls,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- struct GNUNET_HashCode *h_wire,
- struct GNUNET_TIME_Absolute *timestamp,
- struct GNUNET_TIME_Absolute *refund_deadline,
- struct TALER_Amount *total_amount)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("h_wire",
- h_wire),
- GNUNET_PQ_result_spec_absolute_time ("timestamp",
- timestamp),
- GNUNET_PQ_result_spec_absolute_time ("refund_deadline",
- refund_deadline),
- TALER_PQ_result_spec_amount ("total_amount",
- total_amount),
- GNUNET_PQ_result_spec_end
- };
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Finding transaction for h_contract_terms '%s', merchant_pub: '%s'.\n",
- GNUNET_h2s (h_contract_terms),
- TALER_B2S (merchant_pub));
-
- check_connection (pg);
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "find_transaction",
- params,
- rs);
-}
-
-
-/**
* Closure for #find_payments_cb().
*/
struct FindPaymentsContext
@@ -3548,12 +3424,10 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->cls = pg;
plugin->drop_tables = &postgres_drop_tables;
plugin->initialize = &postgres_initialize;
- plugin->store_transaction = &postgres_store_transaction;
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->store_wire_fee_by_exchange = &postgres_store_wire_fee_by_exchange;
- plugin->find_transaction = &postgres_find_transaction;
plugin->find_payments_by_hash_and_coin = &postgres_find_payments_by_hash_and_coin;
plugin->find_payments = &postgres_find_payments;
plugin->find_transfers_by_hash = &postgres_find_transfers_by_hash;
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index cbf51b31..33a05ddb 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -846,14 +846,40 @@ run (void *cls)
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->mark_proposal_paid (plugin->cls,
&h_contract_terms,
- &merchant_pub));
+ &merchant_pub,
+ "my-session-123"));
+ {
+ char *last_session_id;
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+ plugin->find_contract_terms (plugin->cls,
+ &out,
+ &last_session_id,
+ order_id,
+ &merchant_pub));
+ FAILIF (0 != strcmp (last_session_id, "my-session-123"));
+ GNUNET_free (last_session_id);
+ }
+
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
- plugin->find_contract_terms (plugin->cls,
- &out,
- order_id,
- &merchant_pub));
+ plugin->mark_proposal_paid (plugin->cls,
+ &h_contract_terms,
+ &merchant_pub,
+ NULL));
+
+
+ {
+ char *last_session_id;
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+ plugin->find_contract_terms (plugin->cls,
+ &out,
+ &last_session_id,
+ order_id,
+ &merchant_pub));
+ FAILIF (0 != strcmp (last_session_id, ""));
+ GNUNET_free (last_session_id);
+ }
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->find_contract_terms_history (plugin->cls,
@@ -900,7 +926,8 @@ run (void *cls)
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->mark_proposal_paid (plugin->cls,
&h_contract_terms_future,
- &merchant_pub));
+ &merchant_pub,
+ "hello"));
FAILIF (2 !=
plugin->find_contract_terms_by_date_and_range (plugin->cls,
fake_now,
@@ -920,14 +947,6 @@ run (void *cls)
NULL));
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
- plugin->store_transaction (plugin->cls,
- &h_contract_terms,
- &merchant_pub,
- &h_wire,
- timestamp,
- refund_deadline,
- &amount_with_fee));
- FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->store_deposit (plugin->cls,
&h_contract_terms,
&merchant_pub,
@@ -951,29 +970,6 @@ run (void *cls)
GNUNET_TIME_UNIT_ZERO_ABS,
&signkey_pub,
transfer_proof));
- {
- struct GNUNET_HashCode ah_wire;
- struct GNUNET_TIME_Absolute atimestamp;
- struct GNUNET_TIME_Absolute arefund_deadline;
- struct TALER_Amount atotal_amount;
-
- FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
- plugin->find_transaction (plugin->cls,
- &h_contract_terms,
- &merchant_pub,
- &ah_wire,
- &atimestamp,
- &arefund_deadline,
- &atotal_amount));
- FAILIF (0 != memcmp (&ah_wire,
- &h_wire,
- sizeof (struct GNUNET_HashCode)));
- FAILIF (atimestamp.abs_value_us != timestamp.abs_value_us);
- FAILIF (arefund_deadline.abs_value_us != refund_deadline.abs_value_us);
- FAILIF (0 != TALER_amount_cmp (&atotal_amount,
- &amount_with_fee));
- }
-
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->find_payments (plugin->cls,
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index 1005e6c5..6f497b00 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -233,18 +233,22 @@ struct TALER_MERCHANTDB_Plugin
* @param cls closure
* @param h_contract_terms hash of the contract that is now paid
* @param merchant_pub merchant's public key
+ * @param last_session_id session id used for the payment, NULL
+ * if payment was not session-bound
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*mark_proposal_paid) (void *cls,
const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_MerchantPublicKeyP *merchant_pub);
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const char *last_session_id);
/**
* Retrieve proposal data given its order ID.
*
* @param cls closure
* @param[out] contract_terms where to store the result
+ * @param[out] last_session_id where to store the result
* @param order_id order_id used to lookup.
* @param merchant_pub instance's public key.
* @return transaction status
@@ -252,6 +256,7 @@ struct TALER_MERCHANTDB_Plugin
enum GNUNET_DB_QueryStatus
(*find_contract_terms) (void *cls,
json_t **contract_terms,
+ char **last_session_id,
const char *order_id,
const struct TALER_MerchantPublicKeyP *merchant_pub);
@@ -373,28 +378,6 @@ struct TALER_MERCHANTDB_Plugin
/**
- * Insert transaction data into the database.
- *
- * @param cls closure
- * @param h_contract_terms proposal data's hashcode
- * @param merchant_pub merchant's public key
- * @param h_wire hash of our wire details
- * @param timestamp time of the confirmation
- * @param refund refund deadline
- * @param total_amount total amount we receive for the contract after fees
- * @return transaction status
- */
- enum GNUNET_DB_QueryStatus
- (*store_transaction) (void *cls,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_wire,
- struct GNUNET_TIME_Absolute timestamp,
- struct GNUNET_TIME_Absolute refund,
- const struct TALER_Amount *total_amount);
-
-
- /**
* Insert payment confirmation from the exchange into the database.
*
* @param cls closure
@@ -487,43 +470,6 @@ struct TALER_MERCHANTDB_Plugin
const struct TALER_MasterSignatureP *exchange_sig);
- /**
- * Find information about a transaction.
- *
- * @param cls our plugin handle
- * @param date limit to transactions' age
- * @param cb function to call with transaction data
- * @param cb_cls closure for @a cb
- * @return transaction status
- */
- enum GNUNET_DB_QueryStatus
- (*find_transactions_by_date) (void *cls,
- struct GNUNET_TIME_Absolute date,
- TALER_MERCHANTDB_TransactionCallback cb,
- void *cb_cls);
-
-
- /**
- * Find information about a transaction.
- *
- * @param cls our plugin handle
- * @param h_contract_terms proposal data's hashcode
- * @param merchant_pub merchant's public key.
- * @param[out] h_wire set to hash of wire details
- * @param[out] timestamp set to timestamp
- * @param[out] refund_deadline set to refund deadline
- * @param[out] total_amount set to total amount
- * @return transaction status
- */
- enum GNUNET_DB_QueryStatus
- (*find_transaction) (void *cls,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- struct GNUNET_HashCode *h_wire,
- struct GNUNET_TIME_Absolute *timestamp,
- struct GNUNET_TIME_Absolute *refund_deadline,
- struct TALER_Amount *total_amount);
-
/**
* Lookup information about coin payments by proposal data's hashcode.