support long_poll_ms argument in bank API (#6987)

This commit is contained in:
Christian Grothoff 2021-08-12 13:13:42 +02:00
parent 10d8342f90
commit f174781b57
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
13 changed files with 167 additions and 121 deletions

View File

@ -1014,7 +1014,7 @@ wire_out_cb (void *cls,
payto_uri = TALER_JSON_wire_to_payto (wire);
if (0 != strcasecmp (payto_uri,
roi->details.credit_account_url))
roi->details.credit_account_uri))
{
/* Destination bank account is wrong in actual wire transfer, so
we should count the wire transfer as entirely spurious, and
@ -1055,7 +1055,7 @@ wire_out_cb (void *cls,
"receiver account mismatch"),
GNUNET_JSON_pack_string ("target",
roi->details.
credit_account_url),
credit_account_uri),
GNUNET_JSON_pack_string ("account_section",
wa->ai->section_name)));
TALER_ARL_amount_add (&total_bad_amount_out_minus,
@ -1165,7 +1165,7 @@ check_rc_matches (void *cls,
if ( (0 == GNUNET_memcmp (&ctx->roi->details.wtid,
&rc->wtid)) &&
(0 == strcasecmp (rc->receiver_account,
ctx->roi->details.credit_account_url)) &&
ctx->roi->details.credit_account_uri)) &&
(0 == TALER_amount_cmp (&rc->amount,
&ctx->roi->details.amount)) )
{
@ -1207,7 +1207,7 @@ complain_out_not_found (void *cls,
};
(void) key;
hash_rc (roi->details.credit_account_url,
hash_rc (roi->details.credit_account_uri,
&roi->details.wtid,
&rkey);
GNUNET_CONTAINER_multihashmap_get_multiple (reserve_closures,
@ -1341,7 +1341,7 @@ history_debit_cb (void *cls,
TALER_B2S (&details->wtid));
/* Update offset */
wa->out_wire_off = row_off;
slen = strlen (details->credit_account_url) + 1;
slen = strlen (details->credit_account_uri) + 1;
roi = GNUNET_malloc (sizeof (struct ReserveOutInfo)
+ slen);
GNUNET_CRYPTO_hash (&details->wtid,
@ -1350,9 +1350,9 @@ history_debit_cb (void *cls,
roi->details.amount = details->amount;
roi->details.execution_date = details->execution_date;
roi->details.wtid = details->wtid;
roi->details.credit_account_url = (const char *) &roi[1];
roi->details.credit_account_uri = (const char *) &roi[1];
memcpy (&roi[1],
details->credit_account_url,
details->credit_account_uri,
slen);
if (GNUNET_OK !=
GNUNET_CONTAINER_multihashmap_put (out_map,
@ -1414,6 +1414,7 @@ process_debits (void *cls)
wa->ai->auth,
wa->out_wire_off,
INT64_MAX,
GNUNET_TIME_UNIT_ZERO,
&history_debit_cb,
wa);
if (NULL == wa->dhh)
@ -1496,7 +1497,7 @@ reserve_in_cb (void *cls,
rii->details.amount = *credit;
rii->details.execution_date = execution_date;
rii->details.reserve_pub = *reserve_pub;
rii->details.debit_account_url = (const char *) &rii[1];
rii->details.debit_account_uri = (const char *) &rii[1];
memcpy (&rii[1],
sender_account_details,
slen);
@ -1752,8 +1753,8 @@ history_credit_cb (void *cls,
}
goto cleanup;
}
if (0 != strcasecmp (details->debit_account_url,
rii->details.debit_account_url))
if (0 != strcasecmp (details->debit_account_uri,
rii->details.debit_account_uri))
{
TALER_ARL_report (report_missattribution_in_inconsistencies,
GNUNET_JSON_PACK (
@ -1843,6 +1844,7 @@ process_credits (void *cls)
wa->ai->auth,
wa->in_wire_off,
INT64_MAX,
GNUNET_TIME_UNIT_ZERO,
&history_credit_cb,
wa);
if (NULL == wa->chh)

View File

@ -14,6 +14,7 @@ taler_fakebank_run_SOURCES = \
taler-fakebank-run.c
taler_fakebank_run_LDADD = \
libtalerfakebank.la \
$(top_builddir)/src/mhd/libtalermhd.la \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetutil

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2017--2020 Taler Systems SA
Copyright (C) 2017--2021 Taler Systems SA
TALER is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -97,9 +97,9 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh,
GNUNET_JSON_spec_fixed_auto ("reserve_pub",
&td.reserve_pub),
GNUNET_JSON_spec_string ("debit_account",
&td.debit_account_url),
&td.debit_account_uri),
GNUNET_JSON_spec_string ("credit_account",
&td.credit_account_url),
&td.credit_account_uri),
GNUNET_JSON_spec_end ()
};
json_t *transaction = json_array_get (history_array,
@ -217,12 +217,14 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx,
const struct TALER_BANK_AuthenticationData *auth,
uint64_t start_row,
int64_t num_results,
struct GNUNET_TIME_Relative timeout,
TALER_BANK_CreditHistoryCallback hres_cb,
void *hres_cb_cls)
{
char url[128];
struct TALER_BANK_CreditHistoryHandle *hh;
CURL *eh;
unsigned long long tms;
if (0 == num_results)
{
@ -230,20 +232,43 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx,
return NULL;
}
tms = (unsigned long long) (timeout.rel_value_us
/ GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us);
if ( ( (UINT64_MAX == start_row) &&
(0 > num_results) ) ||
( (0 == start_row) &&
(0 < num_results) ) )
{
if ( (0 < num_results) &&
(! GNUNET_TIME_relative_is_zero (timeout)) )
GNUNET_snprintf (url,
sizeof (url),
"history/incoming?delta=%lld&long_poll_ms=%llu",
(long long) num_results,
tms);
else
GNUNET_snprintf (url,
sizeof (url),
"history/incoming?delta=%lld",
(long long) num_results);
}
else
{
if ( (0 < num_results) &&
(! GNUNET_TIME_relative_is_zero (timeout)) )
GNUNET_snprintf (url,
sizeof (url),
"history/incoming?delta=%lld&start=%llu&long_poll_ms=%llu",
(long long) num_results,
(unsigned long long) start_row,
tms);
else
GNUNET_snprintf (url,
sizeof (url),
"history/incoming?delta=%lld&start=%llu",
(long long) num_results,
(unsigned long long) start_row);
}
hh = GNUNET_new (struct TALER_BANK_CreditHistoryHandle);
hh->hcb = hres_cb;
hh->hcb_cls = hres_cb_cls;
@ -275,6 +300,13 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx,
curl_easy_cleanup (eh);
return NULL;
}
if (0 != tms)
{
GNUNET_break (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_TIMEOUT_MS,
(long) tms));
}
hh->job = GNUNET_CURL_job_add2 (ctx,
eh,
NULL,

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2017--2020 Taler Systems SA
Copyright (C) 2017--2021 Taler Systems SA
TALER is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -97,9 +97,9 @@ parse_account_history (struct TALER_BANK_DebitHistoryHandle *hh,
GNUNET_JSON_spec_fixed_auto ("wtid",
&td.wtid),
GNUNET_JSON_spec_string ("credit_account",
&td.credit_account_url),
&td.credit_account_uri),
GNUNET_JSON_spec_string ("debit_account",
&td.debit_account_url),
&td.debit_account_uri),
GNUNET_JSON_spec_string ("exchange_base_url",
&td.exchange_base_url),
GNUNET_JSON_spec_end ()
@ -214,35 +214,19 @@ handle_debit_history_finished (void *cls,
}
/**
* Request the debit history of the exchange's bank account.
*
* @param ctx curl context for the event loop
* @param auth authentication data to use
* @param start_row from which row on do we want to get results,
* use UINT64_MAX for the latest; exclusive
* @param num_results how many results do we want;
* negative numbers to go into the past, positive numbers
* to go into the future starting at @a start_row;
* must not be zero.
* @param hres_cb the callback to call with the transaction
* history
* @param hres_cb_cls closure for the above callback
* @return NULL if the inputs are invalid (i.e. zero value for
* @e num_results). In this case, the callback is not
* called.
*/
struct TALER_BANK_DebitHistoryHandle *
TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
const struct TALER_BANK_AuthenticationData *auth,
uint64_t start_row,
int64_t num_results,
struct GNUNET_TIME_Relative timeout,
TALER_BANK_DebitHistoryCallback hres_cb,
void *hres_cb_cls)
{
char url[128];
struct TALER_BANK_DebitHistoryHandle *hh;
CURL *eh;
unsigned long long tms;
if (0 == num_results)
{
@ -250,20 +234,43 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
return NULL;
}
tms = (unsigned long long) (timeout.rel_value_us
/ GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us);
if ( ( (UINT64_MAX == start_row) &&
(0 > num_results) ) ||
( (0 == start_row) &&
(0 < num_results) ) )
{
if ( (0 < num_results) &&
(! GNUNET_TIME_relative_is_zero (timeout)) )
GNUNET_snprintf (url,
sizeof (url),
"history/outgoing?delta=%lld&long_poll_ms=%llu",
(long long) num_results,
tms);
else
GNUNET_snprintf (url,
sizeof (url),
"history/outgoing?delta=%lld",
(long long) num_results);
}
else
{
if ( (0 < num_results) &&
(! GNUNET_TIME_relative_is_zero (timeout)) )
GNUNET_snprintf (url,
sizeof (url),
"history/outgoing?delta=%lld&start=%llu&long_poll_ms=%llu",
(long long) num_results,
(unsigned long long) start_row,
tms);
else
GNUNET_snprintf (url,
sizeof (url),
"history/outgoing?delta=%lld&start=%llu",
(long long) num_results,
(unsigned long long) start_row);
}
hh = GNUNET_new (struct TALER_BANK_DebitHistoryHandle);
hh->hcb = hres_cb;
hh->hcb_cls = hres_cb_cls;
@ -295,6 +302,13 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
curl_easy_cleanup (eh);
return NULL;
}
if (0 != tms)
{
GNUNET_break (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_TIMEOUT_MS,
(long) tms));
}
hh->job = GNUNET_CURL_job_add2 (ctx,
eh,
NULL,
@ -304,13 +318,6 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
}
/**
* Cancel a history request. This function cannot be
* used on a request handle if a response is already
* served for it.
*
* @param hh the history request handle
*/
void
TALER_BANK_debit_history_cancel (struct TALER_BANK_DebitHistoryHandle *hh)
{

View File

@ -321,11 +321,6 @@ struct TALER_FAKEBANK_Handle
*/
uint16_t port;
/**
* Force closing connections after each request.
*/
bool force_close;
#if EPOLL_SUPPORT
/**
* Boxed @e mhd_fd.
@ -1968,8 +1963,7 @@ TALER_FAKEBANK_start (uint16_t port,
return TALER_FAKEBANK_start2 (port,
currency,
65536, /* RAM limit */
1, /* number of threads */
false);
1);
}
@ -1977,8 +1971,7 @@ struct TALER_FAKEBANK_Handle *
TALER_FAKEBANK_start2 (uint16_t port,
const char *currency,
uint64_t ram_limit,
unsigned int num_threads,
bool close_connections)
unsigned int num_threads)
{
struct TALER_FAKEBANK_Handle *h;
@ -1992,7 +1985,6 @@ TALER_FAKEBANK_start2 (uint16_t port,
GNUNET_assert (strlen (currency) < TALER_CURRENCY_LEN);
h = GNUNET_new (struct TALER_FAKEBANK_Handle);
h->port = port;
h->force_close = close_connections;
h->ram_limit = ram_limit;
h->serial_counter = 0;
GNUNET_assert (0 ==

View File

@ -215,18 +215,18 @@ credit_history_cb (void *cls,
/* If credit/debit accounts were specified, use as a filter */
if ( (NULL != credit_account) &&
(0 != strcasecmp (credit_account,
details->credit_account_url) ) )
details->credit_account_uri) ) )
return GNUNET_OK;
if ( (NULL != debit_account) &&
(0 != strcasecmp (debit_account,
details->debit_account_url) ) )
details->debit_account_uri) ) )
return GNUNET_OK;
fprintf (stdout,
"%llu: %s->%s (%s) over %s at %s\n",
(unsigned long long) serial_id,
details->debit_account_url,
details->credit_account_url,
details->debit_account_uri,
details->credit_account_uri,
TALER_B2S (&details->reserve_pub),
TALER_amount2s (&details->amount),
GNUNET_STRINGS_absolute_time_to_string (details->execution_date));
@ -252,6 +252,7 @@ execute_credit_history (void)
&auth,
start_row,
-10,
GNUNET_TIME_UNIT_ZERO,
&credit_history_cb,
NULL);
if (NULL == chh)
@ -329,18 +330,18 @@ debit_history_cb (void *cls,
/* If credit/debit accounts were specified, use as a filter */
if ( (NULL != credit_account) &&
(0 != strcasecmp (credit_account,
details->credit_account_url) ) )
details->credit_account_uri) ) )
return GNUNET_OK;
if ( (NULL != debit_account) &&
(0 != strcasecmp (debit_account,
details->debit_account_url) ) )
details->debit_account_uri) ) )
return GNUNET_OK;
fprintf (stdout,
"%llu: %s->%s (%s) over %s at %s\n",
(unsigned long long) serial_id,
details->debit_account_url,
details->credit_account_url,
details->debit_account_uri,
details->credit_account_uri,
TALER_B2S (&details->wtid),
TALER_amount2s (&details->amount),
GNUNET_STRINGS_absolute_time_to_string (details->execution_date));
@ -366,6 +367,7 @@ execute_debit_history (void)
&auth,
start_row,
-10,
GNUNET_TIME_UNIT_ZERO,
&debit_history_cb,
NULL);
if (NULL == dhh)

