diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-08-27 02:01:12 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-08-27 02:01:12 +0200 |
commit | 4cfe3ac7beb8fa8de59156e9ff97730b396c66ab (patch) | |
tree | d119a5c0bdd51b320c5e65afca1bb8aeab9cc242 /src/backenddb/plugin_merchantdb_postgres.c | |
parent | f0e666563588c4858417b776105d8fc3e17f8840 (diff) | |
download | merchant-4cfe3ac7beb8fa8de59156e9ff97730b396c66ab.tar.gz merchant-4cfe3ac7beb8fa8de59156e9ff97730b396c66ab.tar.bz2 merchant-4cfe3ac7beb8fa8de59156e9ff97730b396c66ab.zip |
fix refund generation (hopefully)
Diffstat (limited to 'src/backenddb/plugin_merchantdb_postgres.c')
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 125 |
1 files changed, 64 insertions, 61 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index 443d5276..c19602a5 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -2104,22 +2104,23 @@ process_deposits_for_refund_cb (void *cls, unsigned int num_results) { struct InsertRefundContext *ctx = cls; - struct TALER_Amount previous_refund; + struct TALER_Amount current_refund; + struct TALER_Amount deposit_refund[num_results]; + struct TALER_CoinSpendPublicKeyP deposit_coin_pubs[num_results]; + struct TALER_Amount deposit_amount_with_fee[num_results]; + struct TALER_Amount deposit_refund_fee[num_results]; TALER_amount_get_zero (ctx->refund->currency, - &previous_refund); + ¤t_refund); - for (unsigned int i=0;i<num_results;i++) + /* Pass 1: Collect amount of existing refunds into current_refund. + * Also store existing refunded amount for each deposit in deposit_refund. */ + + for (unsigned int i=0; i<num_results; i++) { struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_Amount amount_with_fee; struct TALER_Amount refund_fee; - struct FindRefundContext ictx; - enum GNUNET_DB_QueryStatus ires; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&coin_pub), - GNUNET_PQ_query_param_end - }; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("coin_pub", &coin_pub), @@ -2129,9 +2130,6 @@ process_deposits_for_refund_cb (void *cls, &refund_fee), GNUNET_PQ_result_spec_end }; - struct TALER_Amount left; - struct TALER_Amount remaining_refund; - const struct TALER_Amount *increment; if (GNUNET_OK != GNUNET_PQ_extract_result (result, @@ -2143,11 +2141,14 @@ process_deposits_for_refund_cb (void *cls, return; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Processing refund for coin %s, deposit value was %s\n", - TALER_B2S (&coin_pub), - TALER_amount2s (&amount_with_fee)); - TALER_amount_get_zero (amount_with_fee.currency, + struct FindRefundContext ictx; + enum GNUNET_DB_QueryStatus ires; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&coin_pub), + GNUNET_PQ_query_param_end + }; + + TALER_amount_get_zero (ctx->refund->currency, &ictx.refunded_amount); ictx.err = GNUNET_OK; /* no error so far */ ires = GNUNET_PQ_eval_prepared_multi_select (ctx->pg->conn, @@ -2167,39 +2168,47 @@ process_deposits_for_refund_cb (void *cls, ctx->qs = GNUNET_DB_STATUS_SOFT_ERROR; return; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Processing refund for coin %s total up to %s\n", - TALER_B2S (&coin_pub), - TALER_amount2s (&ictx.refunded_amount)); - - /** - * Sum coin's contribution for refunding to the total (previously - * awarded) refund. If this value will exceed the current awarded - * refund, we'll return #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS. - */ + deposit_refund[i] = ictx.refunded_amount; + deposit_amount_with_fee[i] = amount_with_fee; + deposit_coin_pubs[i] = coin_pub; + deposit_refund_fee[i] = refund_fee; if (GNUNET_SYSERR == - TALER_amount_add (&previous_refund, - &previous_refund, + TALER_amount_add (¤t_refund, + ¤t_refund, &ictx.refunded_amount)) { GNUNET_break (0); ctx->qs = GNUNET_DB_STATUS_HARD_ERROR; return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Existing refund for coin %s is %s\n", + TALER_B2S (&coin_pub), + TALER_amount2s (&ictx.refunded_amount)); + } - if (0 >= TALER_amount_cmp (ctx->refund, - &previous_refund)) - { - /* refund <= refunded_amount; nothing to do! */ - ctx->qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; - return; - } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Total existing refund is %s\n", + TALER_amount2s (¤t_refund)); + + /* stop immediately if we are done */ + if (0 == TALER_amount_cmp (ctx->refund, + ¤t_refund)) + return; + + + /* Phase 2: Try to increase current refund until it matches desired refund */ + + for (unsigned int i=0; i<num_results; i++) + { + const struct TALER_Amount *increment; + struct TALER_Amount left; /* How much of the coin is left after the existing refunds? */ if (GNUNET_SYSERR == TALER_amount_subtract (&left, - &amount_with_fee, - &ictx.refunded_amount)) + &deposit_amount_with_fee[i], + &deposit_refund[i])) { GNUNET_break (0); ctx->qs = GNUNET_DB_STATUS_HARD_ERROR; @@ -2212,15 +2221,17 @@ process_deposits_for_refund_cb (void *cls, /* coin was fully refunded, move to next coin */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Coin %s fully refunded, moving to next coin\n", - TALER_B2S (&coin_pub)); + TALER_B2S (&deposit_coin_pubs[i])); continue; } + struct TALER_Amount remaining_refund; + /* How much of the refund is left? */ if (GNUNET_SYSERR == TALER_amount_subtract (&remaining_refund, ctx->refund, - &previous_refund)) + ¤t_refund)) { GNUNET_break (0); ctx->qs = GNUNET_DB_STATUS_HARD_ERROR; @@ -2240,8 +2251,8 @@ process_deposits_for_refund_cb (void *cls, } if (GNUNET_SYSERR == - TALER_amount_add (&previous_refund, - &previous_refund, + TALER_amount_add (¤t_refund, + ¤t_refund, increment)) { GNUNET_break (0); @@ -2249,21 +2260,14 @@ process_deposits_for_refund_cb (void *cls, return; } - /* Subtract from refund what has already been awarded */ - if (GNUNET_SYSERR == - TALER_amount_subtract (&remaining_refund, - ctx->refund, - &ictx.refunded_amount)) - { - GNUNET_break (0); - ctx->qs = GNUNET_DB_STATUS_HARD_ERROR; - return; - } - /* actually run the refund */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Coin %s deposit amount is %s\n", + TALER_B2S (&deposit_coin_pubs[i]), + TALER_amount2s (&deposit_amount_with_fee[i])); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Coin %s refund will be incremented by %s\n", - TALER_B2S (&coin_pub), + TALER_B2S (&deposit_coin_pubs[i]), TALER_amount2s (increment)); { enum GNUNET_DB_QueryStatus qs; @@ -2272,21 +2276,20 @@ process_deposits_for_refund_cb (void *cls, (qs = insert_refund (ctx->pg, ctx->merchant_pub, ctx->h_contract_terms, - &coin_pub, + &deposit_coin_pubs[i], ctx->reason, increment, - &refund_fee))) + &deposit_refund_fee[i]))) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); ctx->qs = qs; return; } - - /* stop immediately if we are done */ - if (0 == TALER_amount_cmp (ctx->refund, - &previous_refund)) - return; } + /* stop immediately if we are done */ + if (0 == TALER_amount_cmp (ctx->refund, + ¤t_refund)) + return; } /** |