summaryrefslogtreecommitdiff
path: root/src/auditor-lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/auditor-lib')
-rw-r--r--src/auditor-lib/Makefile.am1
-rw-r--r--src/auditor-lib/auditor_api_deposit_confirmation.c6
-rw-r--r--src/auditor-lib/testing_auditor_api_cmd_deposit_confirmation.c374
-rw-r--r--src/auditor-lib/testing_auditor_api_cmd_exec_auditor.c3
-rw-r--r--src/auditor-lib/testing_auditor_api_cmd_exec_wire_auditor.c3
5 files changed, 380 insertions, 7 deletions
diff --git a/src/auditor-lib/Makefile.am b/src/auditor-lib/Makefile.am
index 4589bc975..44849da22 100644
--- a/src/auditor-lib/Makefile.am
+++ b/src/auditor-lib/Makefile.am
@@ -41,6 +41,7 @@ libtalerauditortesting_la_LDFLAGS = \
-no-undefined
libtalerauditortesting_la_SOURCES = \
testing_auditor_api_helpers.c \
+ testing_auditor_api_cmd_deposit_confirmation.c \
testing_auditor_api_cmd_exec_auditor.c \
testing_auditor_api_cmd_exec_wire_auditor.c
libtalerauditortesting_la_LIBADD = \
diff --git a/src/auditor-lib/auditor_api_deposit_confirmation.c b/src/auditor-lib/auditor_api_deposit_confirmation.c
index 1ad6ddad7..736f326dd 100644
--- a/src/auditor-lib/auditor_api_deposit_confirmation.c
+++ b/src/auditor-lib/auditor_api_deposit_confirmation.c
@@ -156,7 +156,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_CoinSpendSignatureP *exchange_sig,
+ const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_MasterPublicKeyP *master_pub,
struct GNUNET_TIME_Absolute ep_start,
struct GNUNET_TIME_Absolute ep_expire,
@@ -181,7 +181,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire,
&dc.purpose,
&exchange_sig->eddsa_signature,
&exchange_pub->eddsa_pub))
- {
+ {
GNUNET_break_op (0);
TALER_LOG_WARNING ("Invalid signature on /deposit-confirmation request!\n");
{
@@ -261,7 +261,7 @@ TALER_AUDITOR_deposit_confirmation (struct TALER_AUDITOR_Handle *auditor,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_CoinSpendSignatureP *exchange_sig,
+ const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_MasterPublicKeyP *master_pub,
struct GNUNET_TIME_Absolute ep_start,
struct GNUNET_TIME_Absolute ep_expire,
diff --git a/src/auditor-lib/testing_auditor_api_cmd_deposit_confirmation.c b/src/auditor-lib/testing_auditor_api_cmd_deposit_confirmation.c
new file mode 100644
index 000000000..3509fec52
--- /dev/null
+++ b/src/auditor-lib/testing_auditor_api_cmd_deposit_confirmation.c
@@ -0,0 +1,374 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2018 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with TALER; see the file COPYING. If not, see
+ <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file auditor-lib/testing_auditor_api_cmd_deposit_confirmation.c
+ * @brief command for testing /deposit_confirmation.
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_curl_lib.h>
+#include "taler_auditor_service.h"
+#include "taler_testing_lib.h"
+#include "taler_signatures.h"
+#include "backoff.h"
+
+
+/**
+ * State for a "deposit confirmation" CMD.
+ */
+struct DepositConfirmationState
+{
+
+ /**
+ * Reference to any command that is able to provide a deposit.
+ */
+ const char *deposit_reference;
+
+ /**
+ * Which coin of the @e deposit_reference should we confirm.
+ */
+ unsigned int coin_index;
+
+ /**
+ * DepositConfirmation handle while operation is running.
+ */
+ struct TALER_AUDITOR_DepositConfirmationHandle *dc;
+
+ /**
+ * Auditor connection.
+ */
+ struct TALER_AUDITOR_Handle *auditor;
+
+ /**
+ * Interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * Task scheduled to try later.
+ */
+ struct GNUNET_SCHEDULER_Task *retry_task;
+
+ /**
+ * How long do we wait until we retry?
+ */
+ struct GNUNET_TIME_Relative backoff;
+
+ /**
+ * Expected HTTP response code.
+ */
+ unsigned int expected_response_code;
+
+ /**
+ * Should we retry on (transient) failures?
+ */
+ int do_retry;
+
+};
+
+
+/**
+ * Run the command.
+ *
+ * @param cls closure.
+ * @param cmd the command to execute.
+ * @param is the interpreter state.
+ */
+static void
+deposit_confirmation_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is);
+
+
+/**
+ * Task scheduled to re-try #deposit_confirmation_run.
+ *
+ * @param cls a `struct DepositConfirmationState`
+ */
+static void
+do_retry (void *cls)
+{
+ struct DepositConfirmationState *dcs = cls;
+
+ dcs->retry_task = NULL;
+ deposit_confirmation_run (dcs,
+ NULL,
+ dcs->is);
+}
+
+
+/**
+ * Callback to analyze the /deposit-confirmation response, just used
+ * to check if the response code is acceptable.
+ *
+ * @param cls closure.
+ * @param http_status HTTP response code.
+ * @param ec taler-specific error code.
+ * @param obj raw response from the auditor.
+ */
+static void
+deposit_confirmation_cb (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const json_t *obj)
+{
+ struct DepositConfirmationState *dcs = cls;
+
+ dcs->dc = NULL;
+ if (dcs->expected_response_code != http_status)
+ {
+ if (GNUNET_YES == dcs->do_retry)
+ {
+ if ( (0 == http_status) ||
+ (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) ||
+ (MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Retrying deposit confirmation failed with %u/%d\n",
+ http_status,
+ (int) ec);
+ /* on DB conflicts, do not use backoff */
+ if (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec)
+ dcs->backoff = GNUNET_TIME_UNIT_ZERO;
+ else
+ dcs->backoff = AUDITOR_LIB_BACKOFF (dcs->backoff);
+ dcs->retry_task = GNUNET_SCHEDULER_add_delayed (dcs->backoff,
+ &do_retry,
+ dcs);
+ return;
+ }
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u to command %s in %s:%u\n",
+ http_status,
+ dcs->is->commands[dcs->is->ip].label,
+ __FILE__,
+ __LINE__);
+ json_dumpf (obj, stderr, 0);
+ TALER_TESTING_interpreter_fail (dcs->is);
+ return;
+ }
+ TALER_TESTING_interpreter_next (dcs->is);
+}
+
+
+/**
+ * Run the command.
+ *
+ * @param cls closure.
+ * @param cmd the command to execute.
+ * @param is the interpreter state.
+ */
+static void
+deposit_confirmation_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct DepositConfirmationState *dcs = cls;
+ const struct TALER_TESTING_Command *deposit_cmd;
+ struct TALER_TESTING_Command *this_cmd;
+ struct GNUNET_HashCode h_wire;
+ struct GNUNET_HashCode h_contract_terms;
+ struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Absolute refund_deadline;
+ const struct TALER_Amount *amount_without_fee;
+ const struct TALER_CoinSpendPublicKeyP *coin_pub;
+ const struct TALER_MerchantPublicKeyP *merchant_pub;
+ const struct TALER_ExchangePublicKeyP *exchange_pub;
+ const struct TALER_ExchangeSignatureP *exchange_sig;
+ const struct TALER_MasterPublicKeyP *master_pub;
+ struct GNUNET_TIME_Absolute ep_start;
+ struct GNUNET_TIME_Absolute ep_expire;
+ struct GNUNET_TIME_Absolute ep_end;
+ const struct TALER_MasterSignatureP *master_sig;
+ const json_t *wire_details;
+ const json_t *contract_terms;
+
+ dcs->is = is;
+ this_cmd = &is->commands[is->ip]; // use this_cmd->label for logging!
+ GNUNET_assert (NULL != dcs->deposit_reference);
+ deposit_cmd
+ = TALER_TESTING_interpreter_lookup_command (is,
+ dcs->deposit_reference);
+ if (NULL == deposit_cmd)
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
+
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_exchange_pub (deposit_cmd,
+ dcs->coin_index,
+ &exchange_pub));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_exchange_sig (deposit_cmd,
+ dcs->coin_index,
+ &exchange_sig));
+
+#if 0
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_contract_terms (deposit_cmd,
+ dcs->coin_index,
+ &contract_terms));
+ TALER_JSON_hash (contract_terms,
+ &h_contract_terms);
+#endif
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_wire_details (deposit_cmd,
+ dcs->coin_index,
+ &wire_details));
+ TALER_JSON_hash (wire_details,
+ &h_wire);
+
+#if 0
+ // FIXME: extract from deposit trait!
+ /* Fixme: do prefer "interpreter fail" over assertions,
+ * as the former takes care of shutting down processes, too */
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_coin_priv (deposit_cmd,
+ ds->coin_index,
+ &coin_priv));
+#endif
+
+ dcs->dc = TALER_AUDITOR_deposit_confirmation
+ (dcs->auditor,
+ &h_wire,
+ &h_contract_terms,
+ timestamp,
+ refund_deadline,
+ amount_without_fee,
+ coin_pub,
+ merchant_pub,
+ exchange_pub,
+ exchange_sig,
+ master_pub,
+ ep_start,
+ ep_expire,
+ ep_end,
+ master_sig,
+ &deposit_confirmation_cb,
+ dcs);
+
+ if (NULL == dcs->dc)
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
+ return;
+}
+
+
+/**
+ * Free the state of a "deposit_confirmation" CMD, and possibly cancel a
+ * pending operation thereof.
+ *
+ * @param cls closure, a `struct DepositConfirmationState`
+ * @param cmd the command which is being cleaned up.
+ */
+static void
+deposit_confirmation_cleanup (void *cls,
+ const struct TALER_TESTING_Command *cmd)
+{
+ struct DepositConfirmationState *dcs = cls;
+
+ if (NULL != dcs->dc)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Command %u (%s) did not complete\n",
+ dcs->is->ip,
+ cmd->label);
+ TALER_AUDITOR_deposit_confirmation_cancel (dcs->dc);
+ dcs->dc = NULL;
+ }
+ if (NULL != dcs->retry_task)
+ {
+ GNUNET_SCHEDULER_cancel (dcs->retry_task);
+ dcs->retry_task = NULL;
+ }
+ GNUNET_free (dcs);
+}
+
+
+/**
+ * Create a "deposit-confirmation" command.
+ *
+ * @param label command label.
+ * @param auditor auditor connection.
+ * @param deposit_reference reference to any operation that can
+ * provide a coin.
+ * @param coin_index if @a deposit_reference offers an array of
+ * coins, this parameter selects which one in that array.
+ * This value is currently ignored, as only one-coin
+ * deposits are implemented.
+ * @param expected_response_code expected HTTP response code.
+ *
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_deposit_confirmation
+ (const char *label,
+ struct TALER_AUDITOR_Handle *auditor,
+ const char *deposit_reference,
+ unsigned int coin_index,
+ unsigned int expected_response_code)
+{
+ struct TALER_TESTING_Command cmd = {0}; /* need explicit zeroing..*/
+ struct DepositConfirmationState *dcs;
+
+ dcs = GNUNET_new (struct DepositConfirmationState);
+ dcs->auditor = auditor;
+ dcs->deposit_reference = deposit_reference;
+ dcs->coin_index = coin_index;
+ dcs->expected_response_code = expected_response_code;
+
+ cmd.cls = dcs;
+ cmd.label = label;
+ cmd.run = &deposit_confirmation_run;
+ cmd.cleanup = &deposit_confirmation_cleanup;
+
+ return cmd;
+}
+
+
+/**
+ * Modify a deposit confirmation command to enable retries when we get
+ * transient errors from the auditor.
+ *
+ * @param cmd a deposit confirmation command
+ * @return the command with retries enabled
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_deposit_confirmation_with_retry (struct TALER_TESTING_Command cmd)
+{
+ struct DepositConfirmationState *dcs;
+
+ GNUNET_assert (&deposit_confirmation_run == cmd.run);
+ dcs = cmd.cls;
+ dcs->do_retry = GNUNET_YES;
+ return cmd;
+}
+
+
+/* end of testing_auditor_api_cmd_deposit_confirmation.c */
diff --git a/src/auditor-lib/testing_auditor_api_cmd_exec_auditor.c b/src/auditor-lib/testing_auditor_api_cmd_exec_auditor.c
index 37d51b781..273612497 100644
--- a/src/auditor-lib/testing_auditor_api_cmd_exec_auditor.c
+++ b/src/auditor-lib/testing_auditor_api_cmd_exec_auditor.c
@@ -137,11 +137,10 @@ auditor_traits (void *cls,
/**
- * Make the "auditor" CMD.
+ * Make the "exec-auditor" CMD.
*
* @param label command label.
* @param config_filename configuration filename.
- *
* @return the command.
*/
struct TALER_TESTING_Command
diff --git a/src/auditor-lib/testing_auditor_api_cmd_exec_wire_auditor.c b/src/auditor-lib/testing_auditor_api_cmd_exec_wire_auditor.c
index 3f7b2ee31..c32130397 100644
--- a/src/auditor-lib/testing_auditor_api_cmd_exec_wire_auditor.c
+++ b/src/auditor-lib/testing_auditor_api_cmd_exec_wire_auditor.c
@@ -137,11 +137,10 @@ wire_auditor_traits (void *cls,
/**
- * Make the "wire-auditor" CMD.
+ * Make the "exec wire-auditor" CMD.
*
* @param label command label.
* @param config_filename configuration filename.
- *
* @return the command.
*/
struct TALER_TESTING_Command