rework /reserve/history to address #5010
This commit is contained in:
parent
2ec1b055a0
commit
2d5b238beb
@ -53,6 +53,7 @@ taler_exchange_httpd_SOURCES = \
|
|||||||
taler-exchange-httpd_refresh.c taler-exchange-httpd_refresh.h \
|
taler-exchange-httpd_refresh.c taler-exchange-httpd_refresh.h \
|
||||||
taler-exchange-httpd_refund.c taler-exchange-httpd_refund.h \
|
taler-exchange-httpd_refund.c taler-exchange-httpd_refund.h \
|
||||||
taler-exchange-httpd_reserve.c taler-exchange-httpd_reserve.h \
|
taler-exchange-httpd_reserve.c taler-exchange-httpd_reserve.h \
|
||||||
|
taler-exchange-httpd_reserve_status.c taler-exchange-httpd_reserve_status.h \
|
||||||
taler-exchange-httpd_responses.c taler-exchange-httpd_responses.h \
|
taler-exchange-httpd_responses.c taler-exchange-httpd_responses.h \
|
||||||
taler-exchange-httpd_tracking.c taler-exchange-httpd_tracking.h \
|
taler-exchange-httpd_tracking.c taler-exchange-httpd_tracking.h \
|
||||||
taler-exchange-httpd_wire.c taler-exchange-httpd_wire.h \
|
taler-exchange-httpd_wire.c taler-exchange-httpd_wire.h \
|
||||||
|
@ -552,47 +552,6 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a /reserve/status. Given the public key of a reserve,
|
|
||||||
* return the associated transaction history.
|
|
||||||
*
|
|
||||||
* @param connection the MHD connection to handle
|
|
||||||
* @param reserve_pub public key of the reserve to check
|
|
||||||
* @return MHD result code
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TEH_DB_execute_reserve_status (struct MHD_Connection *connection,
|
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub)
|
|
||||||
{
|
|
||||||
struct TALER_EXCHANGEDB_Session *session;
|
|
||||||
struct TALER_EXCHANGEDB_ReserveHistory *rh;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection,
|
|
||||||
TALER_EC_DB_SETUP_FAILED);
|
|
||||||
}
|
|
||||||
START_TRANSACTION (session, connection);
|
|
||||||
rh = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
|
||||||
session,
|
|
||||||
reserve_pub);
|
|
||||||
COMMIT_TRANSACTION (session, connection);
|
|
||||||
if (NULL == rh)
|
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
|
||||||
MHD_HTTP_NOT_FOUND,
|
|
||||||
"{s:s, s:s}",
|
|
||||||
"error", "Reserve not found",
|
|
||||||
"parameter", "withdraw_pub");
|
|
||||||
res = TEH_RESPONSE_reply_reserve_status_success (connection,
|
|
||||||
rh);
|
|
||||||
TEH_plugin->free_reserve_history (TEH_plugin->cls,
|
|
||||||
rh);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to execute /reserve/withdraw transaction.
|
* Try to execute /reserve/withdraw transaction.
|
||||||
*
|
*
|
||||||
@ -635,12 +594,16 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
struct TALER_Amount fee_withdraw;
|
struct TALER_Amount fee_withdraw;
|
||||||
int res;
|
int res;
|
||||||
int ret;
|
int ret;
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
/* Check if balance is sufficient */
|
/* Check if balance is sufficient */
|
||||||
START_TRANSACTION (session, connection);
|
START_TRANSACTION (session, connection);
|
||||||
rh = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
||||||
session,
|
session,
|
||||||
reserve);
|
reserve,
|
||||||
|
&rh);
|
||||||
|
(void) qs;
|
||||||
|
/* qs: #5010! */
|
||||||
if (NULL == rh)
|
if (NULL == rh)
|
||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
|
@ -97,19 +97,6 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
const struct TALER_EXCHANGEDB_Refund *refund);
|
const struct TALER_EXCHANGEDB_Refund *refund);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a "/reserve/status". Given the public key of a reserve,
|
|
||||||
* return the associated transaction history.
|
|
||||||
*
|
|
||||||
* @param connection the MHD connection to handle
|
|
||||||
* @param reserve_pub public key of the reserve to check
|
|
||||||
* @return MHD result code
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TEH_DB_execute_reserve_status (struct MHD_Connection *connection,
|
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a "/reserve/withdraw". Given a reserve and a properly signed
|
* Execute a "/reserve/withdraw". Given a reserve and a properly signed
|
||||||
* request to withdraw a coin, check the balance of the reserve and
|
* request to withdraw a coin, check the balance of the reserve and
|
||||||
|
@ -29,42 +29,6 @@
|
|||||||
#include "taler-exchange-httpd_keystate.h"
|
#include "taler-exchange-httpd_keystate.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a "/reserve/status" request. Parses the
|
|
||||||
* given "reserve_pub" argument (which should contain the
|
|
||||||
* EdDSA public key of a reserve) and then respond with the
|
|
||||||
* status of the reserve.
|
|
||||||
*
|
|
||||||
* @param rh context of the handler
|
|
||||||
* @param connection the MHD connection to handle
|
|
||||||
* @param[in,out] connection_cls the connection's closure (can be updated)
|
|
||||||
* @param upload_data upload data
|
|
||||||
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
|
|
||||||
* @return MHD result code
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TEH_RESERVE_handler_reserve_status (struct TEH_RequestHandler *rh,
|
|
||||||
struct MHD_Connection *connection,
|
|
||||||
void **connection_cls,
|
|
||||||
const char *upload_data,
|
|
||||||
size_t *upload_data_size)
|
|
||||||
{
|
|
||||||
struct TALER_ReservePublicKeyP reserve_pub;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
res = TEH_PARSE_mhd_request_arg_data (connection,
|
|
||||||
"reserve_pub",
|
|
||||||
&reserve_pub,
|
|
||||||
sizeof (struct TALER_ReservePublicKeyP));
|
|
||||||
if (GNUNET_SYSERR == res)
|
|
||||||
return MHD_NO; /* internal error */
|
|
||||||
if (GNUNET_NO == res)
|
|
||||||
return MHD_YES; /* parse error */
|
|
||||||
return TEH_DB_execute_reserve_status (connection,
|
|
||||||
&reserve_pub);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a "/reserve/withdraw" request. Parses the "reserve_pub"
|
* Handle a "/reserve/withdraw" request. Parses the "reserve_pub"
|
||||||
* EdDSA key of the reserve and the requested "denom_pub" which
|
* EdDSA key of the reserve and the requested "denom_pub" which
|
||||||
|
137
src/exchange/taler-exchange-httpd_reserve_status.c
Normal file
137
src/exchange/taler-exchange-httpd_reserve_status.c
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2014, 2015, 2016 GNUnet e.V.
|
||||||
|
|
||||||
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file taler-exchange-httpd_reserve_status.c
|
||||||
|
* @brief Handle /reserve/status requests
|
||||||
|
* @author Florian Dold
|
||||||
|
* @author Benedikt Mueller
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#include "platform.h"
|
||||||
|
#include <gnunet/gnunet_util_lib.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
#include "taler-exchange-httpd_reserve_status.h"
|
||||||
|
#include "taler-exchange-httpd_parsing.h"
|
||||||
|
#include "taler-exchange-httpd_responses.h"
|
||||||
|
#include "taler-exchange-httpd_keystate.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closure for #reserve_status_transaction.
|
||||||
|
*/
|
||||||
|
struct ReserveStatusContext
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Public key of the reserve the inquiry is about.
|
||||||
|
*/
|
||||||
|
struct TALER_ReservePublicKeyP reserve_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* History of the reserve, set in the callback.
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory *rh;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function implementing /reserve/status transaction.
|
||||||
|
* Execute a /reserve/status. Given the public key of a reserve,
|
||||||
|
* return the associated transaction history. Runs the
|
||||||
|
* transaction logic; IF it returns a non-error code, the transaction
|
||||||
|
* logic MUST NOT queue a MHD response. IF it returns an hard error,
|
||||||
|
* the transaction logic MUST queue a MHD response and set @a mhd_ret.
|
||||||
|
* IF it returns the soft error code, the function MAY be called again
|
||||||
|
* to retry and MUST not queue a MHD response.
|
||||||
|
*
|
||||||
|
* @param cls a `struct ReserveStatusContext *`
|
||||||
|
* @param connection MHD request which triggered the transaction
|
||||||
|
* @param session database session to use
|
||||||
|
* @param[out] mhd_ret set to MHD response status for @a connection,
|
||||||
|
* if transaction failed (!)
|
||||||
|
* @return transaction status
|
||||||
|
*/
|
||||||
|
static enum GNUNET_DB_QueryStatus
|
||||||
|
reserve_status_transaction (void *cls,
|
||||||
|
struct MHD_Connection *connection,
|
||||||
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
|
int *mhd_ret)
|
||||||
|
{
|
||||||
|
struct ReserveStatusContext *rsc = cls;
|
||||||
|
|
||||||
|
return TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
||||||
|
session,
|
||||||
|
&rsc->reserve_pub,
|
||||||
|
&rsc->rh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a "/reserve/status" request. Parses the
|
||||||
|
* given "reserve_pub" argument (which should contain the
|
||||||
|
* EdDSA public key of a reserve) and then respond with the
|
||||||
|
* status of the reserve.
|
||||||
|
*
|
||||||
|
* @param rh context of the handler
|
||||||
|
* @param connection the MHD connection to handle
|
||||||
|
* @param[in,out] connection_cls the connection's closure (can be updated)
|
||||||
|
* @param upload_data upload data
|
||||||
|
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TEH_RESERVE_handler_reserve_status (struct TEH_RequestHandler *rh,
|
||||||
|
struct MHD_Connection *connection,
|
||||||
|
void **connection_cls,
|
||||||
|
const char *upload_data,
|
||||||
|
size_t *upload_data_size)
|
||||||
|
{
|
||||||
|
struct ReserveStatusContext rsc;
|
||||||
|
int res;
|
||||||
|
int mhd_ret;
|
||||||
|
|
||||||
|
res = TEH_PARSE_mhd_request_arg_data (connection,
|
||||||
|
"reserve_pub",
|
||||||
|
&rsc.reserve_pub,
|
||||||
|
sizeof (struct TALER_ReservePublicKeyP));
|
||||||
|
if (GNUNET_SYSERR == res)
|
||||||
|
return MHD_NO; /* internal error */
|
||||||
|
if (GNUNET_NO == res)
|
||||||
|
return MHD_YES; /* parse error */
|
||||||
|
rsc.rh = NULL;
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TEH_DB_run_transaction (connection,
|
||||||
|
&mhd_ret,
|
||||||
|
&reserve_status_transaction,
|
||||||
|
&rsc))
|
||||||
|
return mhd_ret;
|
||||||
|
|
||||||
|
/* generate proper response */
|
||||||
|
if (NULL == rsc.rh)
|
||||||
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
|
MHD_HTTP_NOT_FOUND,
|
||||||
|
"{s:s, s:s}",
|
||||||
|
"error", "Reserve not found",
|
||||||
|
"parameter", "withdraw_pub");
|
||||||
|
mhd_ret = TEH_RESPONSE_reply_reserve_status_success (connection,
|
||||||
|
rsc.rh);
|
||||||
|
TEH_plugin->free_reserve_history (TEH_plugin->cls,
|
||||||
|
rsc.rh);
|
||||||
|
return mhd_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* end of taler-exchange-httpd_reserve_status.c */
|
49
src/exchange/taler-exchange-httpd_reserve_status.h
Normal file
49
src/exchange/taler-exchange-httpd_reserve_status.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2014-2017 GNUnet e.V.
|
||||||
|
|
||||||
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file taler-exchange-httpd_reserve_status.h
|
||||||
|
* @brief Handle /reserve/status requests
|
||||||
|
* @author Florian Dold
|
||||||
|
* @author Benedikt Mueller
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#ifndef TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H
|
||||||
|
#define TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H
|
||||||
|
|
||||||
|
#include <microhttpd.h>
|
||||||
|
#include "taler-exchange-httpd.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a "/reserve/status" request. Parses the
|
||||||
|
* given "reserve_pub" argument (which should contain the
|
||||||
|
* EdDSA public key of a reserve) and then respond with the
|
||||||
|
* status of the reserve.
|
||||||
|
*
|
||||||
|
* @param rh context of the handler
|
||||||
|
* @param connection the MHD connection to handle
|
||||||
|
* @param[in,out] connection_cls the connection's closure (can be updated)
|
||||||
|
* @param upload_data upload data
|
||||||
|
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TEH_RESERVE_handler_reserve_status (struct TEH_RequestHandler *rh,
|
||||||
|
struct MHD_Connection *connection,
|
||||||
|
void **connection_cls,
|
||||||
|
const char *upload_data,
|
||||||
|
size_t *upload_data_size);
|
||||||
|
|
||||||
|
#endif
|
@ -1422,12 +1422,15 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state)
|
|||||||
unsigned int reserve_index;
|
unsigned int reserve_index;
|
||||||
struct TALER_EXCHANGEDB_ReserveHistory *history;
|
struct TALER_EXCHANGEDB_ReserveHistory *history;
|
||||||
struct PERF_TALER_EXCHANGEDB_Data *data;
|
struct PERF_TALER_EXCHANGEDB_Data *data;
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
reserve_index = state->cmd[state->i].details.get_reserve_history.index_reserve;
|
reserve_index = state->cmd[state->i].details.get_reserve_history.index_reserve;
|
||||||
data = &state->cmd[reserve_index].exposed;
|
data = &state->cmd[reserve_index].exposed;
|
||||||
history = state->plugin->get_reserve_history (state->plugin->cls,
|
qs = state->plugin->get_reserve_history (state->plugin->cls,
|
||||||
state->session,
|
state->session,
|
||||||
&data->data.reserve->reserve.pub);
|
&data->data.reserve->reserve.pub,
|
||||||
|
&history);
|
||||||
|
GNUNET_assert (0 >= qs);
|
||||||
GNUNET_assert (NULL != history);
|
GNUNET_assert (NULL != history);
|
||||||
state->plugin->free_reserve_history (state->plugin->cls,
|
state->plugin->free_reserve_history (state->plugin->cls,
|
||||||
history);
|
history);
|
||||||
|
@ -2393,12 +2393,291 @@ postgres_insert_withdraw_info (void *cls,
|
|||||||
if (0 >= qs)
|
if (0 >= qs)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closure for callbacks invoked via #postgres_get_reserve_history.
|
||||||
|
*/
|
||||||
|
struct ReserveHistoryContext
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which reserve are we building the history for?
|
||||||
|
*/
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Where we build the history.
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory *rh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tail of @e rh list.
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory *rh_tail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to #GNUNET_SYSERR on serious internal errors during
|
||||||
|
* the callbacks.
|
||||||
|
*/
|
||||||
|
int status;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append and return a fresh element to the reserve
|
||||||
|
* history kept in @a rhc.
|
||||||
|
*
|
||||||
|
* @param rhc where the history is kept
|
||||||
|
* @return the fresh element that was added
|
||||||
|
*/
|
||||||
|
static struct TALER_EXCHANGEDB_ReserveHistory *
|
||||||
|
append_rh (struct ReserveHistoryContext *rhc)
|
||||||
|
{
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory *tail;
|
||||||
|
|
||||||
|
tail = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
|
||||||
|
if (NULL != rhc->rh_tail)
|
||||||
|
{
|
||||||
|
rhc->rh_tail->next = tail;
|
||||||
|
rhc->rh_tail = tail;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhc->rh_tail = tail;
|
||||||
|
rhc->rh = tail;
|
||||||
|
}
|
||||||
|
return tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add bank transfers to result set for #postgres_get_reserve_history.
|
||||||
|
*
|
||||||
|
* @param cls a `struct ReserveHistoryContext *`
|
||||||
|
* @param result SQL result
|
||||||
|
* @param num_results number of rows in @a result
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
add_bank_to_exchange (void *cls,
|
||||||
|
PGresult *result,
|
||||||
|
unsigned int num_results)
|
||||||
|
{
|
||||||
|
struct ReserveHistoryContext *rhc = cls;
|
||||||
|
|
||||||
|
while (0 < num_results)
|
||||||
|
{
|
||||||
|
struct TALER_EXCHANGEDB_BankTransfer *bt;
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory *tail;
|
||||||
|
|
||||||
|
bt = GNUNET_new (struct TALER_EXCHANGEDB_BankTransfer);
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_variable_size ("wire_reference",
|
||||||
|
&bt->wire_reference,
|
||||||
|
&bt->wire_reference_size),
|
||||||
|
TALER_PQ_result_spec_amount ("credit",
|
||||||
|
&bt->amount),
|
||||||
|
GNUNET_PQ_result_spec_absolute_time ("execution_date",
|
||||||
|
&bt->execution_date),
|
||||||
|
TALER_PQ_result_spec_json ("sender_account_details",
|
||||||
|
&bt->sender_account_details),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result,
|
||||||
|
rs,
|
||||||
|
--num_results))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_free (bt);
|
||||||
|
rhc->status = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bt->reserve_pub = *rhc->reserve_pub;
|
||||||
|
tail = append_rh (rhc);
|
||||||
|
tail->type = TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE;
|
||||||
|
tail->details.bank = bt;
|
||||||
|
} /* end of 'while (0 < rows)' */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add coin withdrawals to result set for #postgres_get_reserve_history.
|
||||||
|
*
|
||||||
|
* @param cls a `struct ReserveHistoryContext *`
|
||||||
|
* @param result SQL result
|
||||||
|
* @param num_results number of rows in @a result
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
add_withdraw_coin (void *cls,
|
||||||
|
PGresult *result,
|
||||||
|
unsigned int num_results)
|
||||||
|
{
|
||||||
|
struct ReserveHistoryContext *rhc = cls;
|
||||||
|
|
||||||
|
while (0 < num_results)
|
||||||
|
{
|
||||||
|
struct TALER_EXCHANGEDB_CollectableBlindcoin *cbc;
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory *tail;
|
||||||
|
|
||||||
|
cbc = GNUNET_new (struct TALER_EXCHANGEDB_CollectableBlindcoin);
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
|
||||||
|
&cbc->h_coin_envelope),
|
||||||
|
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||||
|
&cbc->denom_pub.rsa_public_key),
|
||||||
|
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
|
||||||
|
&cbc->sig.rsa_signature),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
|
||||||
|
&cbc->reserve_sig),
|
||||||
|
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||||
|
&cbc->amount_with_fee),
|
||||||
|
TALER_PQ_result_spec_amount ("fee_withdraw",
|
||||||
|
&cbc->withdraw_fee),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result,
|
||||||
|
rs,
|
||||||
|
--num_results))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_free (cbc);
|
||||||
|
rhc->status = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cbc->reserve_pub = *rhc->reserve_pub;
|
||||||
|
tail = append_rh (rhc);
|
||||||
|
tail->type = TALER_EXCHANGEDB_RO_WITHDRAW_COIN;
|
||||||
|
tail->details.withdraw = cbc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add paybacks to result set for #postgres_get_reserve_history.
|
||||||
|
*
|
||||||
|
* @param cls a `struct ReserveHistoryContext *`
|
||||||
|
* @param result SQL result
|
||||||
|
* @param num_results number of rows in @a result
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
add_payback (void *cls,
|
||||||
|
PGresult *result,
|
||||||
|
unsigned int num_results)
|
||||||
|
{
|
||||||
|
struct ReserveHistoryContext *rhc = cls;
|
||||||
|
|
||||||
|
while (0 < num_results)
|
||||||
|
{
|
||||||
|
struct TALER_EXCHANGEDB_Payback *payback;
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory *tail;
|
||||||
|
|
||||||
|
payback = GNUNET_new (struct TALER_EXCHANGEDB_Payback);
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
TALER_PQ_result_spec_amount ("amount",
|
||||||
|
&payback->value),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
|
||||||
|
&payback->coin.coin_pub),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
|
||||||
|
&payback->coin_blind),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
|
||||||
|
&payback->coin_sig),
|
||||||
|
GNUNET_PQ_result_spec_absolute_time ("timestamp",
|
||||||
|
&payback->timestamp),
|
||||||
|
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||||
|
&payback->coin.denom_pub.rsa_public_key),
|
||||||
|
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
|
||||||
|
&payback->coin.denom_sig.rsa_signature),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result,
|
||||||
|
rs,
|
||||||
|
--num_results))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_free (payback);
|
||||||
|
rhc->status = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
payback->reserve_pub = *rhc->reserve_pub;
|
||||||
|
tail = append_rh (rhc);
|
||||||
|
tail->type = TALER_EXCHANGEDB_RO_PAYBACK_COIN;
|
||||||
|
tail->details.payback = payback;
|
||||||
|
} /* end of 'while (0 < rows)' */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add exchange-to-bank transfers to result set for
|
||||||
|
* #postgres_get_reserve_history.
|
||||||
|
*
|
||||||
|
* @param cls a `struct ReserveHistoryContext *`
|
||||||
|
* @param result SQL result
|
||||||
|
* @param num_results number of rows in @a result
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
add_exchange_to_bank (void *cls,
|
||||||
|
PGresult *result,
|
||||||
|
unsigned int num_results)
|
||||||
|
{
|
||||||
|
struct ReserveHistoryContext *rhc = cls;
|
||||||
|
|
||||||
|
while (0 < num_results)
|
||||||
|
{
|
||||||
|
struct TALER_EXCHANGEDB_ClosingTransfer *closing;
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory *tail;
|
||||||
|
|
||||||
|
closing = GNUNET_new (struct TALER_EXCHANGEDB_ClosingTransfer);
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
TALER_PQ_result_spec_amount ("amount",
|
||||||
|
&closing->amount),
|
||||||
|
TALER_PQ_result_spec_amount ("closing_fee",
|
||||||
|
&closing->closing_fee),
|
||||||
|
GNUNET_PQ_result_spec_absolute_time ("execution_date",
|
||||||
|
&closing->execution_date),
|
||||||
|
TALER_PQ_result_spec_json ("receiver_account",
|
||||||
|
&closing->receiver_account_details),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("wtid",
|
||||||
|
&closing->wtid),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result,
|
||||||
|
rs,
|
||||||
|
--num_results))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_free (closing);
|
||||||
|
rhc->status = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closing->reserve_pub = *rhc->reserve_pub;
|
||||||
|
tail = append_rh (rhc);
|
||||||
|
tail->type = TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK;
|
||||||
|
tail->details.closing = closing;
|
||||||
|
} /* end of 'while (0 < rows)' */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all of the transaction history associated with the specified
|
* Get all of the transaction history associated with the specified
|
||||||
* reserve.
|
* reserve.
|
||||||
@ -2406,289 +2685,77 @@ postgres_insert_withdraw_info (void *cls,
|
|||||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||||
* @param session connection to use
|
* @param session connection to use
|
||||||
* @param reserve_pub public key of the reserve
|
* @param reserve_pub public key of the reserve
|
||||||
* @return known transaction history (NULL if reserve is unknown)
|
* @param[out] rhp set to known transaction history (NULL if reserve is unknown)
|
||||||
|
* @return transaction status
|
||||||
*/
|
*/
|
||||||
static struct TALER_EXCHANGEDB_ReserveHistory *
|
static enum GNUNET_DB_QueryStatus
|
||||||
postgres_get_reserve_history (void *cls,
|
postgres_get_reserve_history (void *cls,
|
||||||
struct TALER_EXCHANGEDB_Session *session,
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub)
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory **rhp)
|
||||||
{
|
{
|
||||||
PGresult *result;
|
struct ReserveHistoryContext rhc;
|
||||||
struct TALER_EXCHANGEDB_ReserveHistory *rh;
|
struct {
|
||||||
struct TALER_EXCHANGEDB_ReserveHistory *rh_tail;
|
/**
|
||||||
int rows;
|
* Name of the prepared statement to run.
|
||||||
int ret;
|
*/
|
||||||
|
const char *statement;
|
||||||
|
/**
|
||||||
|
* Function to use to process the results.
|
||||||
|
*/
|
||||||
|
GNUNET_PQ_PostgresResultHandler cb;
|
||||||
|
} work[] = {
|
||||||
|
/** #TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE */
|
||||||
|
{ "reserves_in_get_transactions",
|
||||||
|
add_bank_to_exchange },
|
||||||
|
/** #TALER_EXCHANGEDB_RO_WITHDRAW_COIN */
|
||||||
|
{ "get_reserves_out",
|
||||||
|
&add_withdraw_coin },
|
||||||
|
/** #TALER_EXCHANGEDB_RO_PAYBACK_COIN */
|
||||||
|
{ "payback_by_reserve",
|
||||||
|
&add_payback },
|
||||||
|
/** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */
|
||||||
|
{ "close_by_reserve",
|
||||||
|
&add_exchange_to_bank },
|
||||||
|
/* List terminator */
|
||||||
|
{ NULL,
|
||||||
|
NULL }
|
||||||
|
};
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
|
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
|
||||||
rh = NULL;
|
rhc.reserve_pub = reserve_pub;
|
||||||
rh_tail = NULL;
|
rhc.rh = NULL;
|
||||||
ret = GNUNET_SYSERR;
|
rhc.rh_tail = NULL;
|
||||||
/** #TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE */
|
rhc.status = GNUNET_OK;
|
||||||
|
for (unsigned int i=0;NULL != work[i].cb;i++)
|
||||||
{
|
{
|
||||||
struct TALER_EXCHANGEDB_BankTransfer *bt;
|
qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
work[i].statement,
|
||||||
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
|
params,
|
||||||
GNUNET_PQ_query_param_end
|
work[i].cb,
|
||||||
};
|
&rhc);
|
||||||
|
if ( (0 > qs) ||
|
||||||
result = GNUNET_PQ_exec_prepared (session->conn,
|
(GNUNET_OK != rhc.status) )
|
||||||
"reserves_in_get_transactions",
|
break;
|
||||||
params);
|
|
||||||
if (PGRES_TUPLES_OK != PQresultStatus (result))
|
|
||||||
{
|
|
||||||
QUERY_ERR (result, session->conn);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (0 == (rows = PQntuples (result)))
|
|
||||||
{
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
||||||
"Asked to fetch history for an unknown reserve.\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
while (0 < rows)
|
|
||||||
{
|
|
||||||
bt = GNUNET_new (struct TALER_EXCHANGEDB_BankTransfer);
|
|
||||||
{
|
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
|
||||||
GNUNET_PQ_result_spec_variable_size ("wire_reference",
|
|
||||||
&bt->wire_reference,
|
|
||||||
&bt->wire_reference_size),
|
|
||||||
TALER_PQ_result_spec_amount ("credit",
|
|
||||||
&bt->amount),
|
|
||||||
GNUNET_PQ_result_spec_absolute_time ("execution_date",
|
|
||||||
&bt->execution_date),
|
|
||||||
TALER_PQ_result_spec_json ("sender_account_details",
|
|
||||||
&bt->sender_account_details),
|
|
||||||
GNUNET_PQ_result_spec_end
|
|
||||||
};
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
GNUNET_PQ_extract_result (result,
|
|
||||||
rs,
|
|
||||||
--rows))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
GNUNET_free (bt);
|
|
||||||
PQclear (result);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bt->reserve_pub = *reserve_pub;
|
|
||||||
if (NULL != rh_tail)
|
|
||||||
{
|
|
||||||
rh_tail->next = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
|
|
||||||
rh_tail = rh_tail->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rh_tail = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
|
|
||||||
rh = rh_tail;
|
|
||||||
}
|
|
||||||
rh_tail->type = TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE;
|
|
||||||
rh_tail->details.bank = bt;
|
|
||||||
} /* end of 'while (0 < rows)' */
|
|
||||||
PQclear (result);
|
|
||||||
}
|
}
|
||||||
/** #TALER_EXCHANGEDB_RO_WITHDRAW_COIN */
|
if ( (qs < 0) ||
|
||||||
{
|
(rhc.status != GNUNET_OK) )
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
|
||||||
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
|
|
||||||
GNUNET_PQ_query_param_end
|
|
||||||
};
|
|
||||||
|
|
||||||
GNUNET_assert (NULL != rh);
|
|
||||||
GNUNET_assert (NULL != rh_tail);
|
|
||||||
GNUNET_assert (NULL == rh_tail->next);
|
|
||||||
result = GNUNET_PQ_exec_prepared (session->conn,
|
|
||||||
"get_reserves_out",
|
|
||||||
params);
|
|
||||||
if (PGRES_TUPLES_OK != PQresultStatus (result))
|
|
||||||
{
|
|
||||||
QUERY_ERR (result, session->conn);
|
|
||||||
PQclear (result);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
rows = PQntuples (result);
|
|
||||||
while (0 < rows)
|
|
||||||
{
|
|
||||||
struct TALER_EXCHANGEDB_CollectableBlindcoin *cbc;
|
|
||||||
|
|
||||||
cbc = GNUNET_new (struct TALER_EXCHANGEDB_CollectableBlindcoin);
|
|
||||||
{
|
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
|
|
||||||
&cbc->h_coin_envelope),
|
|
||||||
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
|
||||||
&cbc->denom_pub.rsa_public_key),
|
|
||||||
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
|
|
||||||
&cbc->sig.rsa_signature),
|
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
|
|
||||||
&cbc->reserve_sig),
|
|
||||||
TALER_PQ_result_spec_amount ("amount_with_fee",
|
|
||||||
&cbc->amount_with_fee),
|
|
||||||
TALER_PQ_result_spec_amount ("fee_withdraw",
|
|
||||||
&cbc->withdraw_fee),
|
|
||||||
GNUNET_PQ_result_spec_end
|
|
||||||
};
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
GNUNET_PQ_extract_result (result,
|
|
||||||
rs,
|
|
||||||
--rows))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
GNUNET_free (cbc);
|
|
||||||
PQclear (result);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
cbc->reserve_pub = *reserve_pub;
|
|
||||||
}
|
|
||||||
rh_tail->next = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
|
|
||||||
rh_tail = rh_tail->next;
|
|
||||||
rh_tail->type = TALER_EXCHANGEDB_RO_WITHDRAW_COIN;
|
|
||||||
rh_tail->details.withdraw = cbc;
|
|
||||||
} /* end of 'while (0 < rows)' */
|
|
||||||
ret = GNUNET_OK;
|
|
||||||
PQclear (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** #TALER_EXCHANGEDB_RO_PAYBACK_COIN */
|
|
||||||
{
|
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
|
||||||
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
|
|
||||||
GNUNET_PQ_query_param_end
|
|
||||||
};
|
|
||||||
|
|
||||||
result = GNUNET_PQ_exec_prepared (session->conn,
|
|
||||||
"payback_by_reserve",
|
|
||||||
params);
|
|
||||||
if (PGRES_TUPLES_OK != PQresultStatus (result))
|
|
||||||
{
|
|
||||||
QUERY_ERR (result, session->conn);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
rows = PQntuples (result);
|
|
||||||
while (0 < rows)
|
|
||||||
{
|
|
||||||
struct TALER_EXCHANGEDB_Payback *payback;
|
|
||||||
|
|
||||||
payback = GNUNET_new (struct TALER_EXCHANGEDB_Payback);
|
|
||||||
{
|
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
|
||||||
TALER_PQ_result_spec_amount ("amount",
|
|
||||||
&payback->value),
|
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
|
|
||||||
&payback->coin.coin_pub),
|
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
|
|
||||||
&payback->coin_blind),
|
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
|
|
||||||
&payback->coin_sig),
|
|
||||||
GNUNET_PQ_result_spec_absolute_time ("timestamp",
|
|
||||||
&payback->timestamp),
|
|
||||||
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
|
||||||
&payback->coin.denom_pub.rsa_public_key),
|
|
||||||
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
|
|
||||||
&payback->coin.denom_sig.rsa_signature),
|
|
||||||
GNUNET_PQ_result_spec_end
|
|
||||||
};
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
GNUNET_PQ_extract_result (result,
|
|
||||||
rs,
|
|
||||||
--rows))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
GNUNET_free (payback);
|
|
||||||
PQclear (result);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
payback->reserve_pub = *reserve_pub;
|
|
||||||
if (NULL != rh_tail)
|
|
||||||
{
|
|
||||||
rh_tail->next = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
|
|
||||||
rh_tail = rh_tail->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rh_tail = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
|
|
||||||
rh = rh_tail;
|
|
||||||
}
|
|
||||||
rh_tail->type = TALER_EXCHANGEDB_RO_PAYBACK_COIN;
|
|
||||||
rh_tail->details.payback = payback;
|
|
||||||
} /* end of 'while (0 < rows)' */
|
|
||||||
PQclear (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */
|
|
||||||
{
|
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
|
||||||
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
|
|
||||||
GNUNET_PQ_query_param_end
|
|
||||||
};
|
|
||||||
|
|
||||||
result = GNUNET_PQ_exec_prepared (session->conn,
|
|
||||||
"close_by_reserve",
|
|
||||||
params);
|
|
||||||
if (PGRES_TUPLES_OK != PQresultStatus (result))
|
|
||||||
{
|
|
||||||
QUERY_ERR (result, session->conn);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
rows = PQntuples (result);
|
|
||||||
while (0 < rows)
|
|
||||||
{
|
|
||||||
struct TALER_EXCHANGEDB_ClosingTransfer *closing;
|
|
||||||
|
|
||||||
closing = GNUNET_new (struct TALER_EXCHANGEDB_ClosingTransfer);
|
|
||||||
{
|
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
|
||||||
TALER_PQ_result_spec_amount ("amount",
|
|
||||||
&closing->amount),
|
|
||||||
TALER_PQ_result_spec_amount ("closing_fee",
|
|
||||||
&closing->closing_fee),
|
|
||||||
GNUNET_PQ_result_spec_absolute_time ("execution_date",
|
|
||||||
&closing->execution_date),
|
|
||||||
TALER_PQ_result_spec_json ("receiver_account",
|
|
||||||
&closing->receiver_account_details),
|
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("wtid",
|
|
||||||
&closing->wtid),
|
|
||||||
GNUNET_PQ_result_spec_end
|
|
||||||
};
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
GNUNET_PQ_extract_result (result,
|
|
||||||
rs,
|
|
||||||
--rows))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
GNUNET_free (closing);
|
|
||||||
PQclear (result);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closing->reserve_pub = *reserve_pub;
|
|
||||||
if (NULL != rh_tail)
|
|
||||||
{
|
|
||||||
rh_tail->next = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
|
|
||||||
rh_tail = rh_tail->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rh_tail = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
|
|
||||||
rh = rh_tail;
|
|
||||||
}
|
|
||||||
rh_tail->type = TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK;
|
|
||||||
rh_tail->details.closing = closing;
|
|
||||||
} /* end of 'while (0 < rows)' */
|
|
||||||
PQclear (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (GNUNET_SYSERR == ret)
|
|
||||||
{
|
{
|
||||||
common_free_reserve_history (cls,
|
common_free_reserve_history (cls,
|
||||||
rh);
|
rhc.rh);
|
||||||
rh = NULL;
|
rhc.rh = NULL;
|
||||||
|
if (qs >= 0)
|
||||||
|
{
|
||||||
|
/* status == SYSERR is a very hard error... */
|
||||||
|
qs = GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rh;
|
*rhp = rhc.rh;
|
||||||
|
return qs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1447,6 +1447,7 @@ run (void *cls)
|
|||||||
unsigned int cnt;
|
unsigned int cnt;
|
||||||
void *rr;
|
void *rr;
|
||||||
size_t rr_size;
|
size_t rr_size;
|
||||||
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
dkp = NULL;
|
dkp = NULL;
|
||||||
rh = NULL;
|
rh = NULL;
|
||||||
@ -1671,9 +1672,11 @@ run (void *cls)
|
|||||||
|
|
||||||
json_decref (sndr);
|
json_decref (sndr);
|
||||||
result = 7;
|
result = 7;
|
||||||
rh = plugin->get_reserve_history (plugin->cls,
|
qs = plugin->get_reserve_history (plugin->cls,
|
||||||
session,
|
session,
|
||||||
&reserve_pub);
|
&reserve_pub,
|
||||||
|
&rh);
|
||||||
|
FAILIF (0 > qs);
|
||||||
FAILIF (NULL == rh);
|
FAILIF (NULL == rh);
|
||||||
rh_head = rh;
|
rh_head = rh;
|
||||||
for (cnt=0; NULL != rh_head; rh_head=rh_head->next, cnt++)
|
for (cnt=0; NULL != rh_head; rh_head=rh_head->next, cnt++)
|
||||||
|
@ -1268,12 +1268,14 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param session connection to use
|
* @param session connection to use
|
||||||
* @param reserve_pub public key of the reserve
|
* @param reserve_pub public key of the reserve
|
||||||
* @return known transaction history (NULL if reserve is unknown)
|
* @param[out] rhp set to known transaction history (NULL if reserve is unknown)
|
||||||
|
* @return transaction status
|
||||||
*/
|
*/
|
||||||
struct TALER_EXCHANGEDB_ReserveHistory *
|
enum GNUNET_DB_QueryStatus
|
||||||
(*get_reserve_history) (void *cls,
|
(*get_reserve_history) (void *cls,
|
||||||
struct TALER_EXCHANGEDB_Session *session,
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub);
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
struct TALER_EXCHANGEDB_ReserveHistory **rhp);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user