summaryrefslogtreecommitdiff
path: root/src/backenddb/plugin_merchantdb_postgres.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-08-27 02:01:12 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-08-27 02:01:12 +0200
commit4cfe3ac7beb8fa8de59156e9ff97730b396c66ab (patch)
treed119a5c0bdd51b320c5e65afca1bb8aeab9cc242 /src/backenddb/plugin_merchantdb_postgres.c
parentf0e666563588c4858417b776105d8fc3e17f8840 (diff)
downloadmerchant-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.c125
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);
+ &current_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 (&current_refund,
+ &current_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 (&current_refund));
+
+ /* stop immediately if we are done */
+ if (0 == TALER_amount_cmp (ctx->refund,
+ &current_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))
+ &current_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 (&current_refund,
+ &current_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,
+ &current_refund))
+ return;
}
/**