diff options
-rw-r--r-- | src/backend/taler-merchant-httpd.h | 20 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_pay.c | 104 | ||||
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 10 | ||||
-rw-r--r-- | src/include/taler_merchantdb_plugin.h | 4 |
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); }; |