diff options
author | Marcello Stanisci <marcello.stanisci@inria.fr> | 2017-07-25 12:05:38 +0200 |
---|---|---|
committer | Marcello Stanisci <marcello.stanisci@inria.fr> | 2017-07-25 12:05:38 +0200 |
commit | dbadf348ce8c069e8362b9e9c9292d8f351b0aba (patch) | |
tree | c782cb89ee848ffd1a7101ade77b520503356264 | |
parent | 2d3fcf511582a69f4ee18a671b6cb2fba2dbdff6 (diff) | |
download | merchant-dbadf348ce8c069e8362b9e9c9292d8f351b0aba.tar.gz merchant-dbadf348ce8c069e8362b9e9c9292d8f351b0aba.tar.bz2 merchant-dbadf348ce8c069e8362b9e9c9292d8f351b0aba.zip |
moving proposal mark-as-paid in the right place
(= after exchange confirmation of all deposited coins)
-rw-r--r-- | src/backend/taler-merchant-httpd_pay.c | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c index b00f8e45..0c93c166 100644 --- a/src/backend/taler-merchant-httpd_pay.c +++ b/src/backend/taler-merchant-httpd_pay.c @@ -464,6 +464,7 @@ deposit_cb (void *cls, http_status); /* Transaction failed; stop all other ongoing deposits */ abort_deposit (pc); + db->rollback (db->cls); if (NULL == proof) { @@ -520,6 +521,7 @@ deposit_cb (void *cls, GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); /* internal error */ abort_deposit (pc); + db->rollback (db->cls); /* Forward error including 'proof' for the body */ resume_pay_with_response (pc, MHD_HTTP_INTERNAL_SERVER_ERROR, @@ -530,6 +532,22 @@ deposit_cb (void *cls, if (0 != pc->pending) return; /* still more to do */ + + qs = db->mark_proposal_paid (db->cls, + &pc->h_contract_terms, + &pc->mi->pubkey); + if (0 > qs) + resume_pay_with_response (pc, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TMH_RESPONSE_make_internal_error (TALER_EC_PAY_DB_STORE_PAYMENTS_ERROR, + "Merchant database error: could not mark proposal as 'paid'")); + qs = db->commit (db->cls); + if (0 > qs) + resume_pay_with_response (pc, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TMH_RESPONSE_make_internal_error (TALER_EC_PAY_DB_STORE_PAYMENTS_ERROR, + "Merchant database error: could not commit")); + resume_pay_with_response (pc, MHD_HTTP_OK, sign_success_response (pc)); @@ -850,6 +868,17 @@ process_pay_with_exchange (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Exchange and fee structure OK. Initiating deposit operation for coins\n"); + if (GNUNET_OK != db->start (db->cls)) + { + GNUNET_break (0); + resume_pay_with_response (pc, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TMH_RESPONSE_make_json_pack ("{s:s, s:I}", + "hint", "Merchant database error: could not start transaction", + "code", (json_int_t) TALER_EC_PAY_DB_STORE_PAYMENTS_ERROR)); + return; + } + /* Initiate /deposit operation for all coins */ for (unsigned int i=0;i<pc->coins_cnt;i++) { @@ -882,6 +911,7 @@ process_pay_with_exchange (void *cls, /* Signature was invalid. If the exchange was unavailable, * we'd get that information in the callback. */ GNUNET_break_op (0); + db->rollback (db->cls); resume_pay_with_response (pc, MHD_HTTP_UNAUTHORIZED, TMH_RESPONSE_make_json_pack ("{s:s, s:I, s:i}", @@ -1318,7 +1348,6 @@ handler_pay_json (struct MHD_Connection *connection, int ret; enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs_st; - enum GNUNET_DB_QueryStatus qs_mp; ret = parse_pay (connection, root, @@ -1409,15 +1438,6 @@ handler_pay_json (struct MHD_Connection *connection, for (unsigned int i=0;i<MAX_RETRIES;i++) { - if (GNUNET_OK != db->start (db->cls)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not start transaction to store successful payment\n"); - return TMH_RESPONSE_reply_internal_error (connection, - TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR, - "Merchant database error"); - } - qs_st = db->store_transaction (db->cls, &pc->h_contract_terms, &pc->mi->pubkey, @@ -1427,13 +1447,8 @@ handler_pay_json (struct MHD_Connection *connection, pc->refund_deadline, &pc->amount); - qs_mp = db->mark_proposal_paid (db->cls, - &pc->h_contract_terms, - &pc->mi->pubkey); - /* Only retry if SOFT error occurred. Exit in case of OK or HARD failure */ - if ( (GNUNET_DB_STATUS_SOFT_ERROR == qs_st) && - (GNUNET_DB_STATUS_SOFT_ERROR == qs_mp) ) + if (GNUNET_DB_STATUS_SOFT_ERROR == qs_st) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Rolling back db transaction\n"); @@ -1441,26 +1456,34 @@ handler_pay_json (struct MHD_Connection *connection, } break; + + /* Only retry if SOFT error occurred. Exit in case of OK or HARD failure */ + if (GNUNET_DB_STATUS_HARD_ERROR == qs_st) + { + GNUNET_break (0); + db->rollback (db->cls); + return TMH_RESPONSE_reply_internal_error (connection, + TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR, + "Merchant database error: hard error while storing transaction"); + } + + continue; } - /* Break if AT LEAST one error occurred */ - if (2 != (qs_st + qs_mp)) + /** + * Break if we couldn't modify one, and only one line; this + * includes hard errors. + */ + if (1 != qs_st) { - db->rollback (db->cls); - /* Special report if retries insufficient */ - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs_st); - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs_mp); - /* Always report on hard error as well to enable diagnostics */ - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs_st); - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs_mp); - + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "No DB errors occurred, but more than one line was modified!\n"); return TMH_RESPONSE_reply_internal_error (connection, TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR, - "Merchant database error"); + "Merchant database error: badly stored transaction"); } - } - db->commit (db->cls); + } MHD_suspend_connection (connection); pc->suspended = GNUNET_YES; |