towards LP support for GET /deposits (#7808)
This commit is contained in:
parent
2de2b6e3cf
commit
7c0de44a2b
@ -2215,6 +2215,7 @@ do_shutdown (void *cls)
|
|||||||
|
|
||||||
mhd = TALER_MHD_daemon_stop ();
|
mhd = TALER_MHD_daemon_stop ();
|
||||||
TEH_resume_keys_requests (true);
|
TEH_resume_keys_requests (true);
|
||||||
|
TEH_deposits_get_cleanup ();
|
||||||
TEH_reserves_get_cleanup ();
|
TEH_reserves_get_cleanup ();
|
||||||
TEH_purses_get_cleanup ();
|
TEH_purses_get_cleanup ();
|
||||||
TEH_kyc_check_cleanup ();
|
TEH_kyc_check_cleanup ();
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <microhttpd.h>
|
#include <microhttpd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include "taler_dbevents.h"
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "taler_mhd_lib.h"
|
#include "taler_mhd_lib.h"
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
@ -37,6 +38,26 @@
|
|||||||
struct DepositWtidContext
|
struct DepositWtidContext
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kept in a DLL.
|
||||||
|
*/
|
||||||
|
struct DepositWtidContext *next;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kept in a DLL.
|
||||||
|
*/
|
||||||
|
struct DepositWtidContext *prev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context for the request we are processing.
|
||||||
|
*/
|
||||||
|
struct TEH_RequestContext *rc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscription for the database event we are waiting for.
|
||||||
|
*/
|
||||||
|
struct GNUNET_DB_EventHandler *eh;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash over the proposal data of the contract for which this deposit is made.
|
* Hash over the proposal data of the contract for which this deposit is made.
|
||||||
*/
|
*/
|
||||||
@ -85,6 +106,11 @@ struct DepositWtidContext
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_TIME_Timestamp execution_time;
|
struct GNUNET_TIME_Timestamp execution_time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout of the request, for long-polling.
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_Absolute timeout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set by #handle_wtid to the coin contribution to the transaction
|
* Set by #handle_wtid to the coin contribution to the transaction
|
||||||
* (that is, @e coin_contribution minus @e coin_fee).
|
* (that is, @e coin_contribution minus @e coin_fee).
|
||||||
@ -107,9 +133,45 @@ struct DepositWtidContext
|
|||||||
* Set to #GNUNET_SYSERR if there was a serious error.
|
* Set to #GNUNET_SYSERR if there was a serious error.
|
||||||
*/
|
*/
|
||||||
enum GNUNET_GenericReturnValue pending;
|
enum GNUNET_GenericReturnValue pending;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #GNUNET_YES if we were suspended, #GNUNET_SYSERR
|
||||||
|
* if we were woken up due to shutdown.
|
||||||
|
*/
|
||||||
|
enum GNUNET_GenericReturnValue suspended;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Head of DLL of suspended requests.
|
||||||
|
*/
|
||||||
|
static struct DepositWtidContext *dwc_head;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tail of DLL of suspended requests.
|
||||||
|
*/
|
||||||
|
static struct DepositWtidContext *dwc_tail;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TEH_deposits_get_cleanup ()
|
||||||
|
{
|
||||||
|
struct DepositWtidContext *n;
|
||||||
|
for (struct DepositWtidContext *ctx = dwc_head;
|
||||||
|
NULL != ctx;
|
||||||
|
ctx = n)
|
||||||
|
{
|
||||||
|
n = ctx->next;
|
||||||
|
GNUNET_assert (GNUNET_YES == ctx->suspended);
|
||||||
|
ctx->suspended = GNUNET_SYSERR;
|
||||||
|
MHD_resume_connection (ctx->rc->connection);
|
||||||
|
GNUNET_CONTAINER_DLL_remove (dwc_head,
|
||||||
|
dwc_tail,
|
||||||
|
ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A merchant asked for details about a deposit. Provide
|
* A merchant asked for details about a deposit. Provide
|
||||||
* them. Generates the 200 reply.
|
* them. Generates the 200 reply.
|
||||||
@ -233,34 +295,99 @@ deposits_get_transaction (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called on events received from Postgres.
|
||||||
|
* Wakes up long pollers.
|
||||||
|
*
|
||||||
|
* @param cls the `struct DepositWtidContext *`
|
||||||
|
* @param extra additional event data provided
|
||||||
|
* @param extra_size number of bytes in @a extra
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
db_event_cb (void *cls,
|
||||||
|
const void *extra,
|
||||||
|
size_t extra_size)
|
||||||
|
{
|
||||||
|
struct DepositWtidContext *ctx = cls;
|
||||||
|
struct GNUNET_AsyncScopeSave old_scope;
|
||||||
|
|
||||||
|
(void) extra;
|
||||||
|
(void) extra_size;
|
||||||
|
if (GNUNET_NO != ctx->suspended)
|
||||||
|
return; /* might get multiple wake-up events */
|
||||||
|
GNUNET_CONTAINER_DLL_remove (dwc_head,
|
||||||
|
dwc_tail,
|
||||||
|
ctx);
|
||||||
|
GNUNET_async_scope_enter (&ctx->rc->async_scope_id,
|
||||||
|
&old_scope);
|
||||||
|
TEH_check_invariants ();
|
||||||
|
ctx->suspended = GNUNET_NO;
|
||||||
|
MHD_resume_connection (ctx->rc->connection);
|
||||||
|
TALER_MHD_daemon_trigger ();
|
||||||
|
TEH_check_invariants ();
|
||||||
|
GNUNET_async_scope_restore (&old_scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup and return the wire transfer identifier.
|
* Lookup and return the wire transfer identifier.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to handle
|
|
||||||
* @param ctx context of the signed request to execute
|
* @param ctx context of the signed request to execute
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
static MHD_RESULT
|
static MHD_RESULT
|
||||||
handle_track_transaction_request (
|
handle_track_transaction_request (
|
||||||
struct MHD_Connection *connection,
|
|
||||||
struct DepositWtidContext *ctx)
|
struct DepositWtidContext *ctx)
|
||||||
{
|
{
|
||||||
MHD_RESULT mhd_ret;
|
struct MHD_Connection *connection = ctx->rc->connection;
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if ( (GNUNET_TIME_absolute_is_future (ctx->timeout)) &&
|
||||||
TEH_DB_run_transaction (connection,
|
(NULL == ctx->eh) )
|
||||||
"handle deposits GET",
|
{
|
||||||
TEH_MT_REQUEST_OTHER,
|
struct TALER_CoinDepositEventP rep = {
|
||||||
&mhd_ret,
|
.header.size = htons (sizeof (rep)),
|
||||||
&deposits_get_transaction,
|
.header.type = htons (TALER_DBEVENT_EXCHANGE_DEPOSIT_STATUS_CHANGED),
|
||||||
ctx))
|
.coin_pub = ctx->coin_pub,
|
||||||
return mhd_ret;
|
.merchant_pub = ctx->merchant,
|
||||||
|
.h_wire = ctx->h_wire
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx->eh = TEH_plugin->event_listen (
|
||||||
|
TEH_plugin->cls,
|
||||||
|
GNUNET_TIME_absolute_get_remaining (ctx->timeout),
|
||||||
|
&rep.header,
|
||||||
|
&db_event_cb,
|
||||||
|
ctx);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
MHD_RESULT mhd_ret;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TEH_DB_run_transaction (connection,
|
||||||
|
"handle deposits GET",
|
||||||
|
TEH_MT_REQUEST_OTHER,
|
||||||
|
&mhd_ret,
|
||||||
|
&deposits_get_transaction,
|
||||||
|
ctx))
|
||||||
|
return mhd_ret;
|
||||||
|
}
|
||||||
if (GNUNET_SYSERR == ctx->pending)
|
if (GNUNET_SYSERR == ctx->pending)
|
||||||
return TALER_MHD_reply_with_error (connection,
|
return TALER_MHD_reply_with_error (connection,
|
||||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
TALER_EC_GENERIC_DB_INVARIANT_FAILURE,
|
TALER_EC_GENERIC_DB_INVARIANT_FAILURE,
|
||||||
"wire fees exceed aggregate in database");
|
"wire fees exceed aggregate in database");
|
||||||
if (ctx->pending)
|
if (GNUNET_YES == ctx->pending)
|
||||||
|
{
|
||||||
|
if ( (GNUNET_TIME_absolute_is_future (ctx->timeout)) &&
|
||||||
|
(GNUNET_NO == ctx->suspended) )
|
||||||
|
{
|
||||||
|
GNUNET_CONTAINER_DLL_insert (dwc_head,
|
||||||
|
dwc_tail,
|
||||||
|
ctx);
|
||||||
|
ctx->suspended = GNUNET_YES;
|
||||||
|
MHD_suspend_connection (connection);
|
||||||
|
return MHD_YES;
|
||||||
|
}
|
||||||
return TALER_MHD_REPLY_JSON_PACK (
|
return TALER_MHD_REPLY_JSON_PACK (
|
||||||
connection,
|
connection,
|
||||||
MHD_HTTP_ACCEPTED,
|
MHD_HTTP_ACCEPTED,
|
||||||
@ -276,6 +403,7 @@ handle_track_transaction_request (
|
|||||||
ctx->kyc.ok),
|
ctx->kyc.ok),
|
||||||
GNUNET_JSON_pack_timestamp ("execution_time",
|
GNUNET_JSON_pack_timestamp ("execution_time",
|
||||||
ctx->execution_time));
|
ctx->execution_time));
|
||||||
|
}
|
||||||
return reply_deposit_details (connection,
|
return reply_deposit_details (connection,
|
||||||
ctx);
|
ctx);
|
||||||
}
|
}
|
||||||
@ -291,6 +419,13 @@ dwc_cleaner (struct TEH_RequestContext *rc)
|
|||||||
{
|
{
|
||||||
struct DepositWtidContext *ctx = rc->rh_ctx;
|
struct DepositWtidContext *ctx = rc->rh_ctx;
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_NO == ctx->suspended);
|
||||||
|
if (NULL != ctx->eh)
|
||||||
|
{
|
||||||
|
TEH_plugin->event_listen_cancel (TEH_plugin->cls,
|
||||||
|
ctx->eh);
|
||||||
|
ctx->eh = NULL;
|
||||||
|
}
|
||||||
GNUNET_free (ctx);
|
GNUNET_free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,6 +439,7 @@ TEH_handler_deposits_get (struct TEH_RequestContext *rc,
|
|||||||
if (NULL == ctx)
|
if (NULL == ctx)
|
||||||
{
|
{
|
||||||
ctx = GNUNET_new (struct DepositWtidContext);
|
ctx = GNUNET_new (struct DepositWtidContext);
|
||||||
|
ctx->rc = rc;
|
||||||
rc->rh_ctx = ctx;
|
rc->rh_ctx = ctx;
|
||||||
rc->rh_cleaner = &dwc_cleaner;
|
rc->rh_cleaner = &dwc_cleaner;
|
||||||
|
|
||||||
@ -358,6 +494,8 @@ TEH_handler_deposits_get (struct TEH_RequestContext *rc,
|
|||||||
TALER_MHD_parse_request_arg_auto_t (rc->connection,
|
TALER_MHD_parse_request_arg_auto_t (rc->connection,
|
||||||
"merchant_sig",
|
"merchant_sig",
|
||||||
&ctx->merchant_sig);
|
&ctx->merchant_sig);
|
||||||
|
TALER_MHD_parse_request_timeout (rc->connection,
|
||||||
|
&ctx->timeout);
|
||||||
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
|
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
|
||||||
{
|
{
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -376,8 +514,7 @@ TEH_handler_deposits_get (struct TEH_RequestContext *rc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle_track_transaction_request (rc->connection,
|
return handle_track_transaction_request (ctx);
|
||||||
ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,13 @@
|
|||||||
#include "taler-exchange-httpd.h"
|
#include "taler-exchange-httpd.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resume long pollers on GET /deposits.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TEH_deposits_get_cleanup (void);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB"
|
* Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB"
|
||||||
* request.
|
* request.
|
||||||
|
@ -57,8 +57,7 @@ struct ReservePoller
|
|||||||
struct TEH_RequestContext *rc;
|
struct TEH_RequestContext *rc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscription for the database event we are
|
* Subscription for the database event we are waiting for.
|
||||||
* waiting for.
|
|
||||||
*/
|
*/
|
||||||
struct GNUNET_DB_EventHandler *eh;
|
struct GNUNET_DB_EventHandler *eh;
|
||||||
|
|
||||||
|
@ -149,7 +149,35 @@ struct TALER_EXCHANGEDB_DenominationKeyInformation
|
|||||||
GNUNET_NETWORK_STRUCT_BEGIN
|
GNUNET_NETWORK_STRUCT_BEGIN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature of events signalling a reserve got funding.
|
* Events signalling that a coin deposit status
|
||||||
|
* changed.
|
||||||
|
*/
|
||||||
|
struct TALER_CoinDepositEventP
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Of type #TALER_DBEVENT_EXCHANGE_DEPOSIT_STATUS_CHANGED.
|
||||||
|
*/
|
||||||
|
struct GNUNET_DB_EventHeaderP header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The coin's public key.
|
||||||
|
*/
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Merchant's public key.
|
||||||
|
*/
|
||||||
|
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash over the wiring information of the merchant.
|
||||||
|
*/
|
||||||
|
struct TALER_MerchantWireHashP h_wire;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events signalling a reserve got funding.
|
||||||
*/
|
*/
|
||||||
struct TALER_ReserveEventP
|
struct TALER_ReserveEventP
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user