View File

@ -23,9 +23,9 @@
* @author Marcello Stanisci
* @author Christian Grothoff
*/
#include "platform.h"
#include "taler_fakebank_lib.h"
#include "taler_mhd_lib.h"
/**
* Number of threads to use (-n)
@ -111,11 +111,18 @@ run (void *cls,
"Maximum transaction history in RAM set to default of %llu\n",
ram);
}
{
enum TALER_MHD_GlobalOptions go;
go = TALER_MHD_GO_NONE;
if (0 != connection_close)
go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
TALER_MHD_setup (go);
}
fb = TALER_FAKEBANK_start2 ((uint16_t) port,
currency_string,
ram,
num_threads,
(0 != connection_close));
num_threads);
if (NULL == fb)
{
ret = EXIT_FAILURE;

View File

@ -443,8 +443,7 @@ launch_fakebank (void *cls)
= TALER_FAKEBANK_start2 ((uint16_t) pnum,
currency,
history_size,
howmany_threads,
false);
howmany_threads);
if (NULL == fakebank)
{
GNUNET_break (0);

View File

@ -30,6 +30,12 @@
#include "taler_bank_service.h"
/**
* How long to wait for an HTTP reply if there
* are no transactions pending at the server?
*/
#define LONGPOLL_TIMEOUT GNUNET_TIME_UNIT_MINUTES
/**
* What is the maximum batch size we use for credit history
* requests with the bank. See `batch_size` below.
@ -545,7 +551,7 @@ history_cb (void *cls,
&details->reserve_pub,
&details->amount,
details->execution_date,
details->debit_account_url,
details->debit_account_uri,
wa->ai->section_name,
serial_id);
switch (qs)
@ -674,6 +680,9 @@ find_transfers (void *cls)
wa_pos->ai->auth,
wa_pos->batch_start,
limit,
test_mode
? GNUNET_TIME_UNIT_ZERO
: LONGPOLL_TIMEOUT,
&history_cb,
wa_pos);
if (NULL == wa_pos->hh)

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2015-2020 Taler Systems SA
Copyright (C) 2015-2021 Taler Systems SA
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
@ -278,13 +278,13 @@ struct TALER_BANK_CreditDetails
* payto://-URL of the source account that
* send the funds.
*/
const char *debit_account_url;
const char *debit_account_uri;
/**
* payto://-URL of the target account that
* received the funds.
*/
const char *credit_account_url;
const char *credit_account_uri;
};
@ -323,6 +323,8 @@ typedef enum GNUNET_GenericReturnValue
* @param num_results how many results do we want; negative numbers to go into the past,
* positive numbers to go into the future starting at @a start_row;
* must not be zero.
* @param timeout how long the client is willing to wait for more results
* (only useful if @a num_results is positive)
* @param hres_cb the callback to call with the transaction history
* @param hres_cb_cls closure for the above callback
* @return NULL
@ -334,6 +336,7 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx,
const struct TALER_BANK_AuthenticationData *auth,
uint64_t start_row,
int64_t num_results,
struct GNUNET_TIME_Relative timeout,
TALER_BANK_CreditHistoryCallback hres_cb,
void *hres_cb_cls);
@ -387,13 +390,13 @@ struct TALER_BANK_DebitDetails
* payto://-URI of the source account that
* send the funds.
*/
const char *debit_account_url; // FIXME: rename: url->uri
const char *debit_account_uri;
/**
* payto://-URI of the target account that
* received the funds.
*/
const char *credit_account_url; // FIXME: rename: url->uri
const char *credit_account_uri;
};
@ -433,6 +436,8 @@ typedef enum GNUNET_GenericReturnValue
* @param num_results how many results do we want; negative numbers to go into the past,
* positive numbers to go into the future starting at @a start_row;
* must not be zero.
* @param timeout how long the client is willing to wait for more results
* (only useful if @a num_results is positive)
* @param hres_cb the callback to call with the transaction history
* @param hres_cb_cls closure for the above callback
* @return NULL
@ -444,6 +449,7 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
const struct TALER_BANK_AuthenticationData *auth,
uint64_t start_row,
int64_t num_results,
struct GNUNET_TIME_Relative timeout,
TALER_BANK_DebitHistoryCallback hres_cb,
void *hres_cb_cls);

