From 9aa323ca7bcf1567f6ecf98cf73b5691ade1b816 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 24 Jan 2016 16:44:57 +0100 Subject: adding skeletons for plugins --- src/wire/plugin_wire_test.c | 235 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 src/wire/plugin_wire_test.c (limited to 'src/wire/plugin_wire_test.c') diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c new file mode 100644 index 00000000..72c87ef5 --- /dev/null +++ b/src/wire/plugin_wire_test.c @@ -0,0 +1,235 @@ +/* + 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 +*/ + +/** + * @file plugin_wire_test.c + * @brief plugin for the "test" wire method + * @author Florian Dold + * @author Christian Grothoff + * @author Sree Harsha Totakura + */ +#include "platform.h" +#include "taler_wire_plugin.h" + + +/** + * Type of the "cls" argument given to each of the functions in + * our API. + */ +struct TestClosure +{ + + /** + * URI of the bank for sending funds to the bank. + */ + char *bank_uri; + + /** + * Which currency do we support? + */ + char *currency; + +}; + + +/** + * Round amount DOWN to the amount that can be transferred via the wire + * method. For example, Taler may support 0.000001 EUR as a unit of + * payment, but SEPA only supports 0.01 EUR. This function would + * round 0.125 EUR to 0.12 EUR in this case. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param[in,out] amount amount to round down + * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary, + * #GNUNET_SYSERR if the amount or currency was invalid + */ +static int +test_amount_round (void *cls, + struct TALER_Amount *amount) +{ + GNUNET_break (0); + return GNUNET_SYSERR; +} + + +/** + * Check if the given wire format JSON object is correctly formatted + * + * @param wire the JSON wire format object + * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not + */ +static int +test_wire_validate (const json_t *wire) +{ + GNUNET_break (0); + return GNUNET_SYSERR; +} + + +/** + * Prepare for exeuction of a wire transfer. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param wire valid wire account information + * @param amount amount to transfer, already rounded + * @param wtid wire transfer identifier to use + * @param ptc function to call with the prepared data to persist + * @param ptc_cls closure for @a ptc + * @return NULL on failure + */ +static struct TALER_WIRE_PrepareHandle * +test_prepare_wire_transfer (void *cls, + const json_t *wire, + const struct TALER_Amount *amount, + const void *wtid, + TALER_WIRE_PrepareTransactionCallback ptc, + void *ptc_cls) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Abort preparation of a wire transfer. For example, + * because we are shutting down. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param pth preparation to cancel + */ +static void +test_prepare_wire_transfer_cancel (void *cls, + struct TALER_WIRE_PrepareHandle *pth) +{ + GNUNET_break (0); +} + + +/** + * Execute a wire transfer. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param buf buffer with the prepared execution details + * @param buf_size number of bytes in @a buf + * @param cc function to call upon success + * @param cc_cls closure for @a cc + * @return NULL on error + */ +static struct TALER_WIRE_ExecuteHandle * +test_execute_wire_transfer (void *cls, + const char *buf, + size_t buf_size, + TALER_WIRE_ConfirmationCallback cc, + void *cc_cls) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Abort execution of a wire transfer. For example, because we are + * shutting down. Note that if an execution is aborted, it may or + * may not still succeed. The caller MUST run @e + * execute_wire_transfer again for the same request as soon as + * possilbe, to ensure that the request either ultimately succeeds + * or ultimately fails. Until this has been done, the transaction is + * in limbo (i.e. may or may not have been committed). + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param eh execution to cancel + */ +static void +test_execute_wire_transfer_cancel (void *cls, + struct TALER_WIRE_ExecuteHandle *eh) +{ + GNUNET_break (0); +} + + +/** + * Initialize test-wire subsystem. + * + * @param cls a configuration instance + * @return NULL on error, otherwise a `struct TALER_WIRE_Plugin` + */ +void * +libtaler_plugin_wire_test_init (void *cls) +{ + struct GNUNET_CONFIGURATION_Handle *cfg = cls; + struct TestClosure *tc; + struct TALER_WIRE_Plugin *plugin; + + tc = GNUNET_new (struct TestClosure); + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "wire-test", + "bank_uri", + &tc->bank_uri)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "wire-test", + "bank_uri"); + GNUNET_free (tc); + return NULL; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "mint", + "CURRENCY", + &tc->currency)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "mint", + "CURRENCY"); + GNUNET_free (tc->bank_uri); + GNUNET_free (tc); + return NULL; + } + + plugin = GNUNET_new (struct TALER_WIRE_Plugin); + plugin->cls = tc; + plugin->amount_round = &test_amount_round; + plugin->wire_validate = &test_wire_validate; + plugin->prepare_wire_transfer = &test_prepare_wire_transfer; + plugin->prepare_wire_transfer_cancel = &test_prepare_wire_transfer_cancel; + plugin->execute_wire_transfer = &test_execute_wire_transfer; + plugin->execute_wire_transfer_cancel = &test_execute_wire_transfer_cancel; + return plugin; +} + + +/** + * Shutdown Test wire subsystem. + * + * @param cls a `struct TALER_WIRE_Plugin` + * @return NULL (always) + */ +void * +libtaler_plugin_wire_test_done (void *cls) +{ + struct TALER_WIRE_Plugin *plugin = cls; + struct TestClosure *tc = plugin->cls; + + GNUNET_free (tc->bank_uri); + GNUNET_free (tc->currency); + GNUNET_free (tc); + GNUNET_free (plugin); + return NULL; +} + +/* end of plugin_wire_test.c */ -- cgit v1.2.3 From 5c58c43609609e6871c7105c7ca8fc3d794dca04 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 24 Jan 2016 16:52:39 +0100 Subject: more work on wire plugins --- src/include/taler_wire_plugin.h | 2 +- src/wire/plugin_wire_template.c | 12 ++++++++++-- src/wire/plugin_wire_test.c | 24 +++++++++++++++++++----- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src/wire/plugin_wire_test.c') diff --git a/src/include/taler_wire_plugin.h b/src/include/taler_wire_plugin.h index 00bcc42e..62930450 100644 --- a/src/include/taler_wire_plugin.h +++ b/src/include/taler_wire_plugin.h @@ -123,7 +123,7 @@ struct TALER_WIRE_Plugin (*prepare_wire_transfer) (void *cls, const json_t *wire, const struct TALER_Amount *amount, - const void *wtid, + const struct TALER_WireTransferIdentifierRawP *wtid, TALER_WIRE_PrepareTransactionCallback ptc, void *ptc_cls); diff --git a/src/wire/plugin_wire_template.c b/src/wire/plugin_wire_template.c index 8abcca8c..baf0ee7d 100644 --- a/src/wire/plugin_wire_template.c +++ b/src/wire/plugin_wire_template.c @@ -60,7 +60,15 @@ static int template_amount_round (void *cls, struct TALER_Amount *amount) { - GNUNET_break (0); + struct TemplateClosure *tc = cls; + + if (0 != strcasecmp (amount->currency, + tc->currency)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_break (0); // not implemented return GNUNET_SYSERR; } @@ -94,7 +102,7 @@ static struct TALER_WIRE_PrepareHandle * template_prepare_wire_transfer (void *cls, const json_t *wire, const struct TALER_Amount *amount, - const void *wtid, + const struct TALER_WireTransferIdentifierRawP *wtid, TALER_WIRE_PrepareTransactionCallback ptc, void *ptc_cls) { diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 72c87ef5..1ea856fd 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -60,8 +60,21 @@ static int test_amount_round (void *cls, struct TALER_Amount *amount) { - GNUNET_break (0); - return GNUNET_SYSERR; + struct TestClosure *tc = cls; + uint32_t delta; + + if (0 != strcasecmp (amount->currency, + tc->currency)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + /* 'test' method supports 1/100 of the unit currency, i.e. 0.01 CUR */ + delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / 100); + if (0 == delta) + return GNUNET_NO; + amount->fraction -= delta; + return GNUNET_OK; } @@ -74,8 +87,9 @@ test_amount_round (void *cls, static int test_wire_validate (const json_t *wire) { - GNUNET_break (0); - return GNUNET_SYSERR; + GNUNET_break (0); /* FIXME: we still need to define the + proper wire format for 'test' */ + return GNUNET_YES; } @@ -94,7 +108,7 @@ static struct TALER_WIRE_PrepareHandle * test_prepare_wire_transfer (void *cls, const json_t *wire, const struct TALER_Amount *amount, - const void *wtid, + const struct TALER_WireTransferIdentifierRawP *wtid, TALER_WIRE_PrepareTransactionCallback ptc, void *ptc_cls) { -- cgit v1.2.3 From ccb4ac92a3e69d26e6c04b10b407f5491eda7001 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 25 Jan 2016 11:08:19 +0100 Subject: more work on wire plugin --- configure.ac | 1 + src/Makefile.am | 2 +- src/include/taler_bank_service.h | 1 + src/wire/Makefile.am | 1 + src/wire/plugin_wire_test.c | 287 ++++++++++++++++++++++++++++++++++++--- 5 files changed, 273 insertions(+), 19 deletions(-) (limited to 'src/wire/plugin_wire_test.c') diff --git a/configure.ac b/configure.ac index 8f06b520..95457e5b 100644 --- a/configure.ac +++ b/configure.ac @@ -357,6 +357,7 @@ AC_CONFIG_FILES([Makefile src/include/Makefile src/util/Makefile src/pq/Makefile + src/bank-lib/Makefile src/wire/Makefile src/mintdb/Makefile src/mint/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 986dcc5d..ac839d52 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,7 +7,7 @@ if WALLET_ONLY SUBDIRS = include util else -SUBDIRS = include util $(PQ_DIR) wire mintdb mint mint-tools +SUBDIRS = include util $(PQ_DIR) bank-lib wire mintdb mint mint-tools if HAVE_LIBCURL SUBDIRS += mint-lib else diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h index b19e213a..b292a7bc 100644 --- a/src/include/taler_bank_service.h +++ b/src/include/taler_bank_service.h @@ -16,6 +16,7 @@ /** * @file include/taler_bank_service.h * @brief C interface of libtalerbank, a C library to use the Taler bank's HTTP API + * This is currently ONLY used to provide the "test" wire transfer protocol. * @author Christian Grothoff */ #ifndef _TALER_BANK_SERVICE_H diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am index a27a59c7..64f50d97 100644 --- a/src/wire/Makefile.am +++ b/src/wire/Makefile.am @@ -21,6 +21,7 @@ libtaler_plugin_wire_test_la_LIBADD = \ $(LTLIBINTL) libtaler_plugin_wire_test_la_LDFLAGS = \ $(TALER_PLUGIN_LDFLAGS) \ + $(top_builddir)/src/bank-lib/libtalerbank.la \ $(top_builddir)/src/util/libtalerutil.la \ -lgnunetutil $(XLIB) diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 1ea856fd..917cf09b 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -17,13 +17,14 @@ /** * @file plugin_wire_test.c * @brief plugin for the "test" wire method - * @author Florian Dold * @author Christian Grothoff - * @author Sree Harsha Totakura */ #include "platform.h" #include "taler_wire_plugin.h" +#include "taler_bank_service.h" +/* only for HTTP status codes */ +#include /** * Type of the "cls" argument given to each of the functions in @@ -33,18 +34,164 @@ struct TestClosure { /** - * URI of the bank for sending funds to the bank. + * Handle to the bank for sending funds to the bank. */ - char *bank_uri; + struct TALER_BANK_Context *bank; /** * Which currency do we support? */ char *currency; + /** + * Handle to the bank task, or NULL. + */ + struct GNUNET_SCHEDULER_Task *bt; + +}; + + +/** + * Handle returned by #test_prepare_wire_transfer. + */ +struct TALER_WIRE_PrepareHandle +{ + + /** + * Task we use for async execution. + */ + struct GNUNET_SCHEDULER_Task *task; + + /** + * Test closure we run in. + */ + struct TestClosure *tc; + + /** + * Wire data for the transfer. + */ + json_t *wire; + + /** + * Function to call with the serialized data. + */ + TALER_WIRE_PrepareTransactionCallback ptc; + + /** + * Closure for @e ptc. + */ + void *ptc_cls; + + /** + * Amount to transfer. + */ + struct TALER_Amount amount; + + /** + * Subject of the wire transfer. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + }; +/** + * Handle returned by #test_execute_wire_transfer. + */ +struct TALER_WIRE_ExecuteHandle +{ + + /** + * Handle to the HTTP request to the bank. + */ + struct TALER_BANK_AdminAddIncomingHandle *aaih; + + /** + * Function to call with the result. + */ + TALER_WIRE_ConfirmationCallback cc; + + /** + * Closure for @e cc. + */ + void *cc_cls; +}; + + +/** + * Task that runs the bank's context's event loop with the GNUnet + * scheduler. + * + * @param cls our `struct TestClosure` + * @param tc scheduler context (unused) + */ +static void +context_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *sct) +{ + 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; + TALER_BANK_perform (tc->bank); + max_fd = -1; + timeout = -1; + FD_ZERO (&read_fd_set); + FD_ZERO (&write_fd_set); + FD_ZERO (&except_fd_set); + TALER_BANK_get_select_info (tc->bank, + &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, + cls); + 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 * method. For example, Taler may support 0.000001 EUR as a unit of @@ -94,7 +241,33 @@ test_wire_validate (const json_t *wire) /** - * Prepare for exeuction of a wire transfer. + * Prepare for exeuction of a wire transfer. Calls the + * callback with the serialized state. + * + * @param cls the `struct TALER_WIRE_PrepareHandle` + * @param sct unused + */ +static void +do_prepare (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *sct) +{ + struct TALER_WIRE_PrepareHandle *pth = cls; + char buf[42]; // FIXME: init: serialize buf! + + pth->task = NULL; + pth->ptc (pth->ptc_cls, + buf, + sizeof (buf)); + GNUNET_free (pth); +} + + +/** + * Prepare for exeuction of a wire transfer. Note that we should call + * @a ptc asynchronously (as that is what the API requires, because + * some transfer methods need it). So while we could immediately call + * @a ptc, we first bundle up all the data and schedule a task to do + * the work. * * @param cls the @e cls of this struct with the plugin-specific state * @param wire valid wire account information @@ -112,8 +285,20 @@ test_prepare_wire_transfer (void *cls, TALER_WIRE_PrepareTransactionCallback ptc, void *ptc_cls) { - GNUNET_break (0); - return NULL; + struct TestClosure *tc = cls; + struct TALER_WIRE_PrepareHandle *pth; + + pth = GNUNET_new (struct TALER_WIRE_PrepareHandle); + pth->tc = tc; + pth->wire = (json_t *) wire; + json_incref (pth->wire); + pth->wtid = *wtid; + pth->ptc = ptc; + pth->ptc_cls = ptc_cls; + pth->amount = *amount; + pth->task = GNUNET_SCHEDULER_add_now (&do_prepare, + pth); + return pth; } @@ -128,7 +313,36 @@ static void test_prepare_wire_transfer_cancel (void *cls, struct TALER_WIRE_PrepareHandle *pth) { - GNUNET_break (0); + GNUNET_SCHEDULER_cancel (pth->task); + json_decref (pth->wire); + GNUNET_free (pth); +} + + +/** + * Called with the result of submitting information about an incoming + * transaction to a bank. + * + * @param cls closure with the `struct TALER_WIRE_ExecuteHandle` + * @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) + */ +static void +execute_cb (void *cls, + unsigned int http_status) +{ + struct TALER_WIRE_ExecuteHandle *eh = cls; + char s[14]; + + eh->aaih = NULL; + GNUNET_snprintf (s, + sizeof (s), + "%u", + http_status); + eh->cc (eh->cc_cls, + (MHD_HTTP_OK == http_status) ? GNUNET_OK : GNUNET_SYSERR, + (MHD_HTTP_OK == http_status) ? NULL : s); + GNUNET_free (eh); } @@ -149,8 +363,32 @@ test_execute_wire_transfer (void *cls, TALER_WIRE_ConfirmationCallback cc, void *cc_cls) { - GNUNET_break (0); - return NULL; + struct TestClosure *tc = cls; + struct TALER_WIRE_ExecuteHandle *eh; + json_t *wire; + struct TALER_Amount amount; + struct TALER_WireTransferIdentifierRawP wtid; + + /* FIXME: deserialize buf */ + wire = NULL; + + eh = GNUNET_new (struct TALER_WIRE_ExecuteHandle); + eh->cc = cc; + eh->cc_cls = cc_cls; + eh->aaih = TALER_BANK_admin_add_incoming (tc->bank, + &wtid, + &amount, + wire, + &execute_cb, + eh); + if (NULL == eh->aaih) + { + GNUNET_break (0); + GNUNET_free (eh); + return NULL; + } + run_bt (tc); + return eh; } @@ -170,7 +408,8 @@ static void test_execute_wire_transfer_cancel (void *cls, struct TALER_WIRE_ExecuteHandle *eh) { - GNUNET_break (0); + TALER_BANK_admin_add_incoming_cancel (eh->aaih); + GNUNET_free (eh); } @@ -186,21 +425,20 @@ libtaler_plugin_wire_test_init (void *cls) struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct TestClosure *tc; struct TALER_WIRE_Plugin *plugin; - - tc = GNUNET_new (struct TestClosure); + char *uri; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "wire-test", "bank_uri", - &tc->bank_uri)) - { + &uri)) + { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "wire-test", "bank_uri"); - GNUNET_free (tc); return NULL; } + tc = GNUNET_new (struct TestClosure); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "mint", @@ -210,7 +448,15 @@ libtaler_plugin_wire_test_init (void *cls) GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "mint", "CURRENCY"); - GNUNET_free (tc->bank_uri); + GNUNET_free (uri); + GNUNET_free (tc); + return NULL; + } + tc->bank = TALER_BANK_init (uri); + if (NULL == tc->bank) + { + GNUNET_break (0); + GNUNET_free (tc->currency); GNUNET_free (tc); return NULL; } @@ -239,7 +485,12 @@ libtaler_plugin_wire_test_done (void *cls) struct TALER_WIRE_Plugin *plugin = cls; struct TestClosure *tc = plugin->cls; - GNUNET_free (tc->bank_uri); + if (NULL != tc->bt) + { + GNUNET_SCHEDULER_cancel (tc->bt); + tc->bt = NULL; + } + TALER_BANK_fini (tc->bank); GNUNET_free (tc->currency); GNUNET_free (tc); GNUNET_free (plugin); -- cgit v1.2.3 From 9b4a9cde8717d053706a2df94c38e19e97eef8ee Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 25 Jan 2016 11:09:55 +0100 Subject: test wire formats before using --- src/wire/plugin_wire_test.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/wire/plugin_wire_test.c') diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 917cf09b..776b786e 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -288,6 +288,12 @@ test_prepare_wire_transfer (void *cls, struct TestClosure *tc = cls; struct TALER_WIRE_PrepareHandle *pth; + if (GNUNET_YES != + test_wire_validate (wire)) + { + GNUNET_break (0); + return NULL; + } pth = GNUNET_new (struct TALER_WIRE_PrepareHandle); pth->tc = tc; pth->wire = (json_t *) wire; @@ -372,6 +378,8 @@ test_execute_wire_transfer (void *cls, /* FIXME: deserialize buf */ wire = NULL; + GNUNET_assert (GNUNET_YES == + test_wire_validate (wire)); eh = GNUNET_new (struct TALER_WIRE_ExecuteHandle); eh->cc = cc; eh->cc_cls = cc_cls; -- cgit v1.2.3 From 891b533a217a23dfd21c6135d62ca5bc91adc38d Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 25 Jan 2016 11:21:55 +0100 Subject: finish serialization/deserialization logic for test wire transfers --- src/include/taler_wire_plugin.h | 4 +- src/wire/plugin_wire_test.c | 89 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 10 deletions(-) (limited to 'src/wire/plugin_wire_test.c') diff --git a/src/include/taler_wire_plugin.h b/src/include/taler_wire_plugin.h index 62930450..8fb194c5 100644 --- a/src/include/taler_wire_plugin.h +++ b/src/include/taler_wire_plugin.h @@ -30,8 +30,8 @@ * Callback with prepared transaction. * * @param cls closure - * @param buf transaction data to persist - * @param buf_size number of bytes in @a buf + * @param buf transaction data to persist, NULL on error + * @param buf_size number of bytes in @a buf, 0 on error */ typedef void (*TALER_WIRE_PrepareTransactionCallback) (void *cls, diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 776b786e..7940b477 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -240,6 +240,29 @@ test_wire_validate (const json_t *wire) } +GNUNET_NETWORK_STRUCT_BEGIN +/** + * Format we used for serialized transaction data. + */ +struct BufFormatP +{ + + /** + * The wire transfer identifier. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * The amount. + */ + struct TALER_AmountNBO amount; + + /* followed by serialized 'wire' JSON data */ + +}; +GNUNET_NETWORK_STRUCT_END + + /** * Prepare for exeuction of a wire transfer. Calls the * callback with the serialized state. @@ -252,12 +275,44 @@ do_prepare (void *cls, const struct GNUNET_SCHEDULER_TaskContext *sct) { struct TALER_WIRE_PrepareHandle *pth = cls; - char buf[42]; // FIXME: init: serialize buf! + char *wire_enc; + size_t len; + struct BufFormatP bf; pth->task = NULL; - pth->ptc (pth->ptc_cls, - buf, - sizeof (buf)); + /* serialize the state into a 'buf' */ + wire_enc = json_dumps (pth->wire, + JSON_COMPACT | JSON_SORT_KEYS); + if (NULL == wire_enc) + { + GNUNET_break (0); + pth->ptc (pth->ptc_cls, + NULL, + 0); + GNUNET_free (pth); + return; + } + len = strlen (wire_enc) + 1; + bf.wtid = pth->wtid; + TALER_amount_hton (&bf.amount, + &pth->amount); + { + char buf[sizeof (struct BufFormatP) + len]; + + memcpy (buf, + &bf, + sizeof (struct BufFormatP)); + memcpy (&buf[sizeof (struct BufFormatP)], + wire_enc, + len); + + /* finally give the state back */ + pth->ptc (pth->ptc_cls, + buf, + sizeof (buf)); + } + free (wire_enc); /* not using GNUNET_free(), + as this one is allocated by libjansson */ GNUNET_free (pth); } @@ -373,10 +428,27 @@ test_execute_wire_transfer (void *cls, struct TALER_WIRE_ExecuteHandle *eh; json_t *wire; struct TALER_Amount amount; - struct TALER_WireTransferIdentifierRawP wtid; + struct BufFormatP bf; - /* FIXME: deserialize buf */ - wire = NULL; + if ( (buf_size <= sizeof (struct BufFormatP)) || + ('\0' != buf[buf_size -1]) ) + { + GNUNET_break (0); + return NULL; + } + memcpy (&bf, + buf, + sizeof (bf)); + TALER_amount_ntoh (&amount, + &bf.amount); + wire = json_loads (&buf[sizeof (struct BufFormatP)], + JSON_REJECT_DUPLICATES, + NULL); + if (NULL == wire) + { + GNUNET_break (0); + return NULL; + } GNUNET_assert (GNUNET_YES == test_wire_validate (wire)); @@ -384,11 +456,12 @@ test_execute_wire_transfer (void *cls, eh->cc = cc; eh->cc_cls = cc_cls; eh->aaih = TALER_BANK_admin_add_incoming (tc->bank, - &wtid, + &bf.wtid, &amount, wire, &execute_cb, eh); + json_decref (wire); if (NULL == eh->aaih) { GNUNET_break (0); -- cgit v1.2.3