From 8f854fb04c02f2e10ab41be3140bdf9aa05e0a83 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 8 May 2017 13:31:28 +0200 Subject: add 'get_latest_reserve_in_reference' to exchangedb API --- src/exchangedb/perf_taler_exchangedb_interpreter.c | 4 +- src/exchangedb/plugin_exchangedb_postgres.c | 70 ++++++++++++++++++++++ src/exchangedb/test_exchangedb.c | 28 +++++++++ src/include/taler_exchangedb_plugin.h | 17 ++++++ 4 files changed, 117 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c b/src/exchangedb/perf_taler_exchangedb_interpreter.c index 9c4eb367a..5e4155c38 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.c +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c @@ -1476,7 +1476,7 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) { unsigned int dki_index; unsigned int reserve_index; - struct PERF_TALER_EXCHANGEDB_Coin *coin ; + struct PERF_TALER_EXCHANGEDB_Coin *coin; dki_index = state->cmd[state->i].details.create_withdraw.index_dki; reserve_index = state->cmd[state->i].details.create_withdraw.index_reserve; @@ -1491,7 +1491,7 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) { unsigned int coin_index; int ret; - struct PERF_TALER_EXCHANGEDB_Coin *coin ; + struct PERF_TALER_EXCHANGEDB_Coin *coin; coin_index = state->cmd[state->i].details.insert_withdraw.index_coin; coin = state->cmd[coin_index].exposed.data.coin; diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 0bf82f048..1ba9914fd 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -769,6 +769,15 @@ postgres_prepare (PGconn *db_conn) 7, NULL); + /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound + transactions for reserves with serial id '\geq' the given parameter */ + PREPARE ("reserves_in_get_latest_wire_reference", + "SELECT" + " wire_reference" + " FROM reserves_in" + " ORDER BY reserve_in_serial_id DESC LIMIT 1", + 0, NULL); + /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound transactions for reserves with serial id '\geq' the given parameter */ PREPARE ("audit_reserves_in_get_transactions_incr", @@ -2250,6 +2259,66 @@ postgres_reserves_in_insert (void *cls, } +/** + * Obtain the most recent @a wire_reference that was inserted via @e reserves_in_insert. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param session the database session handle + * @param[out] wire_reference set to unique reference identifying the wire transfer (binary blob) + * @param[out] wire_reference_size set to number of bytes in @a wire_reference + * @return #GNUNET_OK upon success; #GNUNET_NO if we never got any incoming transfers + * #GNUNET_SYSERR upon failures (DB error) + */ +static int +postgres_get_latest_reserve_in_reference (void *cls, + struct TALER_EXCHANGEDB_Session *session, + void **wire_reference, + size_t *wire_reference_size) +{ + PGresult *result; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + int ret; + + ret = GNUNET_SYSERR; + result = GNUNET_PQ_exec_prepared (session->conn, + "reserves_in_get_latest_wire_reference", + params); + if (PGRES_TUPLES_OK != PQresultStatus (result)) + { + QUERY_ERR (result, session->conn); + goto cleanup; + } + if (0 == PQntuples (result)) + { + ret = GNUNET_NO; + goto cleanup; + } + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_variable_size ("wire_reference", + wire_reference, + wire_reference_size), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + 0)) + { + GNUNET_break (0); + goto cleanup; + } + } + ret = GNUNET_OK; + cleanup: + PQclear (result); + return ret; +} + + /** * Locate the response for a /reserve/withdraw request under the * key of the hash of the blinded message. @@ -6657,6 +6726,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) plugin->get_denomination_info = &postgres_get_denomination_info; plugin->reserve_get = &postgres_reserve_get; plugin->reserves_in_insert = &postgres_reserves_in_insert; + plugin->get_latest_reserve_in_reference = &postgres_get_latest_reserve_in_reference; plugin->get_withdraw_info = &postgres_get_withdraw_info; plugin->insert_withdraw_info = &postgres_insert_withdraw_info; plugin->get_reserve_history = &postgres_get_reserve_history; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 9b399233b..f5358ff0a 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -1445,6 +1445,8 @@ run (void *cls) \"r\":123456789, \ \"address\": \"foobar\"}"; unsigned int cnt; + void *rr; + size_t rr_size; dkp = NULL; rh = NULL; @@ -1503,6 +1505,11 @@ run (void *cls) result = 4; sndr = json_loads ("{ \"account\":\"1\" }", 0, NULL); GNUNET_assert (NULL != sndr); + FAILIF (GNUNET_NO != + plugin->get_latest_reserve_in_reference (plugin->cls, + session, + &rr, + &rr_size)); FAILIF (GNUNET_OK != plugin->reserves_in_insert (plugin->cls, session, @@ -1512,6 +1519,14 @@ run (void *cls) sndr, "TEST", 4)); + FAILIF (GNUNET_OK != + plugin->get_latest_reserve_in_reference (plugin->cls, + session, + &rr, + &rr_size)); + FAILIF (4 != rr_size); + FAILIF (0 != memcmp ("TEST", rr, 4)); + GNUNET_free (rr); FAILIF (GNUNET_OK != check_reserve (session, &reserve_pub, @@ -1527,6 +1542,19 @@ run (void *cls) sndr, "TEST2", 5)); + FAILIF (GNUNET_OK != + plugin->get_latest_reserve_in_reference (plugin->cls, + session, + &rr, + &rr_size)); + FAILIF (GNUNET_OK != + plugin->get_latest_reserve_in_reference (plugin->cls, + session, + &rr, + &rr_size)); + FAILIF (5 != rr_size); + FAILIF (0 != memcmp ("TEST2", rr, 5)); + GNUNET_free (rr); json_decref (sndr); FAILIF (GNUNET_OK != check_reserve (session, diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index e4277b462..01948a1c6 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -1204,6 +1204,23 @@ struct TALER_EXCHANGEDB_Plugin size_t wire_reference_size); + /** + * Obtain the most recent @a wire_reference that was inserted via @e reserves_in_insert. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param db the database connection handle + * @param[out] wire_reference set to unique reference identifying the wire transfer (binary blob) + * @param[out] wire_reference_size set to number of bytes in @a wire_reference + * @return #GNUNET_OK upon success; #GNUNET_NO if we never got any incoming transfers + * #GNUNET_SYSERR upon failures (DB error) + */ + int + (*get_latest_reserve_in_reference)(void *cls, + struct TALER_EXCHANGEDB_Session *db, + void **wire_reference, + size_t *wire_reference_size); + + /** * Locate the response for a /withdraw request under the * key of the hash of the blinded message. -- cgit v1.2.3