View File

@ -66,15 +66,13 @@ TALER_FAKEBANK_start (uint16_t port,
* @param currency which currency should the bank offer
* @param ram_limit how much memory do we use at most
* @param num_threads size of the thread pool, 0 to use the GNUnet scheduler
* @param close_connections true to force closing a connection after each request (no HTTP keep-alive)
* @return NULL on error
*/
struct TALER_FAKEBANK_Handle *
TALER_FAKEBANK_start2 (uint16_t port,
const char *currency,
uint64_t ram_limit,
unsigned int num_threads,
bool close_connections);
unsigned int num_threads);
/**

View File

@ -164,7 +164,7 @@ print_expected (struct History *h,
TALER_amount2s (&h[i].details.amount),
(unsigned long long) h[i].row_id,
TALER_B2S (&h[i].details.reserve_pub),
h[i].details.debit_account_url);
h[i].details.debit_account_uri);
}
}
@ -313,11 +313,11 @@ build_history (struct TALER_TESTING_Interpreter *is,
total,
pos * 2);
h[pos].url = GNUNET_strdup (debit_account);
h[pos].details.debit_account_url = h[pos].url;
h[pos].details.debit_account_uri = h[pos].url;
h[pos].details.amount = *amount;
h[pos].row_id = *row_id;
h[pos].details.reserve_pub = *reserve_pub;
h[pos].details.credit_account_url = exchange_credit_url;
h[pos].details.credit_account_uri = exchange_credit_url;
pos++;
}
GNUNET_assert (GNUNET_YES == ok);
@ -364,16 +364,16 @@ check_result (struct History *h,
&details->reserve_pub)) ||
(0 != TALER_amount_cmp (&h[off].details.amount,
&details->amount)) ||
(0 != strcasecmp (h[off].details.debit_account_url,
details->debit_account_url)) )
(0 != strcasecmp (h[off].details.debit_account_uri,
details->debit_account_uri)) )
{
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"expected debit_account_url: %s\n",
details->debit_account_url);
"expected debit_account_uri: %s\n",
details->debit_account_uri);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"actual debit_account_url: %s\n",
h[off].details.debit_account_url);
"actual debit_account_uri: %s\n",
h[off].details.debit_account_uri);
print_expected (h,
total,
off);
@ -521,6 +521,7 @@ history_run (void *cls,
&hs->auth,
row_id,
hs->num_results,
GNUNET_TIME_UNIT_ZERO,
&history_cb,
is);
GNUNET_assert (NULL != hs->hh);
@ -554,21 +555,10 @@ history_cleanup (void *cls,
}
/**
* Make a "history" CMD.
*
* @param label command label.
* @param auth authentication data to talk with the wire gateway
* @param start_row_reference reference to a command that can
* offer a row identifier, to be used as the starting row
* to accept in the result.
* @param num_results how many rows we want in the result.
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_bank_credits (const char *label,
const struct
TALER_BANK_AuthenticationData *auth,
TALER_TESTING_cmd_bank_credits (
const char *label,
const struct TALER_BANK_AuthenticationData *auth,
const char *start_row_reference,
long long num_results)
{

View File

@ -167,7 +167,7 @@ print_expected (struct History *h,
TALER_amount2s (&h[i].details.amount),
(unsigned long long) h[i].row_id,
TALER_B2S (&h[i].details.wtid),
h[i].details.credit_account_url);
h[i].details.credit_account_uri);
}
}
@ -320,8 +320,8 @@ build_history (struct TALER_TESTING_Interpreter *is,
pos * 2);
h[pos].c_url = GNUNET_strdup (credit_account);
h[pos].d_url = GNUNET_strdup (debit_account);
h[pos].details.credit_account_url = h[pos].c_url;
h[pos].details.debit_account_url = h[pos].d_url;
h[pos].details.credit_account_uri = h[pos].c_url;
h[pos].details.debit_account_uri = h[pos].d_url;
h[pos].details.amount = *amount;
h[pos].row_id = *row_id;
h[pos].details.wtid = *wtid;
@ -372,8 +372,8 @@ check_result (struct History *h,
&details->wtid)) ||
(0 != TALER_amount_cmp (&h[off].details.amount,
&details->amount)) ||
(0 != strcasecmp (h[off].details.credit_account_url,
details->credit_account_url)) )
(0 != strcasecmp (h[off].details.credit_account_uri,
details->credit_account_uri)) )
{
GNUNET_break (0);
print_expected (h,
@ -522,6 +522,7 @@ history_run (void *cls,
&hs->auth,
row_id,
hs->num_results,
GNUNET_TIME_UNIT_ZERO,
&history_cb,
is);
GNUNET_assert (NULL != hs->hh);