summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/taler-exchange-dbinit.13
-rw-r--r--src/exchange-lib/exchange_api_refund.c6
-rw-r--r--src/exchange-lib/test_exchange_api.c26
-rw-r--r--src/exchange-tools/taler-exchange-dbinit.c11
-rw-r--r--src/exchange/taler-exchange-httpd_db.c15
-rw-r--r--src/exchange/taler-exchange-httpd_refund.c22
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c43
7 files changed, 102 insertions, 24 deletions
diff --git a/doc/taler-exchange-dbinit.1 b/doc/taler-exchange-dbinit.1
index 456a85b0c..92bf83b09 100644
--- a/doc/taler-exchange-dbinit.1
+++ b/doc/taler-exchange-dbinit.1
@@ -19,6 +19,9 @@ Use the configuration and other resources for the exchange to operate from DIRNA
.IP "\-h, \-\-help"
Print short help on options.
.B
+.IP "\-r, \-\-reset"
+Drop tables. Dangerous, will delete all existing data in the database before creating the tables.
+.B
.IP "\-v, \-\-version"
Print version information.
diff --git a/src/exchange-lib/exchange_api_refund.c b/src/exchange-lib/exchange_api_refund.c
index 82ae5e8ab..3a840c7c4 100644
--- a/src/exchange-lib/exchange_api_refund.c
+++ b/src/exchange-lib/exchange_api_refund.c
@@ -169,6 +169,10 @@ handle_refund_finished (void *cls,
/* Nothing really to verify, this should never
happen, we should pass the JSON reply to the application */
break;
+ case MHD_HTTP_GONE:
+ /* Kind of normal: the money was already sent to the merchant
+ (it was too late for the refund). */
+ break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
/* Server had an internal issue; we should retry, but this API
leaves this to the application */
@@ -266,7 +270,7 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
" s:I, s:I," /* transaction id, rtransaction id */
" s:o, s:o}", /* merchant_pub, merchant_sig */
"refund_amount", TALER_JSON_from_amount (amount),
- "refund_fee", TALER_JSON_from_amount (amount),
+ "refund_fee", TALER_JSON_from_amount (refund_fee),
"H_contract", GNUNET_JSON_from_data_auto (h_contract),
"coin_pub", GNUNET_JSON_from_data_auto (coin_pub),
"transaction_id", (json_int_t) transaction_id,
diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c
index 169d68f39..6612609fa 100644
--- a/src/exchange-lib/test_exchange_api.c
+++ b/src/exchange-lib/test_exchange_api.c
@@ -2926,7 +2926,10 @@ run (void *cls)
},
/* Run transfers. Should do nothing as refund deadline blocks it */
{ .oc = OC_RUN_AGGREGATOR,
- .label = "run-aggregator" },
+ .label = "run-aggregator-refund" },
+ /* check that aggregator didn't do anything, as expected */
+ { .oc = OC_CHECK_BANK_TRANSFERS_EMPTY,
+ .label = "check-refund-not-run" },
/* Trigger refund */
{ .oc = OC_REFUND,
.label = "refund-ok",
@@ -2949,11 +2952,18 @@ run (void *cls)
},
/* Run transfers. This will do the transfer as refund deadline was 0 */
{ .oc = OC_RUN_AGGREGATOR,
- .label = "run-aggregator" },
+ .label = "run-aggregator-3" },
+ /* Check that deposit did run */
+ { .oc = OC_CHECK_BANK_TRANSFER,
+ .label = "check_bank_transfer-pre-refund",
+ .details.check_bank_transfer.amount = "EUR:4.98",
+ .details.check_bank_transfer.account_debit = 2,
+ .details.check_bank_transfer.account_credit = 42
+ },
/* Run failing refund, as past deadline & aggregation */
{ .oc = OC_REFUND,
.label = "refund-fail",
- .expected_response_code = MHD_HTTP_OK,
+ .expected_response_code = MHD_HTTP_GONE,
.details.refund.amount = "EUR:4.99",
.details.refund.fee = "EUR:0.01",
.details.refund.deposit_ref = "deposit-refund-2",
@@ -3015,6 +3025,16 @@ main (int argc,
NULL);
GNUNET_OS_process_wait (proc);
GNUNET_OS_process_destroy (proc);
+ proc = GNUNET_OS_start_process (GNUNET_NO,
+ GNUNET_OS_INHERIT_STD_ALL,
+ NULL, NULL, NULL,
+ "taler-exchange-dbinit",
+ "taler-exchange-dbinit",
+ "-c", "test_exchange_api.conf",
+ "-r",
+ NULL);
+ GNUNET_OS_process_wait (proc);
+ GNUNET_OS_process_destroy (proc);
exchanged = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
diff --git a/src/exchange-tools/taler-exchange-dbinit.c b/src/exchange-tools/taler-exchange-dbinit.c
index e51f5a21a..16d76e4d0 100644
--- a/src/exchange-tools/taler-exchange-dbinit.c
+++ b/src/exchange-tools/taler-exchange-dbinit.c
@@ -23,13 +23,17 @@
#include "taler_exchangedb_plugin.h"
-
/**
* Return value from main().
*/
static int global_ret;
/**
+ * -r option: do full DB reset
+ */
+static int reset_db;
+
+/**
* Main function that will be run.
*
* @param cls closure
@@ -53,6 +57,8 @@ run (void *cls,
global_ret = 1;
return;
}
+ if (reset_db)
+ (void) plugin->drop_tables (plugin->cls);
if (GNUNET_OK !=
plugin->create_tables (plugin->cls))
{
@@ -79,6 +85,9 @@ main (int argc,
char *const *argv)
{
const struct GNUNET_GETOPT_CommandLineOption options[] = {
+ {'r', "reset", NULL,
+ "reset database (DANGEROUS: all existing data is lost!)", 0,
+ &GNUNET_GETOPT_set_one, &reset_db},
GNUNET_GETOPT_OPTION_END
};
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index 712df02a9..981c97289 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -340,11 +340,13 @@ TMH_DB_execute_refund (struct MHD_Connection *connection,
MHD_HTTP_NOT_FOUND);
}
deposit_found = GNUNET_NO;
+ refund_found = GNUNET_NO;
for (tlp = tl; NULL != tlp; tlp = tlp->next)
{
switch (tlp->type)
{
case TALER_EXCHANGEDB_TT_DEPOSIT:
+ if (GNUNET_NO == deposit_found)
{
dep = tlp->details.deposit;
if ( (0 == memcmp (&dep->merchant_pub,
@@ -364,6 +366,7 @@ TMH_DB_execute_refund (struct MHD_Connection *connection,
/* Melts cannot be refunded, ignore here */
break;
case TALER_EXCHANGEDB_TT_REFUND:
+ if (GNUNET_NO == refund_found)
{
ref = tlp->details.refund;
/* First, check if existing refund request is identical */
@@ -476,15 +479,13 @@ TMH_DB_execute_refund (struct MHD_Connection *connection,
MHD_HTTP_GONE);
}
- /* We no longer need 'tl' or 'dep' or 'ref' */
- TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
- tl);
-
/* check refund amount is sufficiently low */
if (1 == TALER_amount_cmp (&refund->refund_amount,
&dep->amount_with_fee) )
{
GNUNET_break_op (0); /* cannot refund more than original value */
+ TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
+ tl);
return TMH_RESPONSE_reply_refund_failure (connection,
MHD_HTTP_PRECONDITION_FAILED);
}
@@ -500,6 +501,8 @@ TMH_DB_execute_refund (struct MHD_Connection *connection,
not good... */
GNUNET_break (0);
TMH_KS_release (mks);
+ TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
+ tl);
return TMH_RESPONSE_reply_internal_error (connection,
"denomination key not found");
}
@@ -513,6 +516,8 @@ TMH_DB_execute_refund (struct MHD_Connection *connection,
{
TMH_plugin->rollback (TMH_plugin->cls,
session);
+ TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
+ tl);
return TMH_RESPONSE_reply_arg_invalid (connection,
"refund_fee");
}
@@ -521,6 +526,8 @@ TMH_DB_execute_refund (struct MHD_Connection *connection,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Refund fee proposed by merchant is higher than necessary.\n");
}
+ TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
+ tl);
/* Finally, store new refund data */
if (GNUNET_OK !=
diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c
index d8c9a6eed..d6d769134 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -50,18 +50,18 @@ static int
verify_and_execute_refund (struct MHD_Connection *connection,
const struct TALER_EXCHANGEDB_Refund *refund)
{
- struct TALER_RefundRequestPS dr;
+ struct TALER_RefundRequestPS rr;
- dr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND);
- dr.purpose.size = htonl (sizeof (struct TALER_RefundRequestPS));
- dr.h_contract = refund->h_contract;
- dr.transaction_id = GNUNET_htonll (refund->transaction_id);
- dr.coin_pub = refund->coin.coin_pub;
- dr.merchant = refund->merchant_pub;
- dr.rtransaction_id = GNUNET_htonll (refund->rtransaction_id);
- TALER_amount_hton (&dr.refund_amount,
+ rr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND);
+ rr.purpose.size = htonl (sizeof (struct TALER_RefundRequestPS));
+ rr.h_contract = refund->h_contract;
+ rr.transaction_id = GNUNET_htonll (refund->transaction_id);
+ rr.coin_pub = refund->coin.coin_pub;
+ rr.merchant = refund->merchant_pub;
+ rr.rtransaction_id = GNUNET_htonll (refund->rtransaction_id);
+ TALER_amount_hton (&rr.refund_amount,
&refund->refund_amount);
- TALER_amount_hton (&dr.refund_fee,
+ TALER_amount_hton (&rr.refund_fee,
&refund->refund_fee);
if (GNUNET_YES !=
TALER_amount_cmp_currency (&refund->refund_amount,
@@ -80,7 +80,7 @@ verify_and_execute_refund (struct MHD_Connection *connection,
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
- &dr.purpose,
+ &rr.purpose,
&refund->merchant_sig.eddsa_sig,
&refund->merchant_pub.eddsa_pub))
{
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index f53b23104..e2b158c90 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -2260,13 +2260,18 @@ postgres_test_deposit_done (void *cls,
PQclear (result);
return GNUNET_SYSERR;
}
+ if (1 != PQntuples (result))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
{
- /* NOTE: maybe wrong type for a 'boolean' */
- uint32_t done = 0;
+ uint8_t done = 0;
struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint32 ("done",
- &done),
+ GNUNET_PQ_result_spec_auto_from_type ("done",
+ &done),
GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
@@ -3703,6 +3708,16 @@ postgres_get_coin_transactions (void *cls,
tl->next = head;
tl->type = TALER_EXCHANGEDB_TT_DEPOSIT;
tl->details.deposit = deposit;
+ if (GNUNET_SYSERR == get_known_coin (cls,
+ session,
+ &deposit->coin.coin_pub,
+ &deposit->coin))
+ {
+ GNUNET_break (0);
+ GNUNET_free (deposit);
+ PQclear (result);
+ goto cleanup;
+ }
head = tl;
continue;
}
@@ -3762,6 +3777,16 @@ postgres_get_coin_transactions (void *cls,
tl->next = head;
tl->type = TALER_EXCHANGEDB_TT_REFRESH_MELT;
tl->details.melt = melt;
+ if (GNUNET_SYSERR == get_known_coin (cls,
+ session,
+ coin_pub,
+ &melt->coin))
+ {
+ GNUNET_break (0);
+ GNUNET_free (melt);
+ PQclear (result);
+ goto cleanup;
+ }
head = tl;
continue;
}
@@ -3826,6 +3851,16 @@ postgres_get_coin_transactions (void *cls,
tl->next = head;
tl->type = TALER_EXCHANGEDB_TT_REFUND;
tl->details.refund = refund;
+ if (GNUNET_SYSERR == get_known_coin (cls,
+ session,
+ coin_pub,
+ &refund->coin))
+ {
+ GNUNET_break (0);
+ GNUNET_free (refund);
+ PQclear (result);
+ goto cleanup;
+ }
head = tl;
continue;
}