[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [taler-merchant] branch master updated: adding pay_again an
From: |
gnunet |
Subject: |
[GNUnet-SVN] [taler-merchant] branch master updated: adding pay_again and pay_abort commands to testcase (incomplete, not used) |
Date: |
Fri, 29 Dec 2017 15:02:19 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository merchant.
The following commit(s) were added to refs/heads/master by this push:
new 51f363f adding pay_again and pay_abort commands to testcase
(incomplete, not used)
51f363f is described below
commit 51f363f33d125400e0a026f7b8016f5d15511631
Author: Christian Grothoff <address@hidden>
AuthorDate: Fri Dec 29 15:01:22 2017 +0100
adding pay_again and pay_abort commands to testcase (incomplete, not used)
---
src/backend/taler-merchant-httpd_pay.c | 4 -
src/lib/test_merchant_api.c | 624 +++++++++++++++++++++++++++++----
2 files changed, 551 insertions(+), 77 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_pay.c
b/src/backend/taler-merchant-httpd_pay.c
index d2f7afa..20b50d7 100644
--- a/src/backend/taler-merchant-httpd_pay.c
+++ b/src/backend/taler-merchant-httpd_pay.c
@@ -19,10 +19,6 @@
* @author Marcello Stanisci
* @author Christian Grothoff
* @author Florian Dold
- *
- * TODO:
- * - add API to allow wallet to request refunds
- * - write testcase for new logic
*/
#include "platform.h"
#include <jansson.h>
diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c
index 941f46b..469eb80 100644
--- a/src/lib/test_merchant_api.c
+++ b/src/lib/test_merchant_api.c
@@ -20,7 +20,7 @@
* @author Marcello Stanisci
*
* TODO:
- * - add test logic for tips to main test interpreter
+ * - add test logic for pay-abort-refund
*/
#include "platform.h"
#include <taler/taler_exchange_service.h>
@@ -177,6 +177,16 @@ enum OpCode
OC_PAY,
/**
+ * Resume pay operation with additional coins.
+ */
+ OC_PAY_AGAIN,
+
+ /**
+ * Abort payment with coins, requesting refund.
+ */
+ OC_PAY_ABORT,
+
+ /**
* Run the aggregator to execute deposits.
*/
OC_RUN_AGGREGATOR,
@@ -508,7 +518,6 @@ struct Command
/**
* Information for a #OC_PAY command.
- * FIXME: support tests where we pay with multiple coins at once.
*/
struct
{
@@ -541,7 +550,7 @@ struct Command
const char *amount_without_fee;
/**
- * Deposit handle while operation is running.
+ * Pay handle while operation is running.
*/
struct TALER_MERCHANT_Pay *ph;
@@ -560,6 +569,44 @@ struct Command
struct {
/**
+ * Reference to the (incomplete) pay operation that is to be
+ * resumed.
+ */
+ char *pay_ref;
+
+ /**
+ * ";"-separated list of references to additional withdrawn
+ * coins to be used in the payment. Each reference has the
+ * syntax "LABEL[/NUMBER]" where NUMBER refers to a particular
+ * coin (in case multiple coins were created in a step).
+ */
+ char *coin_ref;
+
+ /**
+ * Pay handle while operation is running.
+ */
+ struct TALER_MERCHANT_Pay *ph;
+
+ } pay_again;
+
+ struct {
+
+ /**
+ * Reference to the pay operation that is to be aborted.
+ */
+ char *pay_ref;
+
+ /**
+ * Pay handle while operation is running.
+ */
+ struct TALER_MERCHANT_Pay *ph;
+
+ } pay_abort;
+
+
+ struct {
+
+ /**
* Process for the aggregator.
*/
struct GNUNET_OS_Process *aggregator_proc;
@@ -1656,6 +1703,88 @@ pay_cb (void *cls,
/**
+ * Function called with the result of a /pay again operation.
+ *
+ * @param cls closure with the interpreter state
+ * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful
deposit;
+ * 0 if the exchange's reply is bogus (fails to follow the
protocol)
+ * @param ec taler-specific error object
+ * @param obj the received JSON reply, should be kept as proof (and, in case
of errors,
+ * be forwarded to the customer)
+ */
+static void
+pay_again_cb (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const json_t *obj)
+{
+ struct InterpreterState *is = cls;
+ struct Command *cmd = &is->commands[is->ip];
+ struct PaymentResponsePS mr;
+ struct GNUNET_CRYPTO_EddsaSignature sig;
+ const char *error_name;
+ unsigned int error_line;
+ const struct Command *pref;
+
+ cmd->details.pay_again.ph = NULL;
+ if (cmd->expected_response_code != http_status)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u to command %s\n",
+ http_status,
+ cmd->label);
+ fail (is);
+ return;
+ }
+ GNUNET_assert (NULL != (pref = find_command
+ (is,
+ cmd->details.pay_again.pay_ref)));
+ if (MHD_HTTP_OK == http_status)
+ {
+ struct GNUNET_HashCode hcontract;
+ /* Check signature */
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("sig",
+ &sig),
+ GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
+ &hcontract),
+ GNUNET_JSON_spec_end ()
+ };
+
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_JSON_parse (obj,
+ spec,
+ &error_name,
+ &error_line));
+ mr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_PAYMENT_OK);
+ mr.purpose.size = htonl (sizeof (mr));
+ mr.h_contract_terms = pref->details.pay.h_contract_terms;
+ if (0 != memcmp (&pref->details.pay.h_contract_terms,
+ &hcontract,
+ sizeof (hcontract)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Contract changed in /pay again\n");
+ fail (is);
+ return;
+ }
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_PAYMENT_OK,
+ &mr.purpose,
+ &sig,
+ &pref->details.pay.merchant_pub.eddsa_pub))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Merchant signature given in response to /pay invalid\n");
+ fail (is);
+ return;
+ }
+ }
+ next_command (is);
+}
+
+
+/**
* Task triggered whenever we receive a SIGCHLD (child
* process died).
*
@@ -2193,6 +2322,28 @@ cleanup_state (struct InterpreterState *is)
cmd->details.pay.ph = NULL;
}
break;
+ case OC_PAY_AGAIN:
+ if (NULL != cmd->details.pay_again.ph)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Command %u (%s) did not complete\n",
+ i,
+ cmd->label);
+ TALER_MERCHANT_pay_cancel (cmd->details.pay_again.ph);
+ cmd->details.pay_again.ph = NULL;
+ }
+ break;
+ case OC_PAY_ABORT:
+ if (NULL != cmd->details.pay_abort.ph)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Command %u (%s) did not complete\n",
+ i,
+ cmd->label);
+ TALER_MERCHANT_pay_cancel (cmd->details.pay_abort.ph);
+ cmd->details.pay_abort.ph = NULL;
+ }
+ break;
case OC_RUN_AGGREGATOR:
if (NULL != cmd->details.run_aggregator.aggregator_proc)
{
@@ -2336,6 +2487,122 @@ cleanup_state (struct InterpreterState *is)
/**
+ * Parse the @a coins specification and grow the @a pc
+ * array with the coins found, updating @a npc.
+ *
+ * @param[in,out] pc pointer to array of coins found
+ * @param[in,out] npc length of array at @a pc
+ * @param[in] coins string specifying coins to add to @a pc,
+ * clobbered in the process
+ * @param is interpreter state
+ * @return #GNUNET_OK on success
+ */
+static int
+build_coins (struct TALER_MERCHANT_PayCoin **pc,
+ unsigned int *npc,
+ char *coins,
+ struct InterpreterState *is)
+{
+ struct Command *cmd = &is->commands[is->ip];
+ char *token;
+
+ for (token = strtok (coins, ";");
+ NULL != token;
+ token = strtok (NULL, ";"))
+ {
+ const struct Command *coin_ref;
+ char *ctok;
+ unsigned int ci;
+ struct TALER_MERCHANT_PayCoin *icoin;
+
+ /* Token syntax is "LABEL[/NUMBER]" */
+ ctok = strchr (token, '/');
+ ci = 0;
+ if (NULL != ctok)
+ {
+ *ctok = '\0';
+ ctok++;
+ if (1 != sscanf (ctok,
+ "%u",
+ &ci))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ }
+ GNUNET_assert (coin_ref = find_command (is,
+ token));
+ GNUNET_array_grow (*pc,
+ *npc,
+ (*npc) + 1);
+ icoin = &(*pc)[(*npc)-1];
+ switch (coin_ref->oc)
+ {
+ case OC_WITHDRAW_SIGN:
+ icoin->coin_priv = coin_ref->details.reserve_withdraw.ps.coin_priv;
+ icoin->denom_pub = coin_ref->details.reserve_withdraw.pk->key;
+ icoin->denom_sig = coin_ref->details.reserve_withdraw.sig;
+ icoin->denom_value = coin_ref->details.reserve_withdraw.pk->value;
+ icoin->exchange_url = EXCHANGE_URL;
+ break;
+ case OC_TIP_PICKUP:
+ icoin->coin_priv = coin_ref->details.tip_pickup.psa[ci].coin_priv;
+ icoin->denom_pub = coin_ref->details.tip_pickup.dks[ci]->key;
+ icoin->denom_sig = coin_ref->details.tip_pickup.sigs[ci];
+ icoin->denom_value = coin_ref->details.tip_pickup.dks[ci]->value;
+ icoin->exchange_url = EXCHANGE_URL;
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (cmd->details.pay.amount_without_fee,
+ &icoin->amount_without_fee));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (cmd->details.pay.amount_with_fee,
+ &icoin->amount_with_fee));
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * /pay request to a merchant.
+ *
+ * @param cls closure
+ * @param http_status HTTP response code, 200 or 300-level response codes
+ * can indicate success, depending on whether the
interaction
+ * was with a merchant frontend or backend;
+ * 0 if the merchant's reply is bogus (fails to follow the
protocol)
+ * @param ec taler-specific error code
+ * @param merchant_pub public key of the merchant
+ * @param h_contract hash of the contract
+ * @param num_refunds size of the @a merchant_sigs array, 0 on errors
+ * @param merchant_sigs merchant signatures refunding coins, NULL on errors
+ * @param rtids refund transaction IDs (array of length @a num_refunds)
+ * @param obj the received JSON reply, with error details if the request failed
+ */
+static void
+pay_refund_cb (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct GNUNET_HashCode *h_contract,
+ unsigned int num_refunds,
+ const struct TALER_MerchantSignatureP *merchant_sigs,
+ const uint64_t *rtids,
+ const json_t *obj)
+{
+ struct InterpreterState *is = cls;
+
+ GNUNET_break (0);
+ fail (is); // FIXME: not implemented!
+}
+
+
+/**
* Run the main interpreter loop that performs exchange operations.
*
* @param cls contains the `struct InterpreterState`
@@ -2609,7 +2876,6 @@ interpreter_run (void *cls)
struct TALER_MerchantSignatureP merchant_sig;
struct TALER_Amount total_amount;
struct TALER_Amount max_fee;
- char *token;
const char *error_name;
unsigned int error_line;
@@ -2622,14 +2888,22 @@ interpreter_run (void *cls)
{
/* Get information that needs to be replied in the deposit permission
*/
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("order_id", &order_id),
- GNUNET_JSON_spec_absolute_time ("refund_deadline", &refund_deadline),
- GNUNET_JSON_spec_absolute_time ("pay_deadline", &pay_deadline),
- GNUNET_JSON_spec_absolute_time ("timestamp", ×tamp),
- GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub),
- GNUNET_JSON_spec_fixed_auto ("H_wire", &h_wire),
- TALER_JSON_spec_amount ("amount", &total_amount),
- TALER_JSON_spec_amount ("max_fee", &max_fee),
+ GNUNET_JSON_spec_string ("order_id",
+ &order_id),
+ GNUNET_JSON_spec_absolute_time ("refund_deadline",
+ &refund_deadline),
+ GNUNET_JSON_spec_absolute_time ("pay_deadline",
+ &pay_deadline),
+ GNUNET_JSON_spec_absolute_time ("timestamp",
+ ×tamp),
+ GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+ &merchant_pub),
+ GNUNET_JSON_spec_fixed_auto ("H_wire",
+ &h_wire),
+ TALER_JSON_spec_amount ("amount",
+ &total_amount),
+ TALER_JSON_spec_amount ("max_fee",
+ &max_fee),
GNUNET_JSON_spec_end()
};
@@ -2655,66 +2929,20 @@ interpreter_run (void *cls)
}
/* strtok loop here */
coins = GNUNET_strdup (cmd->details.pay.coin_ref);
-
pc = NULL;
npc = 0;
- for (token = strtok (coins, ";");
- NULL != token;
- token = strtok (NULL, ";"))
+ if (GNUNET_OK !=
+ build_coins (&pc,
+ &npc,
+ coins,
+ is))
{
- const struct Command *coin_ref;
- char *ctok;
- unsigned int ci;
- struct TALER_MERCHANT_PayCoin *icoin;
-
- /* Token syntax is "LABEL[/NUMBER]" */
- ctok = strchr (token, '/');
- ci = 0;
- if (NULL != ctok)
- {
- *ctok = '\0';
- ctok++;
- if (1 != sscanf (ctok,
- "%u",
- &ci))
- {
- GNUNET_break (0);
- fail (is);
- return;
- }
- }
- GNUNET_assert (coin_ref = find_command (is,
- token));
- GNUNET_array_grow (pc,
- npc,
- npc + 1);
- icoin = &pc[npc-1];
- switch (coin_ref->oc)
- {
- case OC_WITHDRAW_SIGN:
- icoin->coin_priv = coin_ref->details.reserve_withdraw.ps.coin_priv;
- icoin->denom_pub = coin_ref->details.reserve_withdraw.pk->key;
- icoin->denom_sig = coin_ref->details.reserve_withdraw.sig;
- icoin->denom_value = coin_ref->details.reserve_withdraw.pk->value;
- icoin->exchange_url = EXCHANGE_URL;
- break;
- case OC_TIP_PICKUP:
- icoin->coin_priv = coin_ref->details.tip_pickup.psa[ci].coin_priv;
- icoin->denom_pub = coin_ref->details.tip_pickup.dks[ci]->key;
- icoin->denom_sig = coin_ref->details.tip_pickup.sigs[ci];
- icoin->denom_value = coin_ref->details.tip_pickup.dks[ci]->value;
- icoin->exchange_url = EXCHANGE_URL;
- break;
- default:
- GNUNET_assert (0);
- }
-
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount
(cmd->details.pay.amount_without_fee,
- &icoin->amount_without_fee));
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount
(cmd->details.pay.amount_with_fee,
- &icoin->amount_with_fee));
+ fail (is);
+ GNUNET_array_grow (pc,
+ npc,
+ 0);
+ GNUNET_free (coins);
+ return;
}
GNUNET_free (coins);
@@ -2746,6 +2974,255 @@ interpreter_run (void *cls)
fail (is);
}
break;
+
+ case OC_PAY_AGAIN:
+ {
+ struct TALER_MERCHANT_PayCoin *pc;
+ const struct Command *pref;
+ unsigned int npc;
+ char *coins;
+ const char *order_id;
+ struct GNUNET_TIME_Absolute refund_deadline;
+ struct GNUNET_TIME_Absolute pay_deadline;
+ struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_HashCode h_wire;
+ struct TALER_MerchantPublicKeyP merchant_pub;
+ struct TALER_MerchantSignatureP merchant_sig;
+ struct TALER_Amount total_amount;
+ struct TALER_Amount max_fee;
+ const char *error_name;
+ unsigned int error_line;
+
+ /* Get original /pay command */
+ GNUNET_assert (NULL != (pref = find_command
+ (is,
+ cmd->details.pay_again.pay_ref)));
+ /* get proposal */
+ GNUNET_assert (NULL != (ref = find_command
+ (is,
+ pref->details.pay.contract_ref)));
+ merchant_sig = ref->details.proposal.merchant_sig;
+ GNUNET_assert (NULL != ref->details.proposal.contract_terms);
+ {
+ /* Get information that needs to be replied in the deposit permission
*/
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("order_id",
+ &order_id),
+ GNUNET_JSON_spec_absolute_time ("refund_deadline",
+ &refund_deadline),
+ GNUNET_JSON_spec_absolute_time ("pay_deadline",
+ &pay_deadline),
+ GNUNET_JSON_spec_absolute_time ("timestamp",
+ ×tamp),
+ GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+ &merchant_pub),
+ GNUNET_JSON_spec_fixed_auto ("H_wire",
+ &h_wire),
+ TALER_JSON_spec_amount ("amount",
+ &total_amount),
+ TALER_JSON_spec_amount ("max_fee",
+ &max_fee),
+ GNUNET_JSON_spec_end()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (ref->details.proposal.contract_terms,
+ spec,
+ &error_name,
+ &error_line))
+ {
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Parser failed on %s:%u\n",
+ error_name,
+ error_line);
+ /**
+ * Let's use fail() here, as the proposal might be broken
+ * because of backend's fault.
+ */
+ fail (is);
+ return;
+ }
+ }
+ /* strtok loop over original coins here */
+ pc = NULL;
+ npc = 0;
+ coins = GNUNET_strdup (pref->details.pay.coin_ref);
+ if (GNUNET_OK !=
+ build_coins (&pc,
+ &npc,
+ coins,
+ is))
+ {
+ fail (is);
+ GNUNET_array_grow (pc,
+ npc,
+ 0);
+ GNUNET_free (coins);
+ return;
+ }
+ GNUNET_free (coins);
+ /* Now loop over additional coins from pay again */
+ coins = GNUNET_strdup (cmd->details.pay_again.coin_ref);
+ if (GNUNET_OK !=
+ build_coins (&pc,
+ &npc,
+ coins,
+ is))
+ {
+ fail (is);
+ GNUNET_array_grow (pc,
+ npc,
+ 0);
+ GNUNET_free (coins);
+ return;
+ }
+ GNUNET_free (coins);
+ /* then repeat payment attempt */
+ cmd->details.pay_again.ph = TALER_MERCHANT_pay_wallet
+ (ctx,
+ MERCHANT_URL,
+ instance,
+ &ref->details.proposal.hash,
+ &total_amount,
+ &max_fee,
+ &merchant_pub,
+ &merchant_sig,
+ timestamp,
+ refund_deadline,
+ pay_deadline,
+ &h_wire,
+ order_id,
+ npc /* num_coins */,
+ pc /* coins */,
+ &pay_again_cb,
+ is);
+ GNUNET_array_grow (pc,
+ npc,
+ 0);
+ }
+ if (NULL == cmd->details.pay_again.ph)
+ {
+ GNUNET_break (0);
+ fail (is);
+ }
+ break;
+ case OC_PAY_ABORT:
+ {
+ struct TALER_MERCHANT_PayCoin *pc;
+ const struct Command *pref;
+ unsigned int npc;
+ char *coins;
+ const char *order_id;
+ struct GNUNET_TIME_Absolute refund_deadline;
+ struct GNUNET_TIME_Absolute pay_deadline;
+ struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_HashCode h_wire;
+ struct TALER_MerchantPublicKeyP merchant_pub;
+ struct TALER_MerchantSignatureP merchant_sig;
+ struct TALER_Amount total_amount;
+ struct TALER_Amount max_fee;
+ const char *error_name;
+ unsigned int error_line;
+
+ /* Get original /pay command */
+ GNUNET_assert (NULL != (pref = find_command
+ (is,
+ cmd->details.pay_abort.pay_ref)));
+ /* get proposal */
+ GNUNET_assert (NULL != (ref = find_command
+ (is,
+ pref->details.pay.contract_ref)));
+ merchant_sig = ref->details.proposal.merchant_sig;
+ GNUNET_assert (NULL != ref->details.proposal.contract_terms);
+ {
+ /* Get information that needs to be replied in the deposit permission
*/
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("order_id",
+ &order_id),
+ GNUNET_JSON_spec_absolute_time ("refund_deadline",
+ &refund_deadline),
+ GNUNET_JSON_spec_absolute_time ("pay_deadline",
+ &pay_deadline),
+ GNUNET_JSON_spec_absolute_time ("timestamp",
+ ×tamp),
+ GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+ &merchant_pub),
+ GNUNET_JSON_spec_fixed_auto ("H_wire",
+ &h_wire),
+ TALER_JSON_spec_amount ("amount",
+ &total_amount),
+ TALER_JSON_spec_amount ("max_fee",
+ &max_fee),
+ GNUNET_JSON_spec_end()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (ref->details.proposal.contract_terms,
+ spec,
+ &error_name,
+ &error_line))
+ {
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Parser failed on %s:%u\n",
+ error_name,
+ error_line);
+ /**
+ * Let's use fail() here, as the proposal might be broken
+ * because of backend's fault.
+ */
+ fail (is);
+ return;
+ }
+ }
+ /* strtok loop over original coins here */
+ pc = NULL;
+ npc = 0;
+ coins = GNUNET_strdup (pref->details.pay.coin_ref);
+ if (GNUNET_OK !=
+ build_coins (&pc,
+ &npc,
+ coins,
+ is))
+ {
+ fail (is);
+ GNUNET_array_grow (pc,
+ npc,
+ 0);
+ GNUNET_free (coins);
+ return;
+ }
+ GNUNET_free (coins);
+ /* then trigger abort-refund operation */
+ cmd->details.pay_abort.ph = TALER_MERCHANT_pay_abort
+ (ctx,
+ MERCHANT_URL,
+ instance,
+ &ref->details.proposal.hash,
+ &total_amount,
+ &max_fee,
+ &merchant_pub,
+ &merchant_sig,
+ timestamp,
+ refund_deadline,
+ pay_deadline,
+ &h_wire,
+ order_id,
+ npc /* num_coins */,
+ pc /* coins */,
+ &pay_refund_cb,
+ is);
+ GNUNET_array_grow (pc,
+ npc,
+ 0);
+ }
+ if (NULL == cmd->details.pay_abort.ph)
+ {
+ GNUNET_break (0);
+ fail (is);
+ }
+ break;
case OC_RUN_AGGREGATOR:
{
const struct GNUNET_DISK_FileHandle *pr;
@@ -2838,10 +3315,11 @@ interpreter_run (void *cls)
(is,
cmd->details.track_transfer.check_bank_ref)));
subject = ref->details.check_bank_transfer.subject;
- GNUNET_assert (GNUNET_OK == GNUNET_STRINGS_string_to_data (subject,
- strlen (subject),
- &wtid,
- sizeof (wtid)));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_STRINGS_string_to_data (subject,
+ strlen (subject),
+ &wtid,
+ sizeof (wtid)));
if (NULL == (cmd->details.track_transfer.tdo
= TALER_MERCHANT_track_transfer (ctx,
MERCHANT_URL,
--
To stop receiving notification emails like this one, please contact
address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [taler-merchant] branch master updated: adding pay_again and pay_abort commands to testcase (incomplete, not used),
gnunet <=