summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/taler-merchant-httpd.h20
-rw-r--r--src/backend/taler-merchant-httpd_pay.c104
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c10
-rw-r--r--src/include/taler_merchantdb_plugin.h4
4 files changed, 107 insertions, 31 deletions
diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h
index efecc467..25242617 100644
--- a/src/backend/taler-merchant-httpd.h
+++ b/src/backend/taler-merchant-httpd.h
@@ -136,19 +136,29 @@ extern json_t *j_wire;
*/
extern struct GNUNET_HashCode h_wire;
-
+/**
+ * Our private key (for the merchant to sign contracts).
+ */
extern struct GNUNET_CRYPTO_EddsaPrivateKey *privkey;
+/**
+ * Our public key, corresponds to #privkey.
+ */
extern struct TALER_MerchantPublicKeyP pubkey;
-
+/**
+ * Handle to the database backend.
+ */
extern struct TALER_MERCHANTDB_Plugin *db;
-
-
+/**
+ * If the frontend does NOT specify an execution date, how long should
+ * we tell the mint to wait to aggregate transactions before
+ * executing? This delay is added to the current time when we
+ * generate the advisory execution time for the mint.
+ */
extern struct GNUNET_TIME_Relative edate_delay;
-
/**
* Kick MHD to run now, to be called after MHD_resume_connection().
* Basically, we need to explicitly resume MHD's event loop whenever
diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c
index f6423fce..ee2e6bee 100644
--- a/src/backend/taler-merchant-httpd_pay.c
+++ b/src/backend/taler-merchant-httpd_pay.c
@@ -17,6 +17,7 @@
* @file backend/taler-merchant-httpd_pay.c
* @brief HTTP serving layer mainly intended to communicate with the frontend
* @author Marcello Stanisci
+ * @author Christian Grothoff
*/
#include "platform.h"
#include <jansson.h>
@@ -67,6 +68,11 @@ struct MERCHANT_DepositConfirmation
struct TALER_Amount percoin_amount;
/**
+ * Amount this coin contributes to the total purchase price.
+ */
+ struct TALER_Amount amount_without_fee;
+
+ /**
* Public key of the coin.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
@@ -112,6 +118,12 @@ struct PayContext
struct MHD_Connection *connection;
/**
+ * Handle to the mint that we are doing the payment with.
+ * (initially NULL while @e fo is trying to find a mint).
+ */
+ struct TALER_MINT_Handle *mh;
+
+ /**
* Handle for operation to lookup /keys (and auditors) from
* the mint used for this transaction; NULL if no operation is
* pending.
@@ -219,6 +231,29 @@ resume_pay_with_response (struct PayContext *pc,
/**
+ * Abort all pending /deposit operations.
+ *
+ * @param pc pay context to abort
+ */
+static void
+abort_deposit (struct PayContext *pc)
+{
+ unsigned int i;
+
+ for (i=0;i<pc->coins_cnt;i++)
+ {
+ struct MERCHANT_DepositConfirmation *dci = &pc->dc[i];
+
+ if (NULL != dci->dh)
+ {
+ TALER_MINT_deposit_cancel (dci->dh);
+ dci->dh = NULL;
+ }
+ }
+}
+
+
+/**
* Callback to handle a deposit permission's response.
*
* @param cls a `struct MERCHANT_DepositConfirmation` (i.e. a pointer
@@ -245,26 +280,34 @@ deposit_cb (void *cls,
pc->pending--;
if (MHD_HTTP_OK != http_status)
{
- unsigned int i;
-
/* Transaction failed; stop all other ongoing deposits */
- for (i=0;i<pc->coins_cnt;i++)
- {
- struct MERCHANT_DepositConfirmation *dci = &pc->dc[i];
-
- if (NULL != dci->dh)
- {
- TALER_MINT_deposit_cancel (dci->dh);
- dci->dh = NULL;
- }
- }
+ abort_deposit (pc);
/* Forward error including 'proof' for the body */
resume_pay_with_response (pc,
http_status,
TMH_RESPONSE_make_json (proof));
return;
}
- /* FIXME: store result to DB here somewhere! */
+ /* store result to DB */
+ if (GNUNET_OK !=
+ db->store_payment (db->cls,
+ &pc->h_contract,
+ &h_wire,
+ pc->transaction_id,
+ pc->timestamp,
+ pc->refund_deadline,
+ &dc->amount_without_fee,
+ &dc->coin_pub,
+ proof))
+ {
+ /* internal error */
+ abort_deposit (pc);
+ /* Forward error including 'proof' for the body */
+ resume_pay_with_response (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TMH_RESPONSE_make_internal_error ("Merchant database error"));
+ return;
+ }
if (0 != pc->pending)
return; /* still more to do */
resume_pay_with_response (pc,
@@ -351,6 +394,7 @@ process_pay_with_mint (void *cls,
TMH_RESPONSE_make_external_error ("mint not supported"));
return;
}
+ pc->mh = mh;
keys = TALER_MINT_get_keys (mh);
if (NULL == keys)
@@ -398,12 +442,34 @@ process_pay_with_mint (void *cls,
}
else
{
- TALER_amount_add (&acc_fee,
- &denom_details->fee_deposit,
- &acc_fee);
- TALER_amount_add (&acc_amount,
- &dc->percoin_amount,
- &acc_amount);
+ if ( (GNUNET_OK !=
+ TALER_amount_add (&acc_fee,
+ &denom_details->fee_deposit,
+ &acc_fee)) ||
+ (GNUNET_OK !=
+ TALER_amount_add (&acc_amount,
+ &dc->percoin_amount,
+ &acc_amount)) )
+ {
+ GNUNET_break_op (0);
+ /* Overflow in these amounts? Very strange. */
+ resume_pay_with_response (pc,
+ MHD_HTTP_BAD_REQUEST,
+ TMH_RESPONSE_make_internal_error ("Overflow adding up amounts"));
+ return;
+ }
+ }
+ if (GNUNET_SYSERR ==
+ TALER_amount_subtract (&dc->amount_without_fee,
+ &dc->percoin_amount,
+ &denom_details->fee_deposit))
+ {
+ GNUNET_break_op (0);
+ /* fee higher than residual coin value, makes no sense. */
+ resume_pay_with_response (pc,
+ MHD_HTTP_BAD_REQUEST,
+ TMH_RESPONSE_make_internal_error ("Fee higher than coin value"));
+ return;
}
}
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 92f57bbc..2b4f41ec 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -77,7 +77,7 @@ postgres_initialize (void *cls,
"amount_without_fee_frac INT4 NOT NULL,"
"amount_without_fee_curr VARCHAR(" TALER_CURRENCY_LEN_STR ") NOT NULL,"
"coin_pub BYTEA NOT NULL,"
- "mint_sig BYTEA NOT NULL);",
+ "mint_proof BYTEA NOT NULL);",
tmp_str);
ret = GNUNET_POSTGRES_exec (pg->conn,
sql);
@@ -96,7 +96,7 @@ postgres_initialize (void *cls,
",amount_without_fee_frac"
",amount_without_fee_curr"
",coin_pub"
- ",mint_sig) VALUES "
+ ",mint_proof) VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
10, NULL))) ||
(PGRES_COMMAND_OK != (status = PQresultStatus(res))) )
@@ -124,7 +124,7 @@ postgres_initialize (void *cls,
* @param refund refund deadline
* @param amount_without_fee amount the mint will deposit
* @param coin_pub public key of the coin
- * @param merchant_pub our public key
+ * @param mint_proof proof from the mint that coin was accepted
* @return #GNUNET_OK on success, #GNUNET_SYSERR upon error
*/
static int
@@ -136,7 +136,7 @@ postgres_store_payment (void *cls,
struct GNUNET_TIME_Absolute refund,
const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_MintSignatureP *mint_sig)
+ json_t *mint_proof)
{
struct PostgresClosure *pg = cls;
PGresult *res;
@@ -150,7 +150,7 @@ postgres_store_payment (void *cls,
TALER_PQ_query_param_absolute_time (&refund),
TALER_PQ_query_param_amount (amount_without_fee),
TALER_PQ_query_param_auto_from_type (coin_pub),
- TALER_PQ_query_param_auto_from_type (mint_sig),
+ TALER_PQ_query_param_json (mint_proof),
TALER_PQ_query_param_end
};
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index b6e378c6..f237b8d7 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -69,7 +69,7 @@ struct TALER_MERCHANTDB_Plugin
* @param refund refund deadline
* @param amount_without_fee amount the mint will deposit
* @param coin_pub public key of the coin
- * @param merchant_pub our public key
+ * @param mint_proof proof from mint that coin was accepted
* @return #GNUNET_OK on success, #GNUNET_SYSERR upon error
*/
int
@@ -81,7 +81,7 @@ struct TALER_MERCHANTDB_Plugin
struct GNUNET_TIME_Absolute refund,
const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_MintSignatureP *mint_sig);
+ json_t *mint_proof);
};