Merge branch 'master' of git.taler.net:/var/git/exchange
This commit is contained in:
commit
025fbdb41a
1
.gitignore
vendored
1
.gitignore
vendored
@ -30,6 +30,7 @@ GTAGS
|
||||
src/lib/test_exchange_api
|
||||
doc/doxygen/doxygen_sqlite3.db
|
||||
src/bank-lib/test_bank_api
|
||||
src/bank-lib/test_bank_api_with_fakebank
|
||||
src/exchange-lib/test_exchange_api
|
||||
src/exchange-lib/test_exchange_api_home/.local/share/taler/exchange/live-keys/
|
||||
src/exchange/taler-exchange-aggregator
|
||||
|
@ -23,7 +23,7 @@ Overrides WIREFORMAT option from the configuation file.
|
||||
Print short help on options.
|
||||
.B
|
||||
.IP "\-t, \-\-test"
|
||||
Run in test mode (use temporary tables). Only useful for testcases.
|
||||
Run in test mode and exit when idle.
|
||||
.B
|
||||
.IP "\-v, \-\-version"
|
||||
Print version information.
|
||||
|
@ -47,15 +47,30 @@ endif
|
||||
endif
|
||||
|
||||
check_PROGRAMS = \
|
||||
test_bank_api
|
||||
test_bank_api \
|
||||
test_bank_api_with_fakebank
|
||||
|
||||
TESTS = \
|
||||
$(check_PROGRAMS)
|
||||
|
||||
test_bank_api_SOURCES = \
|
||||
test_bank_interpreter.c test_bank_interpreter.h \
|
||||
test_bank_api.c
|
||||
test_bank_api_LDADD = \
|
||||
libtalerbank.la \
|
||||
libfakebank.la \
|
||||
$(top_builddir)/src/util/libtalerutil.la \
|
||||
-lgnunetcurl \
|
||||
-lgnunetutil \
|
||||
-ljansson
|
||||
|
||||
|
||||
test_bank_api_with_fakebank_SOURCES = \
|
||||
test_bank_interpreter.c test_bank_interpreter.h \
|
||||
test_bank_api_with_fakebank.c
|
||||
test_bank_api_with_fakebank_LDADD = \
|
||||
libtalerbank.la \
|
||||
libfakebank.la \
|
||||
$(top_builddir)/src/util/libtalerutil.la \
|
||||
-lgnunetcurl \
|
||||
-lgnunetutil \
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
/**
|
||||
* @file bank/test_bank_api.c
|
||||
* @brief testcase to test bank's HTTP API interface
|
||||
* @brief testcase to test bank's HTTP API interface against the "real" bank
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
@ -25,440 +25,7 @@
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include <microhttpd.h>
|
||||
|
||||
|
||||
/**
|
||||
* Main execution context for the main loop.
|
||||
*/
|
||||
static struct GNUNET_CURL_Context *ctx;
|
||||
|
||||
/**
|
||||
* Task run on shutdown.
|
||||
*/
|
||||
static struct GNUNET_SCHEDULER_Task *shutdown_task;
|
||||
|
||||
/**
|
||||
* Task that runs the main event loop.
|
||||
*/
|
||||
static struct GNUNET_SCHEDULER_Task *ctx_task;
|
||||
|
||||
/**
|
||||
* Result of the testcases, #GNUNET_OK on success
|
||||
*/
|
||||
static int result;
|
||||
|
||||
|
||||
/**
|
||||
* Opcodes for the interpreter.
|
||||
*/
|
||||
enum OpCode
|
||||
{
|
||||
/**
|
||||
* Termination code, stops the interpreter loop (with success).
|
||||
*/
|
||||
OC_END = 0,
|
||||
|
||||
/**
|
||||
* Add funds to a reserve by (faking) incoming wire transfer.
|
||||
*/
|
||||
OC_ADMIN_ADD_INCOMING
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Details for a bank operation to execute.
|
||||
*/
|
||||
struct Command
|
||||
{
|
||||
/**
|
||||
* Opcode of the command.
|
||||
*/
|
||||
enum OpCode oc;
|
||||
|
||||
/**
|
||||
* Label for the command, can be NULL.
|
||||
*/
|
||||
const char *label;
|
||||
|
||||
/**
|
||||
* Which response code do we expect for this command?
|
||||
*/
|
||||
unsigned int expected_response_code;
|
||||
|
||||
/**
|
||||
* Details about the command.
|
||||
*/
|
||||
union
|
||||
{
|
||||
|
||||
/**
|
||||
* Information for a #OC_ADMIN_ADD_INCOMING command.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
|
||||
/**
|
||||
* String describing the amount to add to the reserve.
|
||||
*/
|
||||
const char *amount;
|
||||
|
||||
/**
|
||||
* Credited account number.
|
||||
*/
|
||||
uint64_t credit_account_no;
|
||||
|
||||
/**
|
||||
* Debited account number.
|
||||
*/
|
||||
uint64_t debit_account_no;
|
||||
|
||||
/**
|
||||
* Wire transfer identifier to use. Initialized to
|
||||
* a random value.
|
||||
*/
|
||||
struct TALER_WireTransferIdentifierRawP wtid;
|
||||
|
||||
/**
|
||||
* Set to the API's handle during the operation.
|
||||
*/
|
||||
struct TALER_BANK_AdminAddIncomingHandle *aih;
|
||||
|
||||
} admin_add_incoming;
|
||||
|
||||
} details;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* State of the interpreter loop.
|
||||
*/
|
||||
struct InterpreterState
|
||||
{
|
||||
/**
|
||||
* Keys from the bank.
|
||||
*/
|
||||
const struct TALER_BANK_Keys *keys;
|
||||
|
||||
/**
|
||||
* Commands the interpreter will run.
|
||||
*/
|
||||
struct Command *commands;
|
||||
|
||||
/**
|
||||
* Interpreter task (if one is scheduled).
|
||||
*/
|
||||
struct GNUNET_SCHEDULER_Task *task;
|
||||
|
||||
/**
|
||||
* Instruction pointer. Tells #interpreter_run() which
|
||||
* instruction to run next.
|
||||
*/
|
||||
unsigned int ip;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Task that runs the context's event loop with the GNUnet scheduler.
|
||||
*
|
||||
* @param cls unused
|
||||
*/
|
||||
static void
|
||||
context_task (void *cls);
|
||||
|
||||
|
||||
/**
|
||||
* Run the context task, the working set has changed.
|
||||
*/
|
||||
static void
|
||||
trigger_context_task ()
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (ctx_task);
|
||||
ctx_task = GNUNET_SCHEDULER_add_now (&context_task,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The testcase failed, return with an error code.
|
||||
*
|
||||
* @param is interpreter state to clean up
|
||||
*/
|
||||
static void
|
||||
fail (struct InterpreterState *is)
|
||||
{
|
||||
result = GNUNET_SYSERR;
|
||||
GNUNET_SCHEDULER_shutdown ();
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Find a command by label.
|
||||
*
|
||||
* @param is interpreter state to search
|
||||
* @param label label to look for
|
||||
* @return NULL if command was not found
|
||||
*/
|
||||
static const struct Command *
|
||||
find_command (const struct InterpreterState *is,
|
||||
const char *label)
|
||||
{
|
||||
unsigned int i;
|
||||
const struct Command *cmd;
|
||||
|
||||
if (NULL == label)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Attempt to lookup command for empty label\n");
|
||||
return NULL;
|
||||
}
|
||||
for (i=0;OC_END != (cmd = &is->commands[i])->oc;i++)
|
||||
if ( (NULL != cmd->label) &&
|
||||
(0 == strcmp (cmd->label,
|
||||
label)) )
|
||||
return cmd;
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Command not found: %s\n",
|
||||
label);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Run the main interpreter loop that performs bank operations.
|
||||
*
|
||||
* @param cls contains the `struct InterpreterState`
|
||||
*/
|
||||
static void
|
||||
interpreter_run (void *cls);
|
||||
|
||||
|
||||
/**
|
||||
* Function called upon completion of our /admin/add/incoming request.
|
||||
*
|
||||
* @param cls closure with the interpreter state
|
||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||
* 0 if the bank's reply is bogus (fails to follow the protocol)
|
||||
* @param json detailed response from the HTTPD, or NULL if reply was not in JSON
|
||||
*/
|
||||
static void
|
||||
add_incoming_cb (void *cls,
|
||||
unsigned int http_status,
|
||||
const json_t *json)
|
||||
{
|
||||
struct InterpreterState *is = cls;
|
||||
struct Command *cmd = &is->commands[is->ip];
|
||||
|
||||
cmd->details.admin_add_incoming.aih = NULL;
|
||||
if (cmd->expected_response_code != http_status)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
if (NULL != json)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Unexpected response code %u:\n",
|
||||
http_status);
|
||||
json_dumpf (json, stderr, 0);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
is->ip++;
|
||||
is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
|
||||
is);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the main interpreter loop that performs bank operations.
|
||||
*
|
||||
* @param cls contains the `struct InterpreterState`
|
||||
*/
|
||||
static void
|
||||
interpreter_run (void *cls)
|
||||
{
|
||||
struct InterpreterState *is = cls;
|
||||
struct Command *cmd = &is->commands[is->ip];
|
||||
struct TALER_Amount amount;
|
||||
const struct GNUNET_SCHEDULER_TaskContext *tc;
|
||||
|
||||
is->task = NULL;
|
||||
tc = GNUNET_SCHEDULER_get_task_context ();
|
||||
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Test aborted by shutdown request\n");
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
switch (cmd->oc)
|
||||
{
|
||||
case OC_END:
|
||||
result = GNUNET_OK;
|
||||
GNUNET_SCHEDULER_shutdown ();
|
||||
return;
|
||||
case OC_ADMIN_ADD_INCOMING:
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_string_to_amount (cmd->details.admin_add_incoming.amount,
|
||||
&amount))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to parse amount `%s' at %u\n",
|
||||
cmd->details.admin_add_incoming.amount,
|
||||
is->ip);
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
|
||||
&cmd->details.admin_add_incoming.wtid,
|
||||
sizeof (cmd->details.admin_add_incoming.wtid));
|
||||
cmd->details.admin_add_incoming.aih
|
||||
= TALER_BANK_admin_add_incoming (ctx,
|
||||
"http://localhost:8081",
|
||||
&cmd->details.admin_add_incoming.wtid,
|
||||
&amount,
|
||||
cmd->details.admin_add_incoming.debit_account_no,
|
||||
cmd->details.admin_add_incoming.credit_account_no,
|
||||
&add_incoming_cb,
|
||||
is);
|
||||
if (NULL == cmd->details.admin_add_incoming.aih)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
trigger_context_task ();
|
||||
return;
|
||||
default:
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unknown instruction %d at %u (%s)\n",
|
||||
cmd->oc,
|
||||
is->ip,
|
||||
cmd->label);
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function run when the test terminates (good or bad).
|
||||
* Cleans up our state.
|
||||
*
|
||||
* @param cls the interpreter state.
|
||||
*/
|
||||
static void
|
||||
do_shutdown (void *cls)
|
||||
{
|
||||
struct InterpreterState *is = cls;
|
||||
struct Command *cmd;
|
||||
unsigned int i;
|
||||
|
||||
shutdown_task = NULL;
|
||||
for (i=0;OC_END != (cmd = &is->commands[i])->oc;i++)
|
||||
{
|
||||
switch (cmd->oc)
|
||||
{
|
||||
case OC_END:
|
||||
GNUNET_assert (0);
|
||||
break;
|
||||
case OC_ADMIN_ADD_INCOMING:
|
||||
if (NULL != cmd->details.admin_add_incoming.aih)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Command %u (%s) did not complete\n",
|
||||
i,
|
||||
cmd->label);
|
||||
TALER_BANK_admin_add_incoming_cancel (cmd->details.admin_add_incoming.aih);
|
||||
cmd->details.admin_add_incoming.aih = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unknown instruction %d at %u (%s)\n",
|
||||
cmd->oc,
|
||||
i,
|
||||
cmd->label);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL != is->task)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (is->task);
|
||||
is->task = NULL;
|
||||
}
|
||||
GNUNET_free (is);
|
||||
if (NULL != ctx_task)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (ctx_task);
|
||||
ctx_task = NULL;
|
||||
}
|
||||
if (NULL != ctx)
|
||||
{
|
||||
GNUNET_CURL_fini (ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Task that runs the context's event loop with the GNUnet scheduler.
|
||||
*
|
||||
* @param cls unused
|
||||
*/
|
||||
static void
|
||||
context_task (void *cls)
|
||||
{
|
||||
long timeout;
|
||||
int max_fd;
|
||||
fd_set read_fd_set;
|
||||
fd_set write_fd_set;
|
||||
fd_set except_fd_set;
|
||||
struct GNUNET_NETWORK_FDSet *rs;
|
||||
struct GNUNET_NETWORK_FDSet *ws;
|
||||
struct GNUNET_TIME_Relative delay;
|
||||
|
||||
ctx_task = NULL;
|
||||
GNUNET_CURL_perform (ctx);
|
||||
max_fd = -1;
|
||||
timeout = -1;
|
||||
FD_ZERO (&read_fd_set);
|
||||
FD_ZERO (&write_fd_set);
|
||||
FD_ZERO (&except_fd_set);
|
||||
GNUNET_CURL_get_select_info (ctx,
|
||||
&read_fd_set,
|
||||
&write_fd_set,
|
||||
&except_fd_set,
|
||||
&max_fd,
|
||||
&timeout);
|
||||
if (timeout >= 0)
|
||||
delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
|
||||
timeout);
|
||||
else
|
||||
delay = GNUNET_TIME_UNIT_FOREVER_REL;
|
||||
rs = GNUNET_NETWORK_fdset_create ();
|
||||
GNUNET_NETWORK_fdset_copy_native (rs,
|
||||
&read_fd_set,
|
||||
max_fd + 1);
|
||||
ws = GNUNET_NETWORK_fdset_create ();
|
||||
GNUNET_NETWORK_fdset_copy_native (ws,
|
||||
&write_fd_set,
|
||||
max_fd + 1);
|
||||
ctx_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
|
||||
delay,
|
||||
rs,
|
||||
ws,
|
||||
&context_task,
|
||||
cls);
|
||||
GNUNET_NETWORK_fdset_destroy (rs);
|
||||
GNUNET_NETWORK_fdset_destroy (ws);
|
||||
}
|
||||
#include "test_bank_interpreter.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -469,33 +36,23 @@ context_task (void *cls)
|
||||
static void
|
||||
run (void *cls)
|
||||
{
|
||||
struct InterpreterState *is;
|
||||
static struct Command commands[] =
|
||||
int *resultp = cls;
|
||||
static struct TBI_Command commands[] =
|
||||
{
|
||||
/* Add EUR:5.01 to account 42 */
|
||||
{ .oc = OC_ADMIN_ADD_INCOMING,
|
||||
{ .oc = TBI_OC_ADMIN_ADD_INCOMING,
|
||||
.label = "deposit-1",
|
||||
.expected_response_code = MHD_HTTP_OK,
|
||||
.details.admin_add_incoming.credit_account_no = 1,
|
||||
.details.admin_add_incoming.debit_account_no = 2,
|
||||
.details.admin_add_incoming.amount = "PUDOS:5.01" },
|
||||
|
||||
{ .oc = OC_END }
|
||||
{ .oc = TBI_OC_END }
|
||||
};
|
||||
|
||||
is = GNUNET_new (struct InterpreterState);
|
||||
is->commands = commands;
|
||||
|
||||
ctx = GNUNET_CURL_init ();
|
||||
GNUNET_assert (NULL != ctx);
|
||||
ctx_task = GNUNET_SCHEDULER_add_now (&context_task,
|
||||
ctx);
|
||||
is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
|
||||
is);
|
||||
shutdown_task
|
||||
= GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
|
||||
(GNUNET_TIME_UNIT_SECONDS, 150),
|
||||
&do_shutdown, is);
|
||||
TBI_run_interpreter (resultp,
|
||||
GNUNET_NO /* we use the "real" taler bank */,
|
||||
commands);
|
||||
}
|
||||
|
||||
|
||||
@ -511,6 +68,7 @@ main (int argc,
|
||||
{
|
||||
struct GNUNET_OS_Process *bankd;
|
||||
unsigned int cnt;
|
||||
int result;
|
||||
|
||||
GNUNET_log_setup ("test-bank-api",
|
||||
"WARNING",
|
||||
@ -545,7 +103,7 @@ main (int argc,
|
||||
fprintf (stderr, "\n");
|
||||
result = GNUNET_SYSERR;
|
||||
if (cnt <= 30)
|
||||
GNUNET_SCHEDULER_run (&run, NULL);
|
||||
GNUNET_SCHEDULER_run (&run, &result);
|
||||
GNUNET_OS_process_kill (bankd,
|
||||
SIGTERM);
|
||||
GNUNET_OS_process_wait (bankd);
|
||||
|
78
src/bank-lib/test_bank_api_with_fakebank.c
Normal file
78
src/bank-lib/test_bank_api_with_fakebank.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2016 GNUnet e.V.
|
||||
|
||||
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, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file bank/test_bank_api_with_fakebank.c
|
||||
* @brief testcase to test bank's HTTP API interface against the fakebank
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "taler_util.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "taler_bank_service.h"
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include <microhttpd.h>
|
||||
#include "test_bank_interpreter.h"
|
||||
|
||||
|
||||
/**
|
||||
* Main function that will be run by the scheduler.
|
||||
*
|
||||
* @param cls closure
|
||||
*/
|
||||
static void
|
||||
run (void *cls)
|
||||
{
|
||||
int *resultp = cls;
|
||||
static struct TBI_Command commands[] =
|
||||
{
|
||||
/* Add EUR:5.01 to account 42 */
|
||||
{ .oc = TBI_OC_ADMIN_ADD_INCOMING,
|
||||
.label = "deposit-1",
|
||||
.expected_response_code = MHD_HTTP_OK,
|
||||
.details.admin_add_incoming.credit_account_no = 1,
|
||||
.details.admin_add_incoming.debit_account_no = 2,
|
||||
.details.admin_add_incoming.amount = "PUDOS:5.01" },
|
||||
|
||||
{ .oc = TBI_OC_END }
|
||||
};
|
||||
|
||||
TBI_run_interpreter (resultp,
|
||||
GNUNET_YES,
|
||||
commands);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main function for the testcase for the bank API.
|
||||
*
|
||||
* @param argc expected to be 1
|
||||
* @param argv expected to only contain the program name
|
||||
*/
|
||||
int
|
||||
main (int argc,
|
||||
char * const *argv)
|
||||
{
|
||||
int result;
|
||||
|
||||
GNUNET_log_setup ("test-bank-api-with-fakebank",
|
||||
"WARNING",
|
||||
NULL);
|
||||
GNUNET_SCHEDULER_run (&run, &result);
|
||||
return (GNUNET_OK == result) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* end of test_bank_api_with_fakebank.c */
|
361
src/bank-lib/test_bank_interpreter.c
Normal file
361
src/bank-lib/test_bank_interpreter.c
Normal file
@ -0,0 +1,361 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2016 GNUnet e.V.
|
||||
|
||||
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, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file bank/test_bank_interpreter.c
|
||||
* @brief interpreter for tests of the bank's HTTP API interface
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "taler_util.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "taler_bank_service.h"
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include <microhttpd.h>
|
||||
#include "test_bank_interpreter.h"
|
||||
#include "fakebank.h"
|
||||
|
||||
|
||||
/**
|
||||
* State of the interpreter loop.
|
||||
*/
|
||||
struct InterpreterState
|
||||
{
|
||||
/**
|
||||
* Keys from the bank.
|
||||
*/
|
||||
const struct TALER_BANK_Keys *keys;
|
||||
|
||||
/**
|
||||
* Commands the interpreter will run.
|
||||
*/
|
||||
struct TBI_Command *commands;
|
||||
|
||||
/**
|
||||
* Interpreter task (if one is scheduled).
|
||||
*/
|
||||
struct GNUNET_SCHEDULER_Task *task;
|
||||
|
||||
/**
|
||||
* Main execution context for the main loop.
|
||||
*/
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
|
||||
/**
|
||||
* Task run on timeout.
|
||||
*/
|
||||
struct GNUNET_SCHEDULER_Task *timeout_task;
|
||||
|
||||
/**
|
||||
* Context for running the main loop with GNUnet's SCHEDULER API.
|
||||
*/
|
||||
struct GNUNET_CURL_RescheduleContext *rc;
|
||||
|
||||
/**
|
||||
* Where to store the final result.
|
||||
*/
|
||||
int *resultp;
|
||||
|
||||
/**
|
||||
* Fakebank, or NULL if we are not using the fakebank.
|
||||
*/
|
||||
struct FAKEBANK_Handle *fakebank;
|
||||
|
||||
/**
|
||||
* Instruction pointer. Tells #interpreter_run() which
|
||||
* instruction to run next.
|
||||
*/
|
||||
unsigned int ip;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The testcase failed, return with an error code.
|
||||
*
|
||||
* @param is interpreter state to clean up
|
||||
*/
|
||||
static void
|
||||
fail (struct InterpreterState *is)
|
||||
{
|
||||
*is->resultp = GNUNET_SYSERR;
|
||||
GNUNET_SCHEDULER_shutdown ();
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Find a command by label.
|
||||
*
|
||||
* @param is interpreter state to search
|
||||
* @param label label to look for
|
||||
* @return NULL if command was not found
|
||||
*/
|
||||
static const struct TBI_Command *
|
||||
find_command (const struct InterpreterState *is,
|
||||
const char *label)
|
||||
{
|
||||
unsigned int i;
|
||||
const struct TBI_Command *cmd;
|
||||
|
||||
if (NULL == label)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Attempt to lookup command for empty label\n");
|
||||
return NULL;
|
||||
}
|
||||
for (i=0;TBI_OC_END != (cmd = &is->commands[i])->oc;i++)
|
||||
if ( (NULL != cmd->label) &&
|
||||
(0 == strcmp (cmd->label,
|
||||
label)) )
|
||||
return cmd;
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Command not found: %s\n",
|
||||
label);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Run the main interpreter loop that performs bank operations.
|
||||
*
|
||||
* @param cls contains the `struct InterpreterState`
|
||||
*/
|
||||
static void
|
||||
interpreter_run (void *cls);
|
||||
|
||||
|
||||
/**
|
||||
* Function called upon completion of our /admin/add/incoming request.
|
||||
*
|
||||
* @param cls closure with the interpreter state
|
||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||
* 0 if the bank's reply is bogus (fails to follow the protocol)
|
||||
* @param json detailed response from the HTTPD, or NULL if reply was not in JSON
|
||||
*/
|
||||
static void
|
||||
add_incoming_cb (void *cls,
|
||||
unsigned int http_status,
|
||||
const json_t *json)
|
||||
{
|
||||
struct InterpreterState *is = cls;
|
||||
struct TBI_Command *cmd = &is->commands[is->ip];
|
||||
|
||||
cmd->details.admin_add_incoming.aih = NULL;
|
||||
if (cmd->expected_response_code != http_status)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
fprintf (stderr,
|
||||
"Unexpected response code %u:\n",
|
||||
http_status);
|
||||
if (NULL != json)
|
||||
{
|
||||
json_dumpf (json, stderr, 0);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
is->ip++;
|
||||
is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
|
||||
is);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the main interpreter loop that performs bank operations.
|
||||
*
|
||||
* @param cls contains the `struct InterpreterState`
|
||||
*/
|
||||
static void
|
||||
interpreter_run (void *cls)
|
||||
{
|
||||
struct InterpreterState *is = cls;
|
||||
struct TBI_Command *cmd = &is->commands[is->ip];
|
||||
struct TALER_Amount amount;
|
||||
const struct GNUNET_SCHEDULER_TaskContext *tc;
|
||||
|
||||
is->task = NULL;
|
||||
tc = GNUNET_SCHEDULER_get_task_context ();
|
||||
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Test aborted by shutdown request\n");
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
switch (cmd->oc)
|
||||
{
|
||||
case TBI_OC_END:
|
||||
*is->resultp = GNUNET_OK;
|
||||
GNUNET_SCHEDULER_shutdown ();
|
||||
return;
|
||||
case TBI_OC_ADMIN_ADD_INCOMING:
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_string_to_amount (cmd->details.admin_add_incoming.amount,
|
||||
&amount))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to parse amount `%s' at %u\n",
|
||||
cmd->details.admin_add_incoming.amount,
|
||||
is->ip);
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
|
||||
&cmd->details.admin_add_incoming.wtid,
|
||||
sizeof (cmd->details.admin_add_incoming.wtid));
|
||||
cmd->details.admin_add_incoming.aih
|
||||
= TALER_BANK_admin_add_incoming (is->ctx,
|
||||
"http://localhost:8081",
|
||||
&cmd->details.admin_add_incoming.wtid,
|
||||
&amount,
|
||||
cmd->details.admin_add_incoming.debit_account_no,
|
||||
cmd->details.admin_add_incoming.credit_account_no,
|
||||
&add_incoming_cb,
|
||||
is);
|
||||
if (NULL == cmd->details.admin_add_incoming.aih)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
default:
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unknown instruction %d at %u (%s)\n",
|
||||
cmd->oc,
|
||||
is->ip,
|
||||
cmd->label);
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function run on timeout.
|
||||
*
|
||||
* @param cls the `struct InterpreterState`
|
||||
*/
|
||||
static void
|
||||
do_timeout (void *cls)
|
||||
{
|
||||
struct InterpreterState *is = cls;
|
||||
|
||||
is->timeout_task = NULL;
|
||||
GNUNET_SCHEDULER_shutdown ();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function run when the test terminates (good or bad).
|
||||
* Cleans up our state.
|
||||
*
|
||||
* @param cls the interpreter state.
|
||||
*/
|
||||
static void
|
||||
do_shutdown (void *cls)
|
||||
{
|
||||
struct InterpreterState *is = cls;
|
||||
struct TBI_Command *cmd;
|
||||
unsigned int i;
|
||||
|
||||
if (NULL != is->timeout_task)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (is->timeout_task);
|
||||
is->timeout_task = NULL;
|
||||
}
|
||||
|
||||
for (i=0;TBI_OC_END != (cmd = &is->commands[i])->oc;i++)
|
||||
{
|
||||
switch (cmd->oc)
|
||||
{
|
||||
case TBI_OC_END:
|
||||
GNUNET_assert (0);
|
||||
break;
|
||||
case TBI_OC_ADMIN_ADD_INCOMING:
|
||||
if (NULL != cmd->details.admin_add_incoming.aih)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Command %u (%s) did not complete\n",
|
||||
i,
|
||||
cmd->label);
|
||||
TALER_BANK_admin_add_incoming_cancel (cmd->details.admin_add_incoming.aih);
|
||||
cmd->details.admin_add_incoming.aih = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unknown instruction %d at %u (%s)\n",
|
||||
cmd->oc,
|
||||
i,
|
||||
cmd->label);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL != is->task)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (is->task);
|
||||
is->task = NULL;
|
||||
}
|
||||
if (NULL != is->fakebank)
|
||||
{
|
||||
FAKEBANK_stop (is->fakebank);
|
||||
is->fakebank = NULL;
|
||||
}
|
||||
GNUNET_CURL_fini (is->ctx);
|
||||
is->ctx = NULL;
|
||||
GNUNET_CURL_gnunet_rc_destroy (is->rc);
|
||||
GNUNET_free (is);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Entry point to the interpeter.
|
||||
*
|
||||
* @param resultp where to store the final result
|
||||
* @param run_bank #GNUNET_YES to run the fakebank
|
||||
* @param commands list of commands to run
|
||||
*/
|
||||
void
|
||||
TBI_run_interpreter (int *resultp,
|
||||
int run_bank,
|
||||
struct TBI_Command *commands)
|
||||
{
|
||||
struct InterpreterState *is;
|
||||
|
||||
is = GNUNET_new (struct InterpreterState);
|
||||
if (GNUNET_YES == run_bank)
|
||||
is->fakebank = FAKEBANK_start (8081);
|
||||
is->resultp = resultp;
|
||||
is->commands = commands;
|
||||
is->ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
|
||||
&is->rc);
|
||||
GNUNET_assert (NULL != is->ctx);
|
||||
is->rc = GNUNET_CURL_gnunet_rc_create (is->ctx);
|
||||
is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
|
||||
is);
|
||||
is->timeout_task
|
||||
= GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
|
||||
(GNUNET_TIME_UNIT_SECONDS, 150),
|
||||
&do_timeout, is);
|
||||
GNUNET_SCHEDULER_add_shutdown (&do_shutdown, is);
|
||||
}
|
||||
|
||||
/* end of test_bank_interpeter.c */
|
127
src/bank-lib/test_bank_interpreter.h
Normal file
127
src/bank-lib/test_bank_interpreter.h
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2016 GNUnet e.V.
|
||||
|
||||
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, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file bank/test_bank_interpreter.h
|
||||
* @brief interpreter for tests of the bank's HTTP API interface
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#ifndef TEST_BANK_INTERPRETER_H
|
||||
#define TEST_BANK_INTERPRETER_H
|
||||
|
||||
#include "taler_util.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "taler_bank_service.h"
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include <microhttpd.h>
|
||||
|
||||
|
||||
/**
|
||||
* Opcodes for the interpreter.
|
||||
*/
|
||||
enum TBI_OpCode
|
||||
{
|
||||
/**
|
||||
* Termination code, stops the interpreter loop (with success).
|
||||
*/
|
||||
TBI_OC_END = 0,
|
||||
|
||||
/**
|
||||
* Add funds to a reserve by (faking) incoming wire transfer.
|
||||
*/
|
||||
TBI_OC_ADMIN_ADD_INCOMING
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Details for a bank operation to execute.
|
||||
*/
|
||||
struct TBI_Command
|
||||
{
|
||||
/**
|
||||
* Opcode of the command.
|
||||
*/
|
||||
enum TBI_OpCode oc;
|
||||
|
||||
/**
|
||||
* Label for the command, can be NULL.
|
||||
*/
|
||||
const char *label;
|
||||
|
||||
/**
|
||||
* Which response code do we expect for this command?
|
||||
*/
|
||||
unsigned int expected_response_code;
|
||||
|
||||
/**
|
||||
* Details about the command.
|
||||
*/
|
||||
union
|
||||
{
|
||||
|
||||
/**
|
||||
* Information for a #TBI_OC_ADMIN_ADD_INCOMING command.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
|
||||
/**
|
||||
* String describing the amount to add to the reserve.
|
||||
*/
|
||||
const char *amount;
|
||||
|
||||
/**
|
||||
* Credited account number.
|
||||
*/
|
||||
uint64_t credit_account_no;
|
||||
|
||||
/**
|
||||
* Debited account number.
|
||||
*/
|
||||
uint64_t debit_account_no;
|
||||
|
||||
/**
|
||||
* Wire transfer identifier to use. Initialized to
|
||||
* a random value.
|
||||
*/
|
||||
struct TALER_WireTransferIdentifierRawP wtid;
|
||||
|
||||
/**
|
||||
* Set to the API's handle during the operation.
|
||||
*/
|
||||
struct TALER_BANK_AdminAddIncomingHandle *aih;
|
||||
|
||||
} admin_add_incoming;
|
||||
|
||||
} details;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Entry point to the interpeter.
|
||||
*
|
||||
* @param resultp where to store the final result
|
||||
* @param run_bank #GNUNET_YES to run the fakebank
|
||||
* @param commands list of commands to run
|
||||
*/
|
||||
void
|
||||
TBI_run_interpreter (int *resultp,
|
||||
int run_bank,
|
||||
struct TBI_Command *commands);
|
||||
|
||||
#endif
|
@ -247,7 +247,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
|
||||
{
|
||||
struct GNUNET_TIME_Absolute valid_from;
|
||||
struct GNUNET_TIME_Absolute withdraw_valid_until;
|
||||
struct GNUNET_TIME_Absolute deposit_valid_until;
|
||||
struct GNUNET_TIME_Absolute expire_deposit;
|
||||
struct GNUNET_TIME_Absolute expire_legal;
|
||||
struct TALER_Amount value;
|
||||
struct TALER_Amount fee_withdraw;
|
||||
@ -262,7 +262,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
|
||||
GNUNET_JSON_spec_fixed_auto ("master_sig",
|
||||
&sig),
|
||||
GNUNET_JSON_spec_absolute_time ("stamp_expire_deposit",
|
||||
&deposit_valid_until),
|
||||
&expire_deposit),
|
||||
GNUNET_JSON_spec_absolute_time ("stamp_expire_withdraw",
|
||||
&withdraw_valid_until),
|
||||
GNUNET_JSON_spec_absolute_time ("stamp_start",
|
||||
@ -302,7 +302,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
|
||||
denom_key_issue.master = *master_key;
|
||||
denom_key_issue.start = GNUNET_TIME_absolute_hton (valid_from);
|
||||
denom_key_issue.expire_withdraw = GNUNET_TIME_absolute_hton (withdraw_valid_until);
|
||||
denom_key_issue.expire_spend = GNUNET_TIME_absolute_hton (deposit_valid_until);
|
||||
denom_key_issue.expire_deposit = GNUNET_TIME_absolute_hton (expire_deposit);
|
||||
denom_key_issue.expire_legal = GNUNET_TIME_absolute_hton (expire_legal);
|
||||
TALER_amount_hton (&denom_key_issue.value,
|
||||
&value);
|
||||
@ -326,7 +326,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
|
||||
denom_key->h_key = denom_key_issue.denom_hash;
|
||||
denom_key->valid_from = valid_from;
|
||||
denom_key->withdraw_valid_until = withdraw_valid_until;
|
||||
denom_key->deposit_valid_until = deposit_valid_until;
|
||||
denom_key->expire_deposit = expire_deposit;
|
||||
denom_key->expire_legal = expire_legal;
|
||||
denom_key->value = value;
|
||||
denom_key->fee_withdraw = fee_withdraw;
|
||||
@ -431,7 +431,7 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
|
||||
}
|
||||
kv.start = GNUNET_TIME_absolute_hton (dk->valid_from);
|
||||
kv.expire_withdraw = GNUNET_TIME_absolute_hton (dk->withdraw_valid_until);
|
||||
kv.expire_spend = GNUNET_TIME_absolute_hton (dk->deposit_valid_until);
|
||||
kv.expire_deposit = GNUNET_TIME_absolute_hton (dk->expire_deposit);
|
||||
kv.expire_legal = GNUNET_TIME_absolute_hton (dk->expire_legal);
|
||||
TALER_amount_hton (&kv.value,
|
||||
&dk->value);
|
||||
|
@ -73,7 +73,7 @@ struct MeltedCoinP
|
||||
/**
|
||||
* Timestamp indicating when coins of this denomination become invalid.
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO deposit_valid_until;
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_deposit;
|
||||
|
||||
/**
|
||||
* Size of the encoded public key that follows.
|
||||
@ -189,7 +189,7 @@ struct MeltedCoin
|
||||
/**
|
||||
* Timestamp indicating when coins of this denomination become invalid.
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute deposit_valid_until;
|
||||
struct GNUNET_TIME_Absolute expire_deposit;
|
||||
|
||||
/**
|
||||
* Denomination key of the original coin.
|
||||
@ -396,7 +396,7 @@ serialize_melted_coin (const struct MeltedCoin *mc,
|
||||
&mc->original_value);
|
||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
||||
mcp.transfer_priv[i] = mc->transfer_priv[i];
|
||||
mcp.deposit_valid_until = GNUNET_TIME_absolute_hton (mc->deposit_valid_until);
|
||||
mcp.expire_deposit = GNUNET_TIME_absolute_hton (mc->expire_deposit);
|
||||
mcp.pbuf_size = htons ((uint16_t) pbuf_size);
|
||||
mcp.sbuf_size = htons ((uint16_t) sbuf_size);
|
||||
memcpy (&buf[off],
|
||||
@ -478,7 +478,7 @@ deserialize_melted_coin (struct MeltedCoin *mc,
|
||||
&mcp.original_value);
|
||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
||||
mc->transfer_priv[i] = mcp.transfer_priv[i];
|
||||
mc->deposit_valid_until = GNUNET_TIME_absolute_ntoh (mcp.deposit_valid_until);
|
||||
mc->expire_deposit = GNUNET_TIME_absolute_ntoh (mcp.expire_deposit);
|
||||
return off;
|
||||
}
|
||||
|
||||
@ -891,8 +891,8 @@ TALER_EXCHANGE_refresh_prepare (unsigned int num_melts,
|
||||
md.melted_coins[i].transfer_priv[j].ecdhe_priv = *tpk;
|
||||
GNUNET_free (tpk);
|
||||
}
|
||||
md.melted_coins[i].deposit_valid_until
|
||||
= melt_pks[i].deposit_valid_until;
|
||||
md.melted_coins[i].expire_deposit
|
||||
= melt_pks[i].expire_deposit;
|
||||
md.melted_coins[i].pub_key.rsa_public_key
|
||||
= GNUNET_CRYPTO_rsa_public_key_dup (melt_pks[i].key.rsa_public_key);
|
||||
md.melted_coins[i].sig.rsa_signature
|
||||
|
@ -48,14 +48,14 @@ static struct GNUNET_CURL_Context *ctx;
|
||||
static struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* Task run on shutdown.
|
||||
* Context for running the CURL event loop.
|
||||
*/
|
||||
static struct GNUNET_SCHEDULER_Task *shutdown_task;
|
||||
static struct GNUNET_CURL_RescheduleContext *rc;
|
||||
|
||||
/**
|
||||
* Task that runs the main event loop.
|
||||
* Task run on timeout.
|
||||
*/
|
||||
static struct GNUNET_SCHEDULER_Task *ctx_task;
|
||||
static struct GNUNET_SCHEDULER_Task *timeout_task;
|
||||
|
||||
/**
|
||||
* Result of the testcases, #GNUNET_OK on success
|
||||
@ -569,27 +569,6 @@ struct InterpreterState
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Task that runs the context's event loop with the GNUnet scheduler.
|
||||
*
|
||||
* @param cls unused
|
||||
*/
|
||||
static void
|
||||
context_task (void *cls);
|
||||
|
||||
|
||||
/**
|
||||
* Run the context task, the working set has changed.
|
||||
*/
|
||||
static void
|
||||
trigger_context_task ()
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (ctx_task);
|
||||
ctx_task = GNUNET_SCHEDULER_add_now (&context_task,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The testcase failed, return with an error code.
|
||||
*
|
||||
@ -1499,7 +1478,6 @@ interpreter_run (void *cls)
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
trigger_context_task ();
|
||||
return;
|
||||
case OC_WITHDRAW_STATUS:
|
||||
GNUNET_assert (NULL !=
|
||||
@ -1515,7 +1493,6 @@ interpreter_run (void *cls)
|
||||
&reserve_pub,
|
||||
&reserve_status_cb,
|
||||
is);
|
||||
trigger_context_task ();
|
||||
return;
|
||||
case OC_WITHDRAW_SIGN:
|
||||
GNUNET_assert (NULL !=
|
||||
@ -1575,7 +1552,6 @@ interpreter_run (void *cls)
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
trigger_context_task ();
|
||||
return;
|
||||
case OC_DEPOSIT:
|
||||
{
|
||||
@ -1728,7 +1704,6 @@ interpreter_run (void *cls)
|
||||
return;
|
||||
}
|
||||
json_decref (wire);
|
||||
trigger_context_task ();
|
||||
return;
|
||||
}
|
||||
case OC_REFRESH_MELT:
|
||||
@ -1826,7 +1801,6 @@ interpreter_run (void *cls)
|
||||
}
|
||||
}
|
||||
}
|
||||
trigger_context_task ();
|
||||
return;
|
||||
case OC_REFRESH_REVEAL:
|
||||
ref = find_command (is,
|
||||
@ -1845,7 +1819,6 @@ interpreter_run (void *cls)
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
trigger_context_task ();
|
||||
return;
|
||||
case OC_REFRESH_LINK:
|
||||
/* find reveal command */
|
||||
@ -1885,13 +1858,11 @@ interpreter_run (void *cls)
|
||||
fail (is);
|
||||
return;
|
||||
}
|
||||
trigger_context_task ();
|
||||
return;
|
||||
case OC_WIRE:
|
||||
cmd->details.wire.wh = TALER_EXCHANGE_wire (exchange,
|
||||
&wire_cb,
|
||||
is);
|
||||
trigger_context_task ();
|
||||
return;
|
||||
case OC_WIRE_DEPOSITS:
|
||||
if (NULL != cmd->details.wire_deposits.wtid_ref)
|
||||
@ -1906,7 +1877,6 @@ interpreter_run (void *cls)
|
||||
&cmd->details.wire_deposits.wtid,
|
||||
&wire_deposits_cb,
|
||||
is);
|
||||
trigger_context_task ();
|
||||
return;
|
||||
case OC_DEPOSIT_WTID:
|
||||
{
|
||||
@ -1969,7 +1939,6 @@ interpreter_run (void *cls)
|
||||
ref->details.deposit.transaction_id,
|
||||
&deposit_wtid_cb,
|
||||
is);
|
||||
trigger_context_task ();
|
||||
}
|
||||
return;
|
||||
default:
|
||||
@ -1984,6 +1953,19 @@ interpreter_run (void *cls)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function run when the test terminates (good or bad) with timeout.
|
||||
*
|
||||
* @param cls NULL
|
||||
*/
|
||||
static void
|
||||
do_timeout (void *cls)
|
||||
{
|
||||
timeout_task = NULL;
|
||||
GNUNET_SCHEDULER_shutdown ();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function run when the test terminates (good or bad).
|
||||
* Cleans up our state.
|
||||
@ -1997,7 +1979,6 @@ do_shutdown (void *cls)
|
||||
struct Command *cmd;
|
||||
unsigned int i;
|
||||
|
||||
shutdown_task = NULL;
|
||||
for (i=0;OC_END != (cmd = &is->commands[i])->oc;i++)
|
||||
{
|
||||
switch (cmd->oc)
|
||||
@ -2156,11 +2137,6 @@ do_shutdown (void *cls)
|
||||
is->task = NULL;
|
||||
}
|
||||
GNUNET_free (is);
|
||||
if (NULL != ctx_task)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (ctx_task);
|
||||
ctx_task = NULL;
|
||||
}
|
||||
if (NULL != exchange)
|
||||
{
|
||||
TALER_EXCHANGE_disconnect (exchange);
|
||||
@ -2171,6 +2147,16 @@ do_shutdown (void *cls)
|
||||
GNUNET_CURL_fini (ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
if (NULL != rc)
|
||||
{
|
||||
GNUNET_CURL_gnunet_rc_destroy (rc);
|
||||
rc = NULL;
|
||||
}
|
||||
if (NULL != timeout_task)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (timeout_task);
|
||||
timeout_task = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2208,60 +2194,6 @@ cert_cb (void *cls,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Task that runs the context's event loop with the GNUnet scheduler.
|
||||
*
|
||||
* @param cls unused
|
||||
*/
|
||||
static void
|
||||
context_task (void *cls)
|
||||
{
|
||||
long timeout;
|
||||
int max_fd;
|
||||
fd_set read_fd_set;
|
||||
fd_set write_fd_set;
|
||||
fd_set except_fd_set;
|
||||
struct GNUNET_NETWORK_FDSet *rs;
|
||||
struct GNUNET_NETWORK_FDSet *ws;
|
||||
struct GNUNET_TIME_Relative delay;
|
||||
|
||||
ctx_task = NULL;
|
||||
GNUNET_CURL_perform (ctx);
|
||||
max_fd = -1;
|
||||
timeout = -1;
|
||||
FD_ZERO (&read_fd_set);
|
||||
FD_ZERO (&write_fd_set);
|
||||
FD_ZERO (&except_fd_set);
|
||||
GNUNET_CURL_get_select_info (ctx,
|
||||
&read_fd_set,
|
||||
&write_fd_set,
|
||||
&except_fd_set,
|
||||
&max_fd,
|
||||
&timeout);
|
||||
if (timeout >= 0)
|
||||
delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
|
||||
timeout);
|
||||
else
|
||||
delay = GNUNET_TIME_UNIT_FOREVER_REL;
|
||||
rs = GNUNET_NETWORK_fdset_create ();
|
||||
GNUNET_NETWORK_fdset_copy_native (rs,
|
||||
&read_fd_set,
|
||||
max_fd + 1);
|
||||
ws = GNUNET_NETWORK_fdset_create ();
|
||||
GNUNET_NETWORK_fdset_copy_native (ws,
|
||||
&write_fd_set,
|
||||
max_fd + 1);
|
||||
ctx_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
|
||||
delay,
|
||||
rs,
|
||||
ws,
|
||||
&context_task,
|
||||
cls);
|
||||
GNUNET_NETWORK_fdset_destroy (rs);
|
||||
GNUNET_NETWORK_fdset_destroy (ws);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main function that will be run by the scheduler.
|
||||
*
|
||||
@ -2507,19 +2439,20 @@ run (void *cls)
|
||||
is = GNUNET_new (struct InterpreterState);
|
||||
is->commands = commands;
|
||||
|
||||
ctx = GNUNET_CURL_init ();
|
||||
ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
|
||||
&rc);
|
||||
rc = GNUNET_CURL_gnunet_rc_create (ctx);
|
||||
GNUNET_assert (NULL != ctx);
|
||||
ctx_task = GNUNET_SCHEDULER_add_now (&context_task,
|
||||
ctx);
|
||||
exchange = TALER_EXCHANGE_connect (ctx,
|
||||
"http://localhost:8081",
|
||||
&cert_cb, is,
|
||||
TALER_EXCHANGE_OPTION_END);
|
||||
GNUNET_assert (NULL != exchange);
|
||||
shutdown_task
|
||||
timeout_task
|
||||
= GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
|
||||
(GNUNET_TIME_UNIT_SECONDS, 150),
|
||||
&do_shutdown, is);
|
||||
&do_timeout, NULL);
|
||||
GNUNET_SCHEDULER_add_shutdown (&do_shutdown, is);
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,12 +30,17 @@ TESTRUN = YES
|
||||
[exchangedb-postgres]
|
||||
DB_CONN_STR = "postgres:///talercheck"
|
||||
|
||||
[wire-incoming-test]
|
||||
[exchange-wire-incoming-sepa]
|
||||
# This is the response we give out for the /wire request. It provides
|
||||
# wallets with the bank information for transfers to the exchange.
|
||||
SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json
|
||||
|
||||
[exchange-wire-incoming-test]
|
||||
# This is the response we give out for the /wire request. It provides
|
||||
# wallets with the bank information for transfers to the exchange.
|
||||
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json
|
||||
|
||||
[wire-outgoing-test]
|
||||
[exchange-wire-outgoing-test]
|
||||
# What is the main website of the bank?
|
||||
BANK_URI = "http://localhost:8082/"
|
||||
# Into which account at the 'bank' should (incoming) wire transfers be made?
|
||||
|
@ -118,7 +118,7 @@ print_dk (const struct TALER_DenominationKeyValidityPS *dk)
|
||||
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_withdraw)));
|
||||
fprintf (stdout,
|
||||
"Deposit end time: %s\n",
|
||||
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_spend)));
|
||||
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_deposit)));
|
||||
fprintf (stdout,
|
||||
"Legal dispute end time: %s\n",
|
||||
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_legal)));
|
||||
@ -320,7 +320,7 @@ main (int argc,
|
||||
print_dk (dk);
|
||||
kv.start = dk->start;
|
||||
kv.expire_withdraw = dk->expire_withdraw;
|
||||
kv.expire_spend = dk->expire_spend;
|
||||
kv.expire_deposit = dk->expire_deposit;
|
||||
kv.expire_legal = dk->expire_legal;
|
||||
kv.value = dk->value;
|
||||
kv.fee_withdraw = dk->fee_withdraw;
|
||||
|
@ -54,8 +54,7 @@ run (void *cls,
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
plugin->create_tables (plugin->cls,
|
||||
GNUNET_NO))
|
||||
plugin->create_tables (plugin->cls))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to initialize database.\n");
|
||||
|
@ -145,7 +145,7 @@ denomkeys_iter (void *cls,
|
||||
if ( (0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.start).abs_value_us % 1000000) ||
|
||||
(0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_withdraw).abs_value_us % 1000000) ||
|
||||
(0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_legal).abs_value_us % 1000000) ||
|
||||
(0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_spend).abs_value_us % 1000000) )
|
||||
(0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit).abs_value_us % 1000000) )
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Timestamps are not multiples of a round second\n");
|
||||
|
@ -765,7 +765,7 @@ create_denomkey_issue (const struct CoinTypeParams *params,
|
||||
dki->issue.properties.expire_withdraw =
|
||||
GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (params->anchor,
|
||||
params->duration_withdraw));
|
||||
dki->issue.properties.expire_spend =
|
||||
dki->issue.properties.expire_deposit =
|
||||
GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (params->anchor,
|
||||
params->duration_spend));
|
||||
dki->issue.properties.expire_legal =
|
||||
|
@ -73,8 +73,7 @@ run_transaction (const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
int ret;
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
|
||||
session = plugin->get_session (plugin->cls,
|
||||
GNUNET_NO);
|
||||
session = plugin->get_session (plugin->cls);
|
||||
if (NULL == session)
|
||||
{
|
||||
fprintf (stderr,
|
||||
|
@ -173,7 +173,7 @@ static struct AggregationUnit *au;
|
||||
static int global_ret;
|
||||
|
||||
/**
|
||||
* #GNUNET_YES if we are in test mode and are using temporary tables.
|
||||
* #GNUNET_YES if we are in test mode and should exit when idle.
|
||||
*/
|
||||
static int test_mode;
|
||||
|
||||
@ -518,8 +518,7 @@ run_aggregation (void *cls)
|
||||
return;
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Checking for ready deposits to aggregate\n");
|
||||
if (NULL == (session = db_plugin->get_session (db_plugin->cls,
|
||||
test_mode)))
|
||||
if (NULL == (session = db_plugin->get_session (db_plugin->cls)))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to obtain database session!\n");
|
||||
@ -891,8 +890,7 @@ run_transfers (void *cls)
|
||||
tc = GNUNET_SCHEDULER_get_task_context ();
|
||||
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
|
||||
return;
|
||||
if (NULL == (session = db_plugin->get_session (db_plugin->cls,
|
||||
test_mode)))
|
||||
if (NULL == (session = db_plugin->get_session (db_plugin->cls)))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to obtain database session!\n");
|
||||
@ -987,7 +985,7 @@ main (int argc,
|
||||
"wireformat to use, overrides WIREFORMAT option in [exchange] section", 1,
|
||||
&GNUNET_GETOPT_set_filename, &exchange_wireformat},
|
||||
{'t', "test", NULL,
|
||||
"run in test mode with temporary tables", 0,
|
||||
"run in test mode and exit when idle", 0,
|
||||
&GNUNET_GETOPT_set_one, &test_mode},
|
||||
GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION),
|
||||
GNUNET_GETOPT_OPTION_END
|
||||
|
@ -80,11 +80,6 @@ struct TALER_MasterPublicKeyP TMH_master_public_key;
|
||||
*/
|
||||
struct TALER_EXCHANGEDB_Plugin *TMH_plugin;
|
||||
|
||||
/**
|
||||
* Are we running in test mode?
|
||||
*/
|
||||
int TMH_test_mode;
|
||||
|
||||
/**
|
||||
* Default timeout in seconds for HTTP requests.
|
||||
*/
|
||||
@ -466,9 +461,7 @@ exchange_serve_process_config ()
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Running in TEST mode! Database contents will not persist!\n");
|
||||
TMH_test_mode = GNUNET_YES;
|
||||
TMH_plugin->create_tables (TMH_plugin->cls,
|
||||
GNUNET_YES);
|
||||
TMH_plugin->create_tables (TMH_plugin->cls);
|
||||
}
|
||||
|
||||
{
|
||||
@ -906,19 +899,6 @@ main (int argc,
|
||||
MHD_stop_daemon (mydaemon);
|
||||
break;
|
||||
}
|
||||
|
||||
if (GNUNET_YES == TMH_test_mode)
|
||||
{
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
|
||||
session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
GNUNET_YES);
|
||||
if (NULL == session)
|
||||
GNUNET_break (0);
|
||||
else
|
||||
TMH_plugin->drop_temporary (TMH_plugin->cls,
|
||||
session);
|
||||
}
|
||||
TALER_EXCHANGEDB_plugin_unload (TMH_plugin);
|
||||
TMH_VALIDATION_done ();
|
||||
return (GNUNET_SYSERR == ret) ? 1 : 0;
|
||||
|
@ -43,11 +43,6 @@ extern int TMH_exchange_connection_close;
|
||||
*/
|
||||
extern struct GNUNET_CONFIGURATION_Handle *cfg;
|
||||
|
||||
/**
|
||||
* Are we running in test mode?
|
||||
*/
|
||||
extern int TMH_test_mode;
|
||||
|
||||
/**
|
||||
* Main directory with exchange data.
|
||||
*/
|
||||
|
@ -160,8 +160,7 @@ TMH_DB_execute_deposit (struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||
int ret;
|
||||
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
@ -278,8 +277,7 @@ TMH_DB_execute_reserve_status (struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_ReserveHistory *rh;
|
||||
int res;
|
||||
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
@ -524,8 +522,7 @@ TMH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
|
||||
GNUNET_CRYPTO_hash (blinded_msg,
|
||||
blinded_msg_len,
|
||||
&h_blind);
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
@ -725,8 +722,7 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
||||
int res;
|
||||
unsigned int i;
|
||||
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
@ -1237,8 +1233,7 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
|
||||
unsigned int j;
|
||||
unsigned int off;
|
||||
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
@ -1465,8 +1460,7 @@ TMH_DB_execute_refresh_link (struct MHD_Connection *connection,
|
||||
int res;
|
||||
unsigned int i;
|
||||
|
||||
if (NULL == (ctx.session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (ctx.session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
@ -1528,8 +1522,7 @@ TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
int ret;
|
||||
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
@ -1713,8 +1706,7 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
struct TMH_WireDepositDetail *wdd;
|
||||
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
@ -1879,8 +1871,7 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection,
|
||||
struct DepositWtidContext ctx;
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode)))
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
|
@ -155,7 +155,7 @@ denom_key_issue_to_json (const struct TALER_DenominationPublicKey *pk,
|
||||
"stamp_expire_withdraw",
|
||||
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_withdraw)),
|
||||
"stamp_expire_deposit",
|
||||
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_spend)),
|
||||
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_deposit)),
|
||||
"stamp_expire_legal",
|
||||
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_legal)),
|
||||
"denom_pub",
|
||||
@ -236,7 +236,7 @@ reload_keys_denom_iter (void *cls,
|
||||
return GNUNET_OK;
|
||||
}
|
||||
now = GNUNET_TIME_absolute_get ();
|
||||
if (GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_spend).abs_value_us <
|
||||
if (GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit).abs_value_us <
|
||||
now.abs_value_us)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
@ -250,8 +250,7 @@ reload_keys_denom_iter (void *cls,
|
||||
GNUNET_CRYPTO_hash_context_read (ctx->hash_context,
|
||||
&denom_key_hash,
|
||||
sizeof (struct GNUNET_HashCode));
|
||||
session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
TMH_test_mode);
|
||||
session = TMH_plugin->get_session (TMH_plugin->cls);
|
||||
if (NULL == session)
|
||||
return GNUNET_SYSERR;
|
||||
/* Try to insert DKI into DB until we succeed; note that if the DB
|
||||
@ -749,7 +748,7 @@ TMH_KS_denomination_key_lookup (const struct TMH_KS_StateHandle *key_state,
|
||||
break;
|
||||
case TMH_KS_DKU_DEPOSIT:
|
||||
if (now.abs_value_us >
|
||||
GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_spend).abs_value_us)
|
||||
GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit).abs_value_us)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Not returning DKI for %s, as time to spend coin has passed\n",
|
||||
|
@ -285,8 +285,8 @@ shutdown_action (void *cls)
|
||||
GNUNET_OS_process_destroy (aggregator_proc);
|
||||
aggregator_proc = NULL;
|
||||
}
|
||||
plugin->drop_temporary (plugin->cls,
|
||||
session);
|
||||
plugin->drop_tables (plugin->cls,
|
||||
session);
|
||||
TALER_EXCHANGEDB_plugin_unload (plugin);
|
||||
plugin = NULL;
|
||||
}
|
||||
@ -304,11 +304,9 @@ maint_child_death (void *cls)
|
||||
const struct GNUNET_DISK_FileHandle *pr;
|
||||
char c[16];
|
||||
struct State *state;
|
||||
const struct GNUNET_SCHEDULER_TaskContext *tc;
|
||||
|
||||
child_death_task = NULL;
|
||||
pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
|
||||
tc = GNUNET_SCHEDULER_get_task_context ();
|
||||
GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));
|
||||
GNUNET_OS_process_wait (aggregator_proc);
|
||||
GNUNET_OS_process_destroy (aggregator_proc);
|
||||
@ -1108,8 +1106,7 @@ run (void *cls)
|
||||
|
||||
plugin = TALER_EXCHANGEDB_plugin_load (cfg);
|
||||
if (GNUNET_OK !=
|
||||
plugin->create_tables (plugin->cls,
|
||||
GNUNET_YES))
|
||||
plugin->create_tables (plugin->cls))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_EXCHANGEDB_plugin_unload (plugin);
|
||||
@ -1117,8 +1114,7 @@ run (void *cls)
|
||||
result = 77;
|
||||
return;
|
||||
}
|
||||
session = plugin->get_session (plugin->cls,
|
||||
GNUNET_YES);
|
||||
session = plugin->get_session (plugin->cls);
|
||||
GNUNET_assert (NULL != session);
|
||||
fake_issue (&issue);
|
||||
dpk.rsa_public_key = coin_pub;
|
||||
|
@ -56,7 +56,6 @@ libtalerexchangedb_la_LDFLAGS = \
|
||||
|
||||
|
||||
check_PROGRAMS = \
|
||||
test-exchangedb-deposits \
|
||||
test-exchangedb-keyio \
|
||||
test-exchangedb-postgres \
|
||||
test-perf-taler-exchangedb \
|
||||
@ -65,17 +64,8 @@ check_PROGRAMS = \
|
||||
AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
|
||||
TESTS = \
|
||||
test-exchangedb-postgres \
|
||||
test-perf-taler-exchangedb
|
||||
|
||||
test_exchangedb_deposits_SOURCES = \
|
||||
test_exchangedb_deposits.c
|
||||
test_exchangedb_deposits_LDADD = \
|
||||
libtalerexchangedb.la \
|
||||
$(top_srcdir)/src/util/libtalerutil.la \
|
||||
$(top_srcdir)/src/pq/libtalerpq.la \
|
||||
-lgnunetutil \
|
||||
-ljansson \
|
||||
-lpq
|
||||
test-perf-taler-exchangedb \
|
||||
test-exchangedb-keyio
|
||||
|
||||
test_exchangedb_keyio_SOURCES = \
|
||||
test_exchangedb_keyio.c
|
||||
|
@ -66,7 +66,7 @@ PERF_TALER_EXCHANGEDB_denomination_init ()
|
||||
&properties.master.eddsa_pub);
|
||||
properties.start = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get());
|
||||
properties.expire_withdraw = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_());
|
||||
properties.expire_spend = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_());
|
||||
properties.expire_deposit = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_());
|
||||
properties.expire_legal = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_());
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_string_to_amount (CURRENCY ":1.1", &amount));
|
||||
|
@ -1369,7 +1369,7 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state)
|
||||
break;
|
||||
|
||||
case PERF_TALER_EXCHANGEDB_CMD_NEW_SESSION:
|
||||
state->session = state->plugin->get_session (state->plugin->cls, GNUNET_YES);
|
||||
state->session = state->plugin->get_session (state->plugin->cls);
|
||||
break;
|
||||
|
||||
case PERF_TALER_EXCHANGEDB_CMD_START_TRANSACTION:
|
||||
@ -1816,8 +1816,7 @@ PERF_TALER_EXCHANGEDB_interpret (struct TALER_EXCHANGEDB_Plugin *db_plugin,
|
||||
ret = cmd_init (cmd);
|
||||
if (GNUNET_SYSERR == ret)
|
||||
return ret;
|
||||
state.session = db_plugin->get_session (db_plugin->cls,
|
||||
GNUNET_YES);
|
||||
state.session = db_plugin->get_session (db_plugin->cls);
|
||||
GNUNET_assert (NULL != state.session);
|
||||
ret = interpret (&state);
|
||||
cmd_clean (cmd);
|
||||
@ -1833,7 +1832,8 @@ PERF_TALER_EXCHANGEDB_interpret (struct TALER_EXCHANGEDB_Plugin *db_plugin,
|
||||
* @param init the commands to use for the database initialisation,
|
||||
* if #NULL the standard initialization is used
|
||||
* @param benchmark the commands for the benchmark
|
||||
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
|
||||
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure, #GNUNET_NO
|
||||
* if we failed to init the database
|
||||
*/
|
||||
int
|
||||
PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name,
|
||||
@ -1940,15 +1940,14 @@ PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name,
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Error connectiong to the database\n");
|
||||
return ret;
|
||||
return GNUNET_NO;
|
||||
}
|
||||
ret = plugin->create_tables (plugin->cls,
|
||||
GNUNET_YES);
|
||||
ret = plugin->create_tables (plugin->cls);
|
||||
if (GNUNET_OK != ret)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Error while creating the database architecture\n");
|
||||
return ret;
|
||||
return GNUNET_NO;
|
||||
}
|
||||
/*
|
||||
* Running the initialization
|
||||
@ -1958,7 +1957,7 @@ PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name,
|
||||
init = init_def;
|
||||
}
|
||||
ret = PERF_TALER_EXCHANGEDB_interpret (plugin,
|
||||
init);
|
||||
init);
|
||||
if (GNUNET_OK != ret)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
@ -1980,10 +1979,9 @@ PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name,
|
||||
{
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
|
||||
session = plugin->get_session (plugin->cls,
|
||||
GNUNET_YES);
|
||||
ret = plugin->drop_temporary (plugin->cls,
|
||||
session);
|
||||
session = plugin->get_session (plugin->cls);
|
||||
ret = plugin->drop_tables (plugin->cls,
|
||||
session);
|
||||
if (GNUNET_OK != ret)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
|
@ -467,7 +467,7 @@
|
||||
|
||||
/**
|
||||
* Get informations about a refresh session
|
||||
*
|
||||
*
|
||||
* @param _label the label of the command
|
||||
* @param _label_hash the label of the hash to search
|
||||
*/
|
||||
@ -933,8 +933,8 @@ union PERF_TALER_EXCHANGEDB_CMD_Details
|
||||
*/
|
||||
const char *label_denom;
|
||||
unsigned int index_denom;
|
||||
} insert_denomination;
|
||||
|
||||
} insert_denomination;
|
||||
|
||||
/**
|
||||
* Extra data requiered by the #PERF_TALER_EXCHANGEDB_CMD_GET_DENOMINATION command
|
||||
*/
|
||||
@ -1283,13 +1283,14 @@ struct PERF_TALER_EXCHANGEDB_Cmd
|
||||
* @param init the commands to use for the database initialisation,
|
||||
* if #NULL the standard initialization is used
|
||||
* @param benchmark the commands for the benchmark
|
||||
* @return GNUNET_OK upon success; GNUNET_SYSERR upon failure
|
||||
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure,
|
||||
* #GNUNET_NO if we failed to init the database
|
||||
*/
|
||||
int
|
||||
PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name,
|
||||
const char *configuration_file,
|
||||
struct PERF_TALER_EXCHANGEDB_Cmd *init,
|
||||
struct PERF_TALER_EXCHANGEDB_Cmd *benchmark);
|
||||
const char *configuration_file,
|
||||
struct PERF_TALER_EXCHANGEDB_Cmd *init,
|
||||
struct PERF_TALER_EXCHANGEDB_Cmd *benchmark);
|
||||
|
||||
|
||||
/**
|
||||
@ -1300,9 +1301,8 @@ PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name,
|
||||
* @param cmd the commands to run
|
||||
*/
|
||||
int
|
||||
PERF_TALER_EXCHANGEDB_interpret(
|
||||
struct TALER_EXCHANGEDB_Plugin *db_plugin,
|
||||
struct PERF_TALER_EXCHANGEDB_Cmd cmd[]);
|
||||
PERF_TALER_EXCHANGEDB_interpret(struct TALER_EXCHANGEDB_Plugin *db_plugin,
|
||||
struct PERF_TALER_EXCHANGEDB_Cmd cmd[]);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -29,15 +29,6 @@
|
||||
|
||||
#include "plugin_exchangedb_common.c"
|
||||
|
||||
/**
|
||||
* For testing / experiments, we set the Postgres schema to
|
||||
* #TALER_TEMP_SCHEMA_NAME so we can easily purge everything
|
||||
* associated with a test. We *also* should use the database
|
||||
* "talercheck" instead of "taler" for testing, but we're doing
|
||||
* both: better safe than sorry.
|
||||
*/
|
||||
#define TALER_TEMP_SCHEMA_NAME "taler_temporary"
|
||||
|
||||
/**
|
||||
* Log a query error.
|
||||
*
|
||||
@ -138,39 +129,48 @@ struct PostgresClosure
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the given connection to use a temporary schema
|
||||
*
|
||||
* @param db the database connection
|
||||
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon error
|
||||
*/
|
||||
static int
|
||||
set_temporary_schema (PGconn *db)
|
||||
{
|
||||
SQLEXEC_(db,
|
||||
"CREATE SCHEMA IF NOT EXISTS " TALER_TEMP_SCHEMA_NAME ";"
|
||||
"SET search_path to " TALER_TEMP_SCHEMA_NAME ";");
|
||||
return GNUNET_OK;
|
||||
SQLEXEC_fail:
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drop the temporary taler schema. This is only useful for testcases
|
||||
* Drop all Taler tables. This should only be used by testcases.
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param session database session to use
|
||||
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
|
||||
*/
|
||||
static int
|
||||
postgres_drop_temporary (void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session)
|
||||
postgres_drop_tables (void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Dropping temporary tables\n");
|
||||
"Dropping ALL tables\n");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP SCHEMA " TALER_TEMP_SCHEMA_NAME " CASCADE;");
|
||||
"DROP TABLE IF EXISTS prewire;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS aggregation_tracking;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS deposits;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS refresh_out;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS refresh_commit_coin;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS refresh_commit_link;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS refresh_order;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS refresh_melts;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS refresh_sessions;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS known_coins;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS reserves_out;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS reserves_in;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS reserves;");
|
||||
SQLEXEC_ (session->conn,
|
||||
"DROP TABLE IF EXISTS denominations;");
|
||||
return GNUNET_OK;
|
||||
SQLEXEC_fail:
|
||||
return GNUNET_SYSERR;
|
||||
@ -215,12 +215,10 @@ pq_notice_processor_cb (void *arg,
|
||||
* Create the necessary tables if they are not present
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param temporary should we use a temporary schema
|
||||
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
|
||||
*/
|
||||
static int
|
||||
postgres_create_tables (void *cls,
|
||||
int temporary)
|
||||
postgres_create_tables (void *cls)
|
||||
{
|
||||
struct PostgresClosure *pc = cls;
|
||||
PGconn *conn;
|
||||
@ -239,12 +237,6 @@ postgres_create_tables (void *cls,
|
||||
PQsetNoticeProcessor (conn,
|
||||
&pq_notice_processor_cb,
|
||||
NULL);
|
||||
if ( (GNUNET_YES == temporary) &&
|
||||
(GNUNET_SYSERR == set_temporary_schema (conn)))
|
||||
{
|
||||
PQfinish (conn);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
#define SQLEXEC(sql) SQLEXEC_(conn, sql);
|
||||
#define SQLEXEC_INDEX(sql) SQLEXEC_IGNORE_ERROR_(conn, sql);
|
||||
/* Denomination table for holding the publicly available information of
|
||||
@ -258,7 +250,7 @@ postgres_create_tables (void *cls,
|
||||
",master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)"
|
||||
",valid_from INT8 NOT NULL"
|
||||
",expire_withdraw INT8 NOT NULL"
|
||||
",expire_spend INT8 NOT NULL"
|
||||
",expire_deposit INT8 NOT NULL"
|
||||
",expire_legal INT8 NOT NULL"
|
||||
",coin_val INT8 NOT NULL" /* value of this denom */
|
||||
",coin_frac INT4 NOT NULL" /* fractional value of this denom */
|
||||
@ -533,7 +525,7 @@ postgres_prepare (PGconn *db_conn)
|
||||
",master_sig"
|
||||
",valid_from"
|
||||
",expire_withdraw"
|
||||
",expire_spend"
|
||||
",expire_deposit"
|
||||
",expire_legal"
|
||||
",coin_val" /* value of this denom */
|
||||
",coin_frac" /* fractional value of this denom */
|
||||
@ -563,7 +555,7 @@ postgres_prepare (PGconn *db_conn)
|
||||
",master_sig"
|
||||
",valid_from"
|
||||
",expire_withdraw"
|
||||
",expire_spend"
|
||||
",expire_deposit"
|
||||
",expire_legal"
|
||||
",coin_val" /* value of this denom */
|
||||
",coin_frac" /* fractional value of this denom */
|
||||
@ -1200,13 +1192,10 @@ db_conn_destroy (void *cls)
|
||||
* Connect to the db if the connection does not exist yet.
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param temporary #GNUNET_YES to use a temporary schema; #GNUNET_NO to use the
|
||||
* database default one
|
||||
* @return the database connection, or NULL on error
|
||||
*/
|
||||
static struct TALER_EXCHANGEDB_Session *
|
||||
postgres_get_session (void *cls,
|
||||
int temporary)
|
||||
postgres_get_session (void *cls)
|
||||
{
|
||||
struct PostgresClosure *pc = cls;
|
||||
PGconn *db_conn;
|
||||
@ -1229,12 +1218,6 @@ postgres_get_session (void *cls,
|
||||
PQsetNoticeProcessor (db_conn,
|
||||
&pq_notice_processor_cb,
|
||||
NULL);
|
||||
if ( (GNUNET_YES == temporary) &&
|
||||
(GNUNET_SYSERR == set_temporary_schema(db_conn)) )
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
postgres_prepare (db_conn))
|
||||
{
|
||||
@ -1382,7 +1365,7 @@ postgres_insert_denomination_info (void *cls,
|
||||
GNUNET_PQ_query_param_auto_from_type (&issue->signature),
|
||||
GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.start),
|
||||
GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_withdraw),
|
||||
GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_spend),
|
||||
GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_deposit),
|
||||
GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_legal),
|
||||
TALER_PQ_query_param_amount_nbo (&issue->properties.value),
|
||||
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_withdraw),
|
||||
@ -1478,8 +1461,8 @@ postgres_get_denomination_info (void *cls,
|
||||
&issue->properties.start),
|
||||
GNUNET_PQ_result_spec_absolute_time_nbo ("expire_withdraw",
|
||||
&issue->properties.expire_withdraw),
|
||||
GNUNET_PQ_result_spec_absolute_time_nbo ("expire_spend",
|
||||
&issue->properties.expire_spend),
|
||||
GNUNET_PQ_result_spec_absolute_time_nbo ("expire_deposit",
|
||||
&issue->properties.expire_deposit),
|
||||
GNUNET_PQ_result_spec_absolute_time_nbo ("expire_legal",
|
||||
&issue->properties.expire_legal),
|
||||
TALER_PQ_result_spec_amount_nbo ("coin",
|
||||
@ -4243,7 +4226,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
||||
plugin = GNUNET_new (struct TALER_EXCHANGEDB_Plugin);
|
||||
plugin->cls = pg;
|
||||
plugin->get_session = &postgres_get_session;
|
||||
plugin->drop_temporary = &postgres_drop_temporary;
|
||||
plugin->drop_tables = &postgres_drop_tables;
|
||||
plugin->create_tables = &postgres_create_tables;
|
||||
plugin->start = &postgres_start;
|
||||
plugin->commit = &postgres_commit;
|
||||
|
@ -137,7 +137,7 @@ create_denom_key_pair (unsigned int size,
|
||||
dki.issue.properties.expire_withdraw = GNUNET_TIME_absolute_hton
|
||||
(GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
|
||||
GNUNET_TIME_UNIT_HOURS));
|
||||
dki.issue.properties.expire_spend = GNUNET_TIME_absolute_hton
|
||||
dki.issue.properties.expire_deposit = GNUNET_TIME_absolute_hton
|
||||
(GNUNET_TIME_absolute_add
|
||||
(GNUNET_TIME_absolute_get (),
|
||||
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 2)));
|
||||
@ -172,9 +172,10 @@ static struct TALER_Amount fee_refresh;
|
||||
static struct TALER_Amount fee_refund;
|
||||
static struct TALER_Amount amount_with_fee;
|
||||
|
||||
|
||||
static void
|
||||
free_refresh_commit_coins_array(struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins,
|
||||
unsigned int size)
|
||||
free_refresh_commit_coins_array (struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins,
|
||||
unsigned int size)
|
||||
{
|
||||
unsigned int cnt;
|
||||
struct TALER_EXCHANGEDB_RefreshCommitCoin *ccoin;
|
||||
@ -282,6 +283,7 @@ test_refresh_commit_coins (struct TALER_EXCHANGEDB_Session *session,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function to test melting of coins as part of a refresh session
|
||||
*
|
||||
@ -658,21 +660,30 @@ run (void *cls)
|
||||
if (NULL ==
|
||||
(plugin = TALER_EXCHANGEDB_plugin_load (cfg)))
|
||||
{
|
||||
result = 1;
|
||||
result = 77;
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
plugin->create_tables (plugin->cls,
|
||||
GNUNET_YES))
|
||||
if (NULL !=
|
||||
(session = plugin->get_session (plugin->cls)))
|
||||
{
|
||||
result = 2;
|
||||
if (GNUNET_OK !=
|
||||
plugin->drop_tables (plugin->cls,
|
||||
session))
|
||||
{
|
||||
result = 77;
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
plugin->create_tables (plugin->cls))
|
||||
{
|
||||
result = 77;
|
||||
goto drop;
|
||||
}
|
||||
if (NULL ==
|
||||
(session = plugin->get_session (plugin->cls,
|
||||
GNUNET_YES)))
|
||||
(session = plugin->get_session (plugin->cls)))
|
||||
{
|
||||
result = 3;
|
||||
result = 77;
|
||||
goto drop;
|
||||
}
|
||||
RND_BLK (&reserve_pub);
|
||||
@ -932,8 +943,8 @@ run (void *cls)
|
||||
rh = NULL;
|
||||
if (NULL != session)
|
||||
GNUNET_break (GNUNET_OK ==
|
||||
plugin->drop_temporary (plugin->cls,
|
||||
session));
|
||||
plugin->drop_tables (plugin->cls,
|
||||
session));
|
||||
if (NULL != dkp)
|
||||
destroy_denom_key_pair (dkp);
|
||||
if (NULL != cbc.sig.rsa_signature)
|
||||
|
@ -1,152 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014 GNUnet e.V.
|
||||
|
||||
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, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file exchange/test_exchange_deposits.c
|
||||
* @brief testcase for exchange deposits
|
||||
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <libpq-fe.h>
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include "taler_pq_lib.h"
|
||||
#include "taler_exchangedb_lib.h"
|
||||
#include "taler_exchangedb_plugin.h"
|
||||
|
||||
#define EXCHANGE_CURRENCY "EUR"
|
||||
|
||||
#define DB_URI "postgres:///taler"
|
||||
|
||||
#define break_db_err(result) do { \
|
||||
GNUNET_break(0); \
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Database failure: %s\n", PQresultErrorMessage (result)); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Shorthand for exit jumps.
|
||||
*/
|
||||
#define EXITIF(cond) \
|
||||
do { \
|
||||
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Should we not interact with a temporary table?
|
||||
*/
|
||||
static int persistent;
|
||||
|
||||
/**
|
||||
* Testcase result
|
||||
*/
|
||||
static int result;
|
||||
|
||||
/**
|
||||
* The plugin.
|
||||
*/
|
||||
static struct TALER_EXCHANGEDB_Plugin *plugin;
|
||||
|
||||
/**
|
||||
* Main function that will be run by the scheduler.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param args remaining command-line arguments
|
||||
* @param cfgfile name of the configuration file used (for saving, can be NULL!)
|
||||
* @param cfg configuration
|
||||
*/
|
||||
static void
|
||||
run (void *cls,
|
||||
char *const *args,
|
||||
const char *cfgfile,
|
||||
const struct GNUNET_CONFIGURATION_Handle *cfg)
|
||||
{
|
||||
static const char wire[] = "{"
|
||||
"\"type\":\"SEPA\","
|
||||
"\"IBAN\":\"DE67830654080004822650\","
|
||||
"\"NAME\":\"GNUNET E.V\","
|
||||
"\"BIC\":\"GENODEF1SRL\""
|
||||
"}";
|
||||
struct TALER_EXCHANGEDB_Deposit *deposit;
|
||||
uint64_t transaction_id;
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
|
||||
deposit = NULL;
|
||||
EXITIF (NULL == (plugin = TALER_EXCHANGEDB_plugin_load (cfg)));
|
||||
EXITIF (GNUNET_OK !=
|
||||
plugin->create_tables (plugin->cls,
|
||||
! persistent));
|
||||
session = plugin->get_session (plugin->cls,
|
||||
! persistent);
|
||||
EXITIF (NULL == session);
|
||||
deposit = GNUNET_malloc (sizeof (struct TALER_EXCHANGEDB_Deposit) + sizeof (wire));
|
||||
/* Makeup a random coin public key */
|
||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||
deposit,
|
||||
sizeof (struct TALER_EXCHANGEDB_Deposit));
|
||||
/* Makeup a random 64bit transaction ID */
|
||||
transaction_id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||
UINT64_MAX);
|
||||
deposit->transaction_id = GNUNET_htonll (transaction_id);
|
||||
/* Random amount */
|
||||
deposit->amount_with_fee.value =
|
||||
htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX));
|
||||
deposit->amount_with_fee.fraction =
|
||||
htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX));
|
||||
GNUNET_assert (strlen (EXCHANGE_CURRENCY) < sizeof (deposit->amount_with_fee.currency));
|
||||
strcpy (deposit->amount_with_fee.currency, EXCHANGE_CURRENCY);
|
||||
/* Copy wireformat */
|
||||
deposit->wire = json_loads (wire, 0, NULL);
|
||||
EXITIF (GNUNET_OK !=
|
||||
plugin->insert_deposit (plugin->cls,
|
||||
session,
|
||||
deposit));
|
||||
EXITIF (GNUNET_OK !=
|
||||
plugin->have_deposit (plugin->cls,
|
||||
session,
|
||||
deposit));
|
||||
result = GNUNET_OK;
|
||||
|
||||
EXITIF_exit:
|
||||
GNUNET_free_non_null (deposit);
|
||||
if (NULL != plugin)
|
||||
{
|
||||
TALER_EXCHANGEDB_plugin_unload (plugin);
|
||||
plugin = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
static const struct GNUNET_GETOPT_CommandLineOption options[] = {
|
||||
{'T', "persist", NULL,
|
||||
gettext_noop ("Use a persistent database table instead of a temporary one"),
|
||||
GNUNET_NO, &GNUNET_GETOPT_set_one, &persistent},
|
||||
GNUNET_GETOPT_OPTION_END
|
||||
};
|
||||
|
||||
|
||||
persistent = GNUNET_NO;
|
||||
result = GNUNET_SYSERR;
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_PROGRAM_run (argc, argv,
|
||||
"test-exchange-deposits",
|
||||
"testcase for exchange deposits",
|
||||
options, &run, NULL))
|
||||
return 3;
|
||||
return (GNUNET_OK == result) ? 0 : 1;
|
||||
}
|
@ -35,6 +35,7 @@
|
||||
#define NB_WITHDRAW_INIT 1
|
||||
#define NB_WITHDRAW_SAVE 1
|
||||
|
||||
|
||||
/**
|
||||
* Allocate, copies and free all the data used in the interpreter
|
||||
* Used to check for memory leaks
|
||||
@ -42,7 +43,8 @@
|
||||
static void
|
||||
test_allocate ()
|
||||
{
|
||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki, *dki_copy;
|
||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki_copy;
|
||||
struct PERF_TALER_EXCHANGEDB_Reserve *reserve, *reserve_copy;
|
||||
struct PERF_TALER_EXCHANGEDB_Coin *coin, *coin_copy;
|
||||
struct TALER_EXCHANGEDB_Deposit *deposit, *deposit_copy;
|
||||
@ -68,6 +70,7 @@ test_allocate ()
|
||||
PERF_TALER_EXCHANGEDB_deposit_free (deposit_copy);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs the performances tests for the exchange database
|
||||
* and logs the results using Gauger
|
||||
@ -170,13 +173,15 @@ main (int argc, char ** argv)
|
||||
// End of deposit initialization
|
||||
PERF_TALER_EXCHANGEDB_INIT_CMD_END ("end"),
|
||||
};
|
||||
|
||||
|
||||
test_allocate ();
|
||||
ret = PERF_TALER_EXCHANGEDB_run_benchmark ("test-perf-taler-exchangedb",
|
||||
"./test-exchange-db-postgres.conf",
|
||||
init,
|
||||
benchmark);
|
||||
"./test-exchange-db-postgres.conf",
|
||||
init,
|
||||
benchmark);
|
||||
if (GNUNET_SYSERR == ret)
|
||||
return 1;
|
||||
if (GNUNET_NO == ret)
|
||||
return 77; /* testcase skipped */
|
||||
return 0;
|
||||
}
|
||||
|
@ -95,14 +95,14 @@ struct TALER_EXCHANGE_DenomPublicKey
|
||||
/**
|
||||
* Timestamp indicating when coins of this denomination become invalid.
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute deposit_valid_until;
|
||||
struct GNUNET_TIME_Absolute expire_deposit;
|
||||
|
||||
/**
|
||||
* When do signatures with this denomination key become invalid?
|
||||
* After this point, these signatures cannot be used in (legal)
|
||||
* disputes anymore, as the Exchange is then allowed to destroy its side
|
||||
* of the evidence. @e expire_legal is expected to be significantly
|
||||
* larger than @e expire_spend (by a year or more).
|
||||
* larger than @e expire_deposit (by a year or more).
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute expire_legal;
|
||||
|
||||
|
@ -205,8 +205,7 @@ struct TALER_EXCHANGEDB_ReserveHistory
|
||||
* merchant must either use a different public key or a different
|
||||
* transaction ID for the two transactions. The same coin must not
|
||||
* be used twice at the same merchant for the same transaction
|
||||
* (as determined by transaction ID). (Note: we might want to
|
||||
* fix #3819 and include at least h_contract as well.)
|
||||
* (as determined by transaction ID).
|
||||
*/
|
||||
struct TALER_EXCHANGEDB_Deposit
|
||||
{
|
||||
@ -317,12 +316,12 @@ struct TALER_EXCHANGEDB_Refund
|
||||
struct TALER_CoinPublicInfo coin;
|
||||
|
||||
/**
|
||||
* Public key of the merchant.
|
||||
* Public key of the merchant.
|
||||
*/
|
||||
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||
|
||||
|
||||
/**
|
||||
* Signature from the merchant affirming the refund.
|
||||
* Signature from the merchant affirming the refund.
|
||||
*/
|
||||
struct TALER_MerchantSignatureP merchant_sig;
|
||||
|
||||
@ -338,7 +337,7 @@ struct TALER_EXCHANGEDB_Refund
|
||||
* refunded.
|
||||
*/
|
||||
uint64_t transaction_id;
|
||||
|
||||
|
||||
/**
|
||||
* Merchant-generated REFUND transaction ID to detect duplicate
|
||||
* refunds.
|
||||
@ -718,36 +717,31 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* Connect to the db if the connection does not exist yet.
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param temporary #GNUNET_YES to use a temporary schema; #GNUNET_NO to use the
|
||||
* database default one
|
||||
* @param the database connection, or NULL on error
|
||||
*/
|
||||
struct TALER_EXCHANGEDB_Session *
|
||||
(*get_session) (void *cls,
|
||||
int temporary);
|
||||
(*get_session) (void *cls);
|
||||
|
||||
|
||||
/**
|
||||
* Drop the temporary taler schema. This is only useful for testcases.
|
||||
* Drop the Taler tables. This should only be used in testcases.
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
|
||||
*/
|
||||
int
|
||||
(*drop_temporary) (void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *db);
|
||||
(*drop_tables) (void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *db);
|
||||
|
||||
|
||||
/**
|
||||
* Create the necessary tables if they are not present
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param temporary should we use a temporary schema
|
||||
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
|
||||
*/
|
||||
int
|
||||
(*create_tables) (void *cls,
|
||||
int temporary);
|
||||
(*create_tables) (void *cls);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -659,18 +659,18 @@ struct TALER_DenominationKeyValidityPS
|
||||
* exchange will refuse transactions involving this key as it will
|
||||
* "drop" the table with double-spending information (shortly after)
|
||||
* this time. Note that wallets should refresh coins significantly
|
||||
* before this time to be on the safe side. @e expire_spend must be
|
||||
* before this time to be on the safe side. @e expire_deposit must be
|
||||
* significantly larger than @e expire_withdraw (by months or even
|
||||
* years).
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_spend;
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_deposit;
|
||||
|
||||
/**
|
||||
* When do signatures with this denomination key become invalid?
|
||||
* After this point, these signatures cannot be used in (legal)
|
||||
* disputes anymore, as the Exchange is then allowed to destroy its side
|
||||
* of the evidence. @e expire_legal is expected to be significantly
|
||||
* larger than @e expire_spend (by a year or more).
|
||||
* larger than @e expire_deposit (by a year or more).
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_legal;
|
||||
|
||||
@ -762,18 +762,18 @@ struct TALER_ExchangeKeyValidityPS
|
||||
* exchange will refuse transactions involving this key as it will
|
||||
* "drop" the table with double-spending information (shortly after)
|
||||
* this time. Note that wallets should refresh coins significantly
|
||||
* before this time to be on the safe side. @e expire_spend must be
|
||||
* before this time to be on the safe side. @e expire_deposit must be
|
||||
* significantly larger than @e expire_withdraw (by months or even
|
||||
* years).
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_spend;
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_deposit;
|
||||
|
||||
/**
|
||||
* When do signatures with this denomination key become invalid?
|
||||
* After this point, these signatures cannot be used in (legal)
|
||||
* disputes anymore, as the Exchange is then allowed to destroy its side
|
||||
* of the evidence. @e expire_legal is expected to be significantly
|
||||
* larger than @e expire_spend (by a year or more).
|
||||
* larger than @e expire_deposit (by a year or more).
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO expire_legal;
|
||||
|
||||
|
@ -51,9 +51,9 @@ struct TestClosure
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
|
||||
/**
|
||||
* Handle to the bank task, or NULL.
|
||||
* Scheduler context for running the @e ctx.
|
||||
*/
|
||||
struct GNUNET_SCHEDULER_Task *bt;
|
||||
struct GNUNET_CURL_RescheduleContext *rc;
|
||||
|
||||
/**
|
||||
* Number of the account that the exchange has at the bank for
|
||||
@ -132,76 +132,6 @@ struct TALER_WIRE_ExecuteHandle
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Task that runs the bank's context's event loop with the GNUnet
|
||||
* scheduler.
|
||||
*
|
||||
* @param cls our `struct TestClosure`
|
||||
*/
|
||||
static void
|
||||
context_task (void *cls)
|
||||
{
|
||||
struct TestClosure *tc = cls;
|
||||
long timeout;
|
||||
int max_fd;
|
||||
fd_set read_fd_set;
|
||||
fd_set write_fd_set;
|
||||
fd_set except_fd_set;
|
||||
struct GNUNET_NETWORK_FDSet *rs;
|
||||
struct GNUNET_NETWORK_FDSet *ws;
|
||||
struct GNUNET_TIME_Relative delay;
|
||||
|
||||
tc->bt = NULL;
|
||||
GNUNET_CURL_perform (tc->ctx);
|
||||
max_fd = -1;
|
||||
timeout = -1;
|
||||
FD_ZERO (&read_fd_set);
|
||||
FD_ZERO (&write_fd_set);
|
||||
FD_ZERO (&except_fd_set);
|
||||
GNUNET_CURL_get_select_info (tc->ctx,
|
||||
&read_fd_set,
|
||||
&write_fd_set,
|
||||
&except_fd_set,
|
||||
&max_fd,
|
||||
&timeout);
|
||||
if (timeout >= 0)
|
||||
delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
|
||||
timeout);
|
||||
else
|
||||
delay = GNUNET_TIME_UNIT_FOREVER_REL;
|
||||
rs = GNUNET_NETWORK_fdset_create ();
|
||||
GNUNET_NETWORK_fdset_copy_native (rs,
|
||||
&read_fd_set,
|
||||
max_fd + 1);
|
||||
ws = GNUNET_NETWORK_fdset_create ();
|
||||
GNUNET_NETWORK_fdset_copy_native (ws,
|
||||
&write_fd_set,
|
||||
max_fd + 1);
|
||||
tc->bt = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
|
||||
delay,
|
||||
rs,
|
||||
ws,
|
||||
&context_task,
|
||||
tc);
|
||||
GNUNET_NETWORK_fdset_destroy (rs);
|
||||
GNUNET_NETWORK_fdset_destroy (ws);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the bank task now.
|
||||
*
|
||||
* @param tc context for which we should initiate running the task
|
||||
*/
|
||||
static void
|
||||
run_bt (struct TestClosure *tc)
|
||||
{
|
||||
if (NULL != tc->bt)
|
||||
GNUNET_SCHEDULER_cancel (tc->bt);
|
||||
tc->bt = GNUNET_SCHEDULER_add_now (&context_task,
|
||||
tc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Round amount DOWN to the amount that can be transferred via the wire
|
||||
@ -751,7 +681,6 @@ test_execute_wire_transfer (void *cls,
|
||||
GNUNET_free (eh);
|
||||
return NULL;
|
||||
}
|
||||
run_bt (tc);
|
||||
return eh;
|
||||
}
|
||||
|
||||
@ -831,7 +760,9 @@ libtaler_plugin_wire_test_init (void *cls)
|
||||
GNUNET_free (tc);
|
||||
return NULL;
|
||||
}
|
||||
tc->ctx = GNUNET_CURL_init ();
|
||||
tc->ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
|
||||
&tc->rc);
|
||||
tc->rc = GNUNET_CURL_gnunet_rc_create (tc->ctx);
|
||||
if (NULL == tc->ctx)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -867,16 +798,16 @@ libtaler_plugin_wire_test_done (void *cls)
|
||||
struct TALER_WIRE_Plugin *plugin = cls;
|
||||
struct TestClosure *tc = plugin->cls;
|
||||
|
||||
if (NULL != tc->bt)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (tc->bt);
|
||||
tc->bt = NULL;
|
||||
}
|
||||
if (NULL != tc->ctx)
|
||||
{
|
||||
GNUNET_CURL_fini (tc->ctx);
|
||||
tc->ctx = NULL;
|
||||
}
|
||||
if (NULL != tc->rc)
|
||||
{
|
||||
GNUNET_CURL_gnunet_rc_destroy (tc->rc);
|
||||
tc->rc = NULL;
|
||||
}
|
||||
GNUNET_free_non_null (tc->currency);
|
||||
GNUNET_free_non_null (tc->bank_uri);
|
||||
GNUNET_free (tc);
|
||||
|
Loading…
Reference in New Issue
Block a user