diff --git a/contrib/gana b/contrib/gana
index 59de2acb7..bf43b20a0 160000
--- a/contrib/gana
+++ b/contrib/gana
@@ -1 +1 @@
-Subproject commit 59de2acb7c716c816ed15786b5369e56c325770c
+Subproject commit bf43b20a0362ac19bcf1bab9c33215e55d8d9f36
diff --git a/contrib/microhttpd.tag b/contrib/microhttpd.tag
index d80405036..5156a1a3a 100644
--- a/contrib/microhttpd.tag
+++ b/contrib/microhttpd.tag
@@ -46,6 +46,12 @@
microhttpd.h
+
+ #define
+ MHD_HTTP_CONTENT_TOO_LARGE
+ microhttpd.h
+
+
#define
MHD_HTTP_REQUEST_TIMEOUT
diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c
index 76e4db70a..60492e50f 100644
--- a/src/bank-lib/fakebank.c
+++ b/src/bank-lib/fakebank.c
@@ -400,6 +400,148 @@ struct Transaction
};
+/**
+ * Function called to clean up context of a connection.
+ *
+ * @param ctx context to clean up
+ */
+typedef void
+(*ConnectionCleaner)(void *ctx);
+
+/**
+ * Universal context we keep per connection.
+ */
+struct ConnectionContext
+{
+ /**
+ * Function we call upon completion to clean up.
+ */
+ ConnectionCleaner ctx_cleaner;
+
+ /**
+ * Request-handler specific context.
+ */
+ void *ctx;
+};
+
+
+/**
+ * This is the "base" structure for both the /history and the
+ * /history-range API calls.
+ */
+struct HistoryArgs
+{
+
+ /**
+ * Bank account number of the requesting client.
+ */
+ uint64_t account_number;
+
+ /**
+ * Index of the starting transaction, exclusive (!).
+ */
+ uint64_t start_idx;
+
+ /**
+ * Requested number of results and order
+ * (positive: ascending, negative: descending)
+ */
+ int64_t delta;
+
+ /**
+ * Timeout for long polling.
+ */
+ struct GNUNET_TIME_Relative lp_timeout;
+
+ /**
+ * true if starting point was given.
+ */
+ bool have_start;
+
+};
+
+
+/**
+ * Context we keep per history request.
+ */
+struct HistoryContext
+{
+ /**
+ * When does this request time out.
+ */
+ struct GNUNET_TIME_Absolute timeout;
+
+ /**
+ * Client arguments for this request.
+ */
+ struct HistoryArgs ha;
+
+ /**
+ * Account the request is about.
+ */
+ struct Account *acc;
+
+ /**
+ * Payto URI of the account.
+ */
+ char *payto_uri;
+
+ /**
+ * JSON object we are building to return.
+ */
+ json_t *history;
+
+};
+
+
+/**
+ * Function called to clean up a history context.
+ *
+ * @param cls a `struct HistoryContext *`
+ */
+static void
+history_cleanup (void *cls)
+{
+ struct HistoryContext *hc = cls;
+
+ GNUNET_free (hc->payto_uri);
+ json_decref (hc->history);
+ GNUNET_free (hc);
+}
+
+
+/**
+ * Context we keep per get withdrawal operation request.
+ */
+struct WithdrawContext
+{
+ /**
+ * When does this request time out.
+ */
+ struct GNUNET_TIME_Absolute timeout;
+
+ /**
+ * The withdrawal operation this is about.
+ */
+ struct WithdrawalOperation *wo;
+
+};
+
+
+/**
+ * Function called to clean up a withdraw context.
+ *
+ * @param cls a `struct WithdrawContext *`
+ */
+static void
+withdraw_cleanup (void *cls)
+{
+ struct WithdrawContext *wc = cls;
+
+ GNUNET_free (wc);
+}
+
+
/**
* Handle for the fake bank.
*/
@@ -569,13 +711,6 @@ struct TALER_FAKEBANK_Handle
};
-/**
- * Special address "con_cls" can point to to indicate that the handler has
- * been called more than once already (was previously suspended).
- */
-static int special_ptr;
-
-
/**
* Task run whenever HTTP server operations are pending.
*
@@ -1583,15 +1718,14 @@ handle_mhd_completion_callback (void *cls,
enum MHD_RequestTerminationCode toe)
{
/* struct TALER_FAKEBANK_Handle *h = cls; */
+ struct ConnectionContext *cc = *con_cls;
(void) cls;
(void) connection;
(void) toe;
- if (NULL == *con_cls)
+ if (NULL == cc)
return;
- if (&special_ptr == *con_cls)
- return;
- GNUNET_JSON_post_parser_cleanup (*con_cls);
- *con_cls = NULL;
+ cc->ctx_cleaner (cc->ctx);
+ GNUNET_free (cc);
}
@@ -1603,7 +1737,7 @@ handle_mhd_completion_callback (void *cls,
* @param account account into which to deposit the funds (credit)
* @param upload_data request data
* @param upload_data_size size of @a upload_data in bytes
- * @param con_cls closure for request (a `struct Buffer *`)
+ * @param con_cls closure for request (a `struct ConnectionContext *`)
* @return MHD result code
*/
static MHD_RESULT
@@ -1614,14 +1748,21 @@ handle_admin_add_incoming (struct TALER_FAKEBANK_Handle *h,
size_t *upload_data_size,
void **con_cls)
{
+ struct ConnectionContext *cc = *con_cls;
enum GNUNET_JSON_PostResult pr;
json_t *json;
uint64_t row_id;
struct GNUNET_TIME_Timestamp timestamp;
+ if (NULL == cc)
+ {
+ cc = GNUNET_new (struct ConnectionContext);
+ cc->ctx_cleaner = &GNUNET_JSON_post_parser_cleanup;
+ *con_cls = cc;
+ }
pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
connection,
- con_cls,
+ &cc->ctx,
upload_data,
upload_data_size,
&json);
@@ -1736,7 +1877,7 @@ handle_admin_add_incoming (struct TALER_FAKEBANK_Handle *h,
* @param account account making the transfer
* @param upload_data request data
* @param upload_data_size size of @a upload_data in bytes
- * @param con_cls closure for request (a `struct Buffer *`)
+ * @param con_cls closure for request (a `struct ConnectionContext *`)
* @return MHD result code
*/
static MHD_RESULT
@@ -1747,14 +1888,21 @@ handle_transfer (struct TALER_FAKEBANK_Handle *h,
size_t *upload_data_size,
void **con_cls)
{
+ struct ConnectionContext *cc = *con_cls;
enum GNUNET_JSON_PostResult pr;
json_t *json;
uint64_t row_id;
struct GNUNET_TIME_Timestamp ts;
+ if (NULL == cc)
+ {
+ cc = GNUNET_new (struct ConnectionContext);
+ cc->ctx_cleaner = &GNUNET_JSON_post_parser_cleanup;
+ *con_cls = cc;
+ }
pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
connection,
- con_cls,
+ &cc->ctx,
upload_data,
upload_data_size,
&json);
@@ -1895,42 +2043,6 @@ handle_home_page (struct TALER_FAKEBANK_Handle *h,
}
-/**
- * This is the "base" structure for both the /history and the
- * /history-range API calls.
- */
-struct HistoryArgs
-{
-
- /**
- * Bank account number of the requesting client.
- */
- uint64_t account_number;
-
- /**
- * Index of the starting transaction, exclusive (!).
- */
- uint64_t start_idx;
-
- /**
- * Requested number of results and order
- * (positive: ascending, negative: descending)
- */
- int64_t delta;
-
- /**
- * Timeout for long polling.
- */
- struct GNUNET_TIME_Relative lp_timeout;
-
- /**
- * true if starting point was given.
- */
- bool have_start;
-
-};
-
-
/**
* Parse URL history arguments, of _both_ APIs:
* /history/incoming and /history/outgoing.
@@ -2176,7 +2288,7 @@ start_lp (struct TALER_FAKEBANK_Handle *h,
* @param h the fakebank handle
* @param connection the connection
* @param account which account the request is about
- * @param con_cls closure for request (NULL or &special_ptr)
+ * @param con_cls closure for request
*/
static MHD_RESULT
handle_debit_history (struct TALER_FAKEBANK_Handle *h,
@@ -2184,87 +2296,106 @@ handle_debit_history (struct TALER_FAKEBANK_Handle *h,
const char *account,
void **con_cls)
{
- struct HistoryArgs ha;
- struct Account *acc;
+ struct ConnectionContext *cc = *con_cls;
+ struct HistoryContext *hc;
struct Transaction *pos;
- json_t *history;
- char *debit_payto;
enum GNUNET_GenericReturnValue ret;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Handling /history/outgoing connection %p\n",
- connection);
- if (GNUNET_OK !=
- (ret = parse_history_common_args (h,
- connection,
- &ha)))
+ if (NULL == cc)
{
- GNUNET_break_op (0);
- return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES;
- }
- if (&special_ptr == *con_cls)
- ha.lp_timeout = GNUNET_TIME_UNIT_ZERO;
- acc = lookup_account (h,
- account,
- NULL);
- if (NULL == acc)
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_BANK_UNKNOWN_ACCOUNT,
- account);
- }
- GNUNET_asprintf (&debit_payto,
- "payto://x-taler-bank/localhost/%s?receiver-name=%s",
- account,
- acc->receiver_name);
- history = json_array ();
- if (NULL == history)
- {
- GNUNET_break (0);
- GNUNET_free (debit_payto);
- return MHD_NO;
- }
- GNUNET_assert (0 ==
- pthread_mutex_lock (&h->big_lock));
- if (! ha.have_start)
- {
- pos = (0 > ha.delta)
- ? acc->out_tail
- : acc->out_head;
+ cc = GNUNET_new (struct ConnectionContext);
+ cc->ctx_cleaner = &history_cleanup;
+ *con_cls = cc;
+ hc = GNUNET_new (struct HistoryContext);
+ cc->ctx = hc;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Handling /history/outgoing connection %p\n",
+ connection);
+ if (GNUNET_OK !=
+ (ret = parse_history_common_args (h,
+ connection,
+ &hc->ha)))
+ {
+ GNUNET_break_op (0);
+ return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES;
+ }
+ GNUNET_assert (0 ==
+ pthread_mutex_lock (&h->big_lock));
+ hc->acc = lookup_account (h,
+ account,
+ NULL);
+ if (NULL == hc->acc)
+ {
+ GNUNET_assert (0 ==
+ pthread_mutex_unlock (&h->big_lock));
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_BANK_UNKNOWN_ACCOUNT,
+ account);
+ }
+ GNUNET_asprintf (&hc->payto_uri,
+ "payto://x-taler-bank/localhost/%s?receiver-name=%s",
+ account,
+ hc->acc->receiver_name);
+ /* New invariant: */
+ GNUNET_assert (0 == strcmp (hc->payto_uri,
+ hc->acc->payto_uri));
+ hc->history = json_array ();
+ if (NULL == hc->history)
+ {
+ GNUNET_break (0);
+ GNUNET_assert (0 ==
+ pthread_mutex_unlock (&h->big_lock));
+ return MHD_NO;
+ }
+ hc->timeout = GNUNET_TIME_relative_to_absolute (hc->ha.lp_timeout);
}
else
{
- struct Transaction *t = h->transactions[ha.start_idx % h->ram_limit];
+ hc = cc->ctx;
+ GNUNET_assert (0 ==
+ pthread_mutex_lock (&h->big_lock));
+ }
+
+ if (! hc->ha.have_start)
+ {
+ pos = (0 > hc->ha.delta)
+ ? hc->acc->out_tail
+ : hc->acc->out_head;
+ }
+ else
+ {
+ struct Transaction *t = h->transactions[hc->ha.start_idx % h->ram_limit];
bool overflow;
uint64_t dir;
bool skip = true;
- dir = (0 > ha.delta) ? (h->ram_limit - 1) : 1;
- overflow = (t->row_id != ha.start_idx);
+ dir = (0 > hc->ha.delta) ? (h->ram_limit - 1) : 1;
+ overflow = (t->row_id != hc->ha.start_idx);
/* If account does not match, linear scan for
first matching account. */
while ( (! overflow) &&
- (NULL != t) &&
- (t->debit_account != acc) )
+ (NULL != t) &&
+ (t->debit_account != hc->acc) )
{
skip = false;
t = h->transactions[(t->row_id + dir) % h->ram_limit];
if ( (NULL != t) &&
- (t->row_id == ha.start_idx) )
+ (t->row_id == hc->ha.start_idx) )
overflow = true; /* full circle, give up! */
}
if ( (NULL == t) ||
overflow)
{
- if (GNUNET_TIME_relative_is_zero (ha.lp_timeout) &&
- (0 < ha.delta))
+ /* FIXME: these conditions are unclear to me. */
+ if ( (GNUNET_TIME_relative_is_zero (hc->ha.lp_timeout)) &&
+ (0 < hc->ha.delta))
{
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
if (overflow)
{
- GNUNET_free (debit_payto);
return TALER_MHD_reply_with_ec (
connection,
TALER_EC_BANK_ANCIENT_TRANSACTION_GONE,
@@ -2272,35 +2403,36 @@ handle_debit_history (struct TALER_FAKEBANK_Handle *h,
}
goto finish;
}
- *con_cls = &special_ptr;
+ if (h->in_shutdown)
+ {
+ GNUNET_assert (0 ==
+ pthread_mutex_unlock (&h->big_lock));
+ goto finish;
+ }
start_lp (h,
connection,
- acc,
- ha.lp_timeout,
+ hc->acc,
+ GNUNET_TIME_absolute_get_remaining (hc->timeout),
LP_DEBIT,
NULL);
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
- json_decref (history);
- GNUNET_free (debit_payto);
return MHD_YES;
}
- if (t->debit_account != acc)
+ if (t->debit_account != hc->acc)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid start specified, transaction %llu not with account %s!\n",
- (unsigned long long) ha.start_idx,
+ (unsigned long long) hc->ha.start_idx,
account);
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
- GNUNET_free (debit_payto);
- json_decref (history);
return MHD_NO;
}
if (skip)
{
/* range is exclusive, skip the matching entry */
- if (0 > ha.delta)
+ if (0 > hc->ha.delta)
pos = t->prev_out;
else
pos = t->next_out;
@@ -2313,9 +2445,9 @@ handle_debit_history (struct TALER_FAKEBANK_Handle *h,
if (NULL != pos)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Returning %lld debit transactions starting (inclusive) from %llu\n",
- (long long) ha.delta,
+ (long long) hc->ha.delta,
(unsigned long long) pos->row_id);
- while ( (0 != ha.delta) &&
+ while ( (0 != hc->ha.delta) &&
(NULL != pos) )
{
json_t *trans;
@@ -2327,9 +2459,9 @@ handle_debit_history (struct TALER_FAKEBANK_Handle *h,
"Unexpected CREDIT transaction #%llu for account `%s'\n",
(unsigned long long) pos->row_id,
account);
- if (0 > ha.delta)
+ if (0 > hc->ha.delta)
pos = pos->prev_in;
- if (0 < ha.delta)
+ if (0 < hc->ha.delta)
pos = pos->next_in;
continue;
}
@@ -2348,7 +2480,7 @@ handle_debit_history (struct TALER_FAKEBANK_Handle *h,
GNUNET_JSON_pack_string ("credit_account",
credit_payto),
GNUNET_JSON_pack_string ("debit_account",
- debit_payto), // FIXME #7275: inefficient to return this here always!
+ hc->payto_uri), // FIXME #7275: inefficient to return this here always!
GNUNET_JSON_pack_string ("exchange_base_url",
pos->subject.debit.exchange_base_url),
GNUNET_JSON_pack_data_auto ("wtid",
@@ -2356,51 +2488,55 @@ handle_debit_history (struct TALER_FAKEBANK_Handle *h,
GNUNET_assert (NULL != trans);
GNUNET_free (credit_payto);
GNUNET_assert (0 ==
- json_array_append_new (history,
+ json_array_append_new (hc->history,
trans));
- if (ha.delta > 0)
- ha.delta--;
+ if (hc->ha.delta > 0)
+ hc->ha.delta--;
else
- ha.delta++;
- if (0 > ha.delta)
+ hc->ha.delta++;
+ if (0 > hc->ha.delta)
pos = pos->prev_out;
- if (0 < ha.delta)
+ if (0 < hc->ha.delta)
pos = pos->next_out;
}
- if ( (0 == json_array_size (history)) &&
- (! GNUNET_TIME_relative_is_zero (ha.lp_timeout)) &&
- (0 < ha.delta))
+ if ( (0 == json_array_size (hc->history)) &&
+ (! h->in_shutdown) &&
+ (GNUNET_TIME_absolute_is_future (hc->timeout)) &&
+ (0 < hc->ha.delta))
{
- *con_cls = &special_ptr;
start_lp (h,
connection,
- acc,
- ha.lp_timeout,
+ hc->acc,
+ GNUNET_TIME_absolute_get_remaining (hc->timeout),
LP_DEBIT,
NULL);
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
- json_decref (history);
return MHD_YES;
}
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
finish:
- if (0 == json_array_size (history))
+ if (0 == json_array_size (hc->history))
{
- json_decref (history);
+ GNUNET_break (h->in_shutdown ||
+ (! GNUNET_TIME_absolute_is_future (hc->timeout)));
return TALER_MHD_reply_static (connection,
MHD_HTTP_NO_CONTENT,
NULL,
NULL,
0);
}
- GNUNET_free (debit_payto);
- return TALER_MHD_REPLY_JSON_PACK (connection,
- MHD_HTTP_OK,
- GNUNET_JSON_pack_array_steal (
- "outgoing_transactions",
- history));
+ {
+ json_t *h = hc->history;
+
+ hc->history = NULL;
+ return TALER_MHD_REPLY_JSON_PACK (connection,
+ MHD_HTTP_OK,
+ GNUNET_JSON_pack_array_steal (
+ "outgoing_transactions",
+ h));
+ }
}
@@ -2419,77 +2555,101 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h,
const char *account,
void **con_cls)
{
- struct HistoryArgs ha;
- struct Account *acc;
+ struct ConnectionContext *cc = *con_cls;
+ struct HistoryContext *hc;
const struct Transaction *pos;
- json_t *history;
- const char *credit_payto;
enum GNUNET_GenericReturnValue ret;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Handling /history/incoming connection %p (%d)\n",
- connection,
- (*con_cls == &special_ptr));
- if (GNUNET_OK !=
- (ret = parse_history_common_args (h,
- connection,
- &ha)))
+ if (NULL == cc)
{
- GNUNET_break_op (0);
- return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES;
- }
- if (&special_ptr == *con_cls)
- ha.lp_timeout = GNUNET_TIME_UNIT_ZERO;
- *con_cls = &special_ptr;
- acc = lookup_account (h,
- account,
- NULL);
- if (NULL == acc)
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_BANK_UNKNOWN_ACCOUNT,
- account);
- }
- history = json_array ();
- GNUNET_assert (NULL != history);
- credit_payto = acc->payto_uri;
- GNUNET_assert (0 ==
- pthread_mutex_lock (&h->big_lock));
- if (! ha.have_start)
- {
- pos = (0 > ha.delta)
- ? acc->in_tail
- : acc->in_head;
+ cc = GNUNET_new (struct ConnectionContext);
+ cc->ctx_cleaner = &history_cleanup;
+ *con_cls = cc;
+ hc = GNUNET_new (struct HistoryContext);
+ cc->ctx = hc;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Handling /history/incoming connection %p\n",
+ connection);
+ if (GNUNET_OK !=
+ (ret = parse_history_common_args (h,
+ connection,
+ &hc->ha)))
+ {
+ GNUNET_break_op (0);
+ return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES;
+ }
+ GNUNET_assert (0 ==
+ pthread_mutex_lock (&h->big_lock));
+ hc->acc = lookup_account (h,
+ account,
+ NULL);
+ if (NULL == hc->acc)
+ {
+ GNUNET_assert (0 ==
+ pthread_mutex_unlock (&h->big_lock));
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_BANK_UNKNOWN_ACCOUNT,
+ account);
+ }
+ /* FIXME: was simply: acc->payto_uri -- same!? */
+ GNUNET_asprintf (&hc->payto_uri,
+ "payto://x-taler-bank/localhost/%s?receiver-name=%s",
+ account,
+ hc->acc->receiver_name);
+ GNUNET_assert (0 == strcmp (hc->payto_uri,
+ hc->acc->payto_uri));
+ hc->history = json_array ();
+ if (NULL == hc->history)
+ {
+ GNUNET_break (0);
+ GNUNET_assert (0 ==
+ pthread_mutex_unlock (&h->big_lock));
+ return MHD_NO;
+ }
+ hc->timeout = GNUNET_TIME_relative_to_absolute (hc->ha.lp_timeout);
}
else
{
- struct Transaction *t = h->transactions[ha.start_idx % h->ram_limit];
+ hc = cc->ctx;
+ GNUNET_assert (0 ==
+ pthread_mutex_lock (&h->big_lock));
+ }
+
+ if (! hc->ha.have_start)
+ {
+ pos = (0 > hc->ha.delta)
+ ? hc->acc->in_tail
+ : hc->acc->in_head;
+ }
+ else
+ {
+ struct Transaction *t = h->transactions[hc->ha.start_idx % h->ram_limit];
bool overflow;
uint64_t dir;
bool skip = true;
- overflow = ( (NULL != t) && (t->row_id != ha.start_idx) );
- dir = (0 > ha.delta) ? (h->ram_limit - 1) : 1;
+ overflow = ( (NULL != t) && (t->row_id != hc->ha.start_idx) );
+ dir = (0 > hc->ha.delta) ? (h->ram_limit - 1) : 1;
/* If account does not match, linear scan for
first matching account. */
while ( (! overflow) &&
(NULL != t) &&
- (t->credit_account != acc) )
+ (t->credit_account != hc->acc) )
{
skip = false;
t = h->transactions[(t->row_id + dir) % h->ram_limit];
if ( (NULL != t) &&
- (t->row_id == ha.start_idx) )
+ (t->row_id == hc->ha.start_idx) )
overflow = true; /* full circle, give up! */
}
if ( (NULL == t) ||
overflow)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "No transactions available, suspending request\n");
- if (GNUNET_TIME_relative_is_zero (ha.lp_timeout) &&
- (0 < ha.delta))
+ /* FIXME: these conditions are unclear to me. */
+ if (GNUNET_TIME_relative_is_zero (hc->ha.lp_timeout) &&
+ (0 < hc->ha.delta))
{
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
@@ -2500,23 +2660,27 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h,
NULL);
goto finish;
}
- *con_cls = &special_ptr;
+ if (h->in_shutdown)
+ {
+ GNUNET_assert (0 ==
+ pthread_mutex_unlock (&h->big_lock));
+ goto finish;
+ }
start_lp (h,
connection,
- acc,
- ha.lp_timeout,
+ hc->acc,
+ GNUNET_TIME_absolute_get_remaining (hc->timeout),
LP_CREDIT,
NULL);
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
- json_decref (history);
return MHD_YES;
}
if (skip)
{
/* range from application is exclusive, skip the
matching entry */
- if (0 > ha.delta)
+ if (0 > hc->ha.delta)
pos = t->prev_in;
else
pos = t->next_in;
@@ -2529,9 +2693,9 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h,
if (NULL != pos)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Returning %lld credit transactions starting (inclusive) from %llu\n",
- (long long) ha.delta,
+ (long long) hc->ha.delta,
(unsigned long long) pos->row_id);
- while ( (0 != ha.delta) &&
+ while ( (0 != hc->ha.delta) &&
(NULL != pos) )
{
json_t *trans;
@@ -2542,9 +2706,9 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h,
"Unexpected DEBIT transaction #%llu for account `%s'\n",
(unsigned long long) pos->row_id,
account);
- if (0 > ha.delta)
+ if (0 > hc->ha.delta)
pos = pos->prev_in;
- if (0 < ha.delta)
+ if (0 < hc->ha.delta)
pos = pos->next_in;
continue;
}
@@ -2556,57 +2720,62 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h,
TALER_JSON_pack_amount ("amount",
&pos->amount),
GNUNET_JSON_pack_string ("credit_account",
- credit_payto), // FIXME #7275: inefficient to repeat this always here!
+ hc->payto_uri), // FIXME #7275: inefficient to repeat this always here!
GNUNET_JSON_pack_string ("debit_account",
pos->debit_account->payto_uri),
GNUNET_JSON_pack_data_auto ("reserve_pub",
&pos->subject.credit.reserve_pub));
GNUNET_assert (NULL != trans);
GNUNET_assert (0 ==
- json_array_append_new (history,
+ json_array_append_new (hc->history,
trans));
- if (ha.delta > 0)
- ha.delta--;
+ if (hc->ha.delta > 0)
+ hc->ha.delta--;
else
- ha.delta++;
- if (0 > ha.delta)
+ hc->ha.delta++;
+ if (0 > hc->ha.delta)
pos = pos->prev_in;
- if (0 < ha.delta)
+ if (0 < hc->ha.delta)
pos = pos->next_in;
}
- if ( (0 == json_array_size (history)) &&
- (! GNUNET_TIME_relative_is_zero (ha.lp_timeout)) &&
- (0 < ha.delta))
+ if ( (0 == json_array_size (hc->history)) &&
+ (! h->in_shutdown) &&
+ (GNUNET_TIME_absolute_is_future (hc->timeout)) &&
+ (0 < hc->ha.delta))
{
- *con_cls = &special_ptr;
start_lp (h,
connection,
- acc,
- ha.lp_timeout,
+ hc->acc,
+ GNUNET_TIME_absolute_get_remaining (hc->timeout),
LP_CREDIT,
NULL);
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
- json_decref (history);
return MHD_YES;
}
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
finish:
- if (0 == json_array_size (history))
+ if (0 == json_array_size (hc->history))
{
- json_decref (history);
+ GNUNET_break (h->in_shutdown ||
+ (! GNUNET_TIME_absolute_is_future (hc->timeout)));
return TALER_MHD_reply_static (connection,
MHD_HTTP_NO_CONTENT,
NULL,
NULL,
0);
}
- return TALER_MHD_REPLY_JSON_PACK (connection,
- MHD_HTTP_OK,
- GNUNET_JSON_pack_array_steal (
- "incoming_transactions",
- history));
+ {
+ json_t *h = hc->history;
+
+ hc->history = NULL;
+ return TALER_MHD_REPLY_JSON_PACK (connection,
+ MHD_HTTP_OK,
+ GNUNET_JSON_pack_array_steal (
+ "incoming_transactions",
+ h));
+ }
}
@@ -2711,25 +2880,39 @@ get_withdrawal_operation (struct TALER_FAKEBANK_Handle *h,
struct GNUNET_TIME_Relative lp,
void **con_cls)
{
- struct WithdrawalOperation *wo;
+ struct ConnectionContext *cc = *con_cls;
+ struct WithdrawContext *wc;
GNUNET_assert (0 ==
pthread_mutex_lock (&h->big_lock));
- wo = lookup_withdrawal_operation (h,
- wopid);
- if (NULL == wo)
+ if (NULL == cc)
{
- GNUNET_assert (0 ==
- pthread_mutex_unlock (&h->big_lock));
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_BANK_TRANSACTION_NOT_FOUND,
- wopid);
+ cc = GNUNET_new (struct ConnectionContext);
+ cc->ctx_cleaner = &withdraw_cleanup;
+ *con_cls = cc;
+ wc = GNUNET_new (struct WithdrawContext);
+ cc->ctx = wc;
+ wc->wo = lookup_withdrawal_operation (h,
+ wopid);
+ if (NULL == wc->wo)
+ {
+ GNUNET_assert (0 ==
+ pthread_mutex_unlock (&h->big_lock));
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_BANK_TRANSACTION_NOT_FOUND,
+ wopid);
+ }
+ wc->timeout = GNUNET_TIME_relative_to_absolute (lp);
}
- if ( (NULL != *con_cls) ||
- (GNUNET_TIME_relative_is_zero (lp)) ||
- wo->confirmation_done ||
- wo->aborted)
+ else
+ {
+ wc = cc->ctx;
+ }
+ if (GNUNET_TIME_absolute_is_past (wc->timeout) ||
+ h->in_shutdown ||
+ wc->wo->confirmation_done ||
+ wc->wo->aborted)
{
json_t *wt;
@@ -2744,27 +2927,26 @@ get_withdrawal_operation (struct TALER_FAKEBANK_Handle *h,
connection,
MHD_HTTP_OK,
GNUNET_JSON_pack_bool ("aborted",
- wo->aborted),
+ wc->wo->aborted),
GNUNET_JSON_pack_bool ("selection_done",
- wo->selection_done),
+ wc->wo->selection_done),
GNUNET_JSON_pack_bool ("transfer_done",
- wo->confirmation_done),
+ wc->wo->confirmation_done),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("suggested_exchange",
h->exchange_url)),
TALER_JSON_pack_amount ("amount",
- &wo->amount),
+ &wc->wo->amount),
GNUNET_JSON_pack_array_steal ("wire_types",
wt));
}
- *con_cls = &special_ptr;
start_lp (h,
connection,
- wo->debit_account,
- lp,
+ wc->wo->debit_account,
+ GNUNET_TIME_absolute_get_remaining (wc->timeout),
LP_WITHDRAW,
- wo);
+ wc->wo);
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
return MHD_YES;
@@ -2903,13 +3085,20 @@ post_withdrawal_operation (struct TALER_FAKEBANK_Handle *h,
size_t *upload_data_size,
void **con_cls)
{
+ struct ConnectionContext *cc = *con_cls;
enum GNUNET_JSON_PostResult pr;
json_t *json;
MHD_RESULT res;
+ if (NULL == cc)
+ {
+ cc = GNUNET_new (struct ConnectionContext);
+ cc->ctx_cleaner = &GNUNET_JSON_post_parser_cleanup;
+ *con_cls = cc;
+ }
pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
connection,
- con_cls,
+ &cc->ctx,
upload_data,
upload_data_size,
&json);
@@ -3294,13 +3483,20 @@ post_account_withdrawals_access (struct TALER_FAKEBANK_Handle *h,
size_t *upload_data_size,
void **con_cls)
{
+ struct ConnectionContext *cc = *con_cls;
enum GNUNET_JSON_PostResult pr;
json_t *json;
MHD_RESULT res;
+ if (NULL == cc)
+ {
+ cc = GNUNET_new (struct ConnectionContext);
+ cc->ctx_cleaner = &GNUNET_JSON_post_parser_cleanup;
+ *con_cls = cc;
+ }
pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
connection,
- con_cls,
+ &cc->ctx,
upload_data,
upload_data_size,
&json);
@@ -3367,13 +3563,20 @@ post_testing_register (struct TALER_FAKEBANK_Handle *h,
size_t *upload_data_size,
void **con_cls)
{
+ struct ConnectionContext *cc = *con_cls;
enum GNUNET_JSON_PostResult pr;
json_t *json;
MHD_RESULT res;
+ if (NULL == cc)
+ {
+ cc = GNUNET_new (struct ConnectionContext);
+ cc->ctx_cleaner = &GNUNET_JSON_post_parser_cleanup;
+ *con_cls = cc;
+ }
pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
connection,
- con_cls,
+ &cc->ctx,
upload_data,
upload_data_size,
&json);
diff --git a/src/benchmark/bank-benchmark-cs.conf b/src/benchmark/bank-benchmark-cs.conf
index d012f0faa..e32370f89 100644
--- a/src/benchmark/bank-benchmark-cs.conf
+++ b/src/benchmark/bank-benchmark-cs.conf
@@ -28,7 +28,7 @@ DB = postgres
# exchange (or the twister) is actually listening.
base_url = "http://localhost:8081/"
-WIREWATCH_IDLE_SLEEP_INTERVAL = 1500 ms
+WIREWATCH_IDLE_SLEEP_INTERVAL = 500 ms
[exchange-offline]
MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv
@@ -51,11 +51,11 @@ MAX_DEBT = EUR:100000000000.0
MAX_DEBT_BANK = EUR:1000000000000000.0
[benchmark]
-USER_PAYTO_URI = payto://x-taler-bank/localhost:8082/42
+USER_PAYTO_URI = payto://x-taler-bank/localhost:8082/42?receiver-name=user42
[exchange-account-2]
# What is the payto://-URL of the exchange (to generate wire response)
-PAYTO_URI = "payto://x-taler-bank/localhost:8082/Exchange"
+PAYTO_URI = "payto://x-taler-bank/localhost:8082/Exchange?receiver-name=Exchange"
enable_debit = YES
enable_credit = YES
diff --git a/src/benchmark/taler-bank-benchmark.c b/src/benchmark/taler-bank-benchmark.c
index b17bb9411..584df4896 100644
--- a/src/benchmark/taler-bank-benchmark.c
+++ b/src/benchmark/taler-bank-benchmark.c
@@ -689,6 +689,8 @@ parallel_benchmark (void)
}
/* But be extra sure we did finish all shards by doing one more */
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Shard check phase\n");
wirewatch[0] = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-exchange-wirewatch",
diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c
index 77ef94ebc..fd7553813 100644
--- a/src/benchmark/taler-exchange-benchmark.c
+++ b/src/benchmark/taler-exchange-benchmark.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2014-2020 Taler Systems SA
+ (C) 2014-2023 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
diff --git a/src/exchange/exchange.conf b/src/exchange/exchange.conf
index 750e71724..38e5816ff 100644
--- a/src/exchange/exchange.conf
+++ b/src/exchange/exchange.conf
@@ -19,7 +19,7 @@ MAX_KEYS_CACHING = forever
# After how many requests should the exchange auto-restart
# (to address potential issues with memory fragmentation)?
# If this option is not specified, auto-restarting is disabled.
-# MAX_REQUESTS = 10000000
+# MAX_REQUESTS = 100000
# How to access our database
DB = postgres
diff --git a/src/exchange/taler-exchange-httpd_age-withdraw.c b/src/exchange/taler-exchange-httpd_age-withdraw.c
index 170cd06a5..0978421a4 100644
--- a/src/exchange/taler-exchange-httpd_age-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_age-withdraw.c
@@ -222,7 +222,6 @@ age_withdraw_transaction (void *cls,
awc->kyc.ok = true;
qs = TEH_plugin->do_age_withdraw (TEH_plugin->cls,
&awc->commitment,
- awc->now,
&found,
&balance_ok,
&ruuid);
@@ -312,7 +311,7 @@ TEH_handler_age_withdraw (struct TEH_RequestContext *rc,
const json_t *root)
{
MHD_RESULT mhd_ret;
- struct AgeWithdrawContext awc;
+ struct AgeWithdrawContext awc = {0};
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
&awc.commitment.reserve_sig),
@@ -321,12 +320,11 @@ TEH_handler_age_withdraw (struct TEH_RequestContext *rc,
TALER_JSON_spec_amount ("amount",
TEH_currency,
&awc.commitment.amount_with_fee),
- GNUNET_JSON_spec_uint32 ("max_age",
+ GNUNET_JSON_spec_uint16 ("max_age",
&awc.commitment.max_age),
GNUNET_JSON_spec_end ()
};
- memset (&awc, 0, sizeof (awc));
awc.commitment.reserve_pub = *reserve_pub;
diff --git a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c
index 1bf87342f..a1ae3a6b0 100644
--- a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c
+++ b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c
@@ -347,6 +347,15 @@ find_original_commitment (
NULL);
break;
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ *result = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "get_age_withdraw_info");
+ break;
+
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ /* FIXME oec: Do we queue a result in this case or retry? */
default:
GNUNET_break (0);
*result = TALER_MHD_reply_with_error (connection,
@@ -616,7 +625,7 @@ verify_commitment_and_max_age (
{
size_t k = 0; /* either 0 or 1, to index into coin_evs */
- for (size_t idx = 0; idx<3; idx++)
+ for (size_t idx = 0; idx j);
+ GNUNET_assert ((TALER_CNC_KAPPA - 1) * num_coins > j);
secret = &disclosed_coin_secrets[j];
k++;
@@ -666,7 +676,6 @@ verify_commitment_and_max_age (
{
struct TALER_CoinPubHashP c_hash;
struct TALER_PlanchetDetail detail;
- struct TALER_BlindedCoinHashP bch;
struct TALER_CoinSpendPrivateKeyP coin_priv;
union TALER_DenominationBlindingKeyP bks;
struct TALER_ExchangeWithdrawValues alg_values = {
@@ -688,19 +697,12 @@ verify_commitment_and_max_age (
.nonce = &nonce,
};
- ec = TEH_keys_denomination_cs_r_pub (
- &cdd,
- false,
- &alg_values.details.cs_values);
-
- if (TALER_EC_NONE != ec)
- {
- GNUNET_break_op (0);
- *result = TALER_MHD_reply_with_ec (connection,
- ec,
- NULL);
- return GNUNET_SYSERR;
- }
+ ec = TEH_keys_denomination_cs_r_pub (&cdd,
+ false,
+ &alg_values.details.
+ cs_values);
+ /* FIXME Handle error? */
+ GNUNET_assert (TALER_EC_NONE == ec);
}
}
@@ -749,10 +751,13 @@ verify_commitment_and_max_age (
return ret;
}
- GNUNET_CRYPTO_hash_context_read (hash_context,
- &detail.blinded_planchet,
- sizeof(detail.blinded_planchet));
}
+
+ /* Continue the running hash of all coin hashes with the calculated
+ * hash-value of the current, disclosed coin */
+ GNUNET_CRYPTO_hash_context_read (hash_context,
+ &bch,
+ sizeof(bch));
}
}
}
@@ -780,61 +785,35 @@ verify_commitment_and_max_age (
/**
- * @brief Executes the database transaction for the withdraw of coins and signs
- * the blinded coins
+ * @brief Signs and persists the undisclosed coins
*
- * @param connection The HTTP-connection to the client
- * @param h_commitment_orig The commitment from the age-withdraw request
- * @param num_coins The number of coins (and also denominations)
- * @param coin_evs The blinded planchets of the coins
- * @param denom_keys The corresponding denominations
+ * @param connection HTTP-connection to the client
+ * @param h_commitment_orig Original commitment
+ * @param num_coins Number of coins
+ * @param coin_evs The Hashes of the undisclosed, blinded coins, @a num_coins many
+ * @param denom_keys The array of denomination keys, @a num_coins. Needed to detect Clause-Schnorr-based denominations
* @param[out] result On error, a HTTP-response will be queued and result set accordingly
* @return GNUNET_OK on success, GNUNET_SYSERR otherwise
*/
-enum GNUNET_GenericReturnValue
-finalize_withdraw_and_sign (
+static enum GNUNET_GenericReturnValue
+sign_and_persist_blinded_coins (
struct MHD_Connection *connection,
- const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
+ const struct TALER_AgeWithdrawCommitmentHashP *h_commitment_orig,
const uint32_t num_coins,
const struct TALER_BlindedPlanchet *coin_evs,
const struct TEH_DenominationKey *denom_keys,
MHD_RESULT *result)
{
enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
- struct TEH_CoinSignData csds[num_coins];
- struct TALER_BlindedDenominationSignature bss[num_coins];
-
- for (uint32_t i = 0; iconnection,
&actx.commitment.h_commitment,
actx.num_coins,
diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c b/src/exchange/taler-exchange-httpd_batch-withdraw.c
index 6cd467d51..c3065e1df 100644
--- a/src/exchange/taler-exchange-httpd_batch-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c
@@ -77,6 +77,11 @@ struct BatchWithdrawContext
*/
const struct TALER_ReservePublicKeyP *reserve_pub;
+ /**
+ * request context
+ */
+ const struct TEH_RequestContext *rc;
+
/**
* KYC status of the reserve used for the operation.
*/
@@ -183,6 +188,99 @@ aml_amount_cb (
}
+/**
+ * Generates our final (successful) response.
+ *
+ * @param rc request context
+ * @param wc operation context
+ * @return MHD queue status
+ */
+static MHD_RESULT
+generate_reply_success (const struct TEH_RequestContext *rc,
+ const struct BatchWithdrawContext *wc)
+{
+ json_t *sigs;
+
+ if (! wc->kyc.ok)
+ {
+ /* KYC required */
+ return TEH_RESPONSE_reply_kyc_required (rc->connection,
+ &wc->h_payto,
+ &wc->kyc);
+ }
+ if (TALER_AML_NORMAL != wc->aml_decision)
+ return TEH_RESPONSE_reply_aml_blocked (rc->connection,
+ wc->aml_decision);
+
+ sigs = json_array ();
+ GNUNET_assert (NULL != sigs);
+ for (unsigned int i = 0; iplanchets_length; i++)
+ {
+ struct PlanchetContext *pc = &wc->planchets[i];
+
+ GNUNET_assert (
+ 0 ==
+ json_array_append_new (
+ sigs,
+ GNUNET_JSON_PACK (
+ TALER_JSON_pack_blinded_denom_sig (
+ "ev_sig",
+ &pc->collectable.sig))));
+ }
+ TEH_METRICS_batch_withdraw_num_coins += wc->planchets_length;
+ return TALER_MHD_REPLY_JSON_PACK (
+ rc->connection,
+ MHD_HTTP_OK,
+ GNUNET_JSON_pack_array_steal ("ev_sigs",
+ sigs));
+}
+
+
+/**
+ * Check if the @a wc is replayed and we already have an
+ * answer. If so, replay the existing answer and return the
+ * HTTP response.
+ *
+ * @param wc parsed request data
+ * @param[out] mret HTTP status, set if we return true
+ * @return true if the request is idempotent with an existing request
+ * false if we did not find the request in the DB and did not set @a mret
+ */
+static bool
+check_request_idempotent (const struct BatchWithdrawContext *wc,
+ MHD_RESULT *mret)
+{
+ const struct TEH_RequestContext *rc = wc->rc;
+
+ for (unsigned int i = 0; iplanchets_length; i++)
+ {
+ struct PlanchetContext *pc = &wc->planchets[i];
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
+ &pc->h_coin_envelope,
+ &pc->collectable);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ *mret = TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "get_withdraw_info");
+ return true; /* well, kind-of */
+ }
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ return false;
+ }
+ /* generate idempotent reply */
+ TEH_METRICS_num_requests[TEH_MT_REQUEST_IDEMPOTENT_BATCH_WITHDRAW]++;
+ *mret = generate_reply_success (rc,
+ wc);
+ return true;
+}
+
+
/**
* Function implementing withdraw transaction. Runs the
* transaction logic; IF it returns a non-error code, the transaction
@@ -448,12 +546,18 @@ batch_withdraw_transaction (void *cls,
if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) ||
(conflict) )
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Idempotent coin in batch, not allowed. Aborting.\n");
- *mhd_ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_CONFLICT,
- TALER_EC_EXCHANGE_WITHDRAW_BATCH_IDEMPOTENT_PLANCHET,
- NULL);
+ if (! check_request_idempotent (wc,
+ mhd_ret))
+ {
+ /* We do not support *some* of the coins of the request being
+ idempotent while others being fresh. */
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Idempotent coin in batch, not allowed. Aborting.\n");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_EXCHANGE_WITHDRAW_BATCH_IDEMPOTENT_PLANCHET,
+ NULL);
+ }
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (nonce_reuse)
@@ -471,99 +575,6 @@ batch_withdraw_transaction (void *cls,
}
-/**
- * Generates our final (successful) response.
- *
- * @param rc request context
- * @param wc operation context
- * @return MHD queue status
- */
-static MHD_RESULT
-generate_reply_success (const struct TEH_RequestContext *rc,
- const struct BatchWithdrawContext *wc)
-{
- json_t *sigs;
-
- if (! wc->kyc.ok)
- {
- /* KYC required */
- return TEH_RESPONSE_reply_kyc_required (rc->connection,
- &wc->h_payto,
- &wc->kyc);
- }
- if (TALER_AML_NORMAL != wc->aml_decision)
- return TEH_RESPONSE_reply_aml_blocked (rc->connection,
- wc->aml_decision);
-
- sigs = json_array ();
- GNUNET_assert (NULL != sigs);
- for (unsigned int i = 0; iplanchets_length; i++)
- {
- struct PlanchetContext *pc = &wc->planchets[i];
-
- GNUNET_assert (
- 0 ==
- json_array_append_new (
- sigs,
- GNUNET_JSON_PACK (
- TALER_JSON_pack_blinded_denom_sig (
- "ev_sig",
- &pc->collectable.sig))));
- }
- TEH_METRICS_batch_withdraw_num_coins += wc->planchets_length;
- return TALER_MHD_REPLY_JSON_PACK (
- rc->connection,
- MHD_HTTP_OK,
- GNUNET_JSON_pack_array_steal ("ev_sigs",
- sigs));
-}
-
-
-/**
- * Check if the @a rc is replayed and we already have an
- * answer. If so, replay the existing answer and return the
- * HTTP response.
- *
- * @param rc request context
- * @param wc parsed request data
- * @param[out] mret HTTP status, set if we return true
- * @return true if the request is idempotent with an existing request
- * false if we did not find the request in the DB and did not set @a mret
- */
-static bool
-check_request_idempotent (const struct TEH_RequestContext *rc,
- const struct BatchWithdrawContext *wc,
- MHD_RESULT *mret)
-{
- for (unsigned int i = 0; iplanchets_length; i++)
- {
- struct PlanchetContext *pc = &wc->planchets[i];
- enum GNUNET_DB_QueryStatus qs;
-
- qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
- &pc->h_coin_envelope,
- &pc->collectable);
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mret = TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "get_withdraw_info");
- return true; /* well, kind-of */
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- return false;
- }
- /* generate idempotent reply */
- TEH_METRICS_num_requests[TEH_MT_REQUEST_IDEMPOTENT_BATCH_WITHDRAW]++;
- *mret = generate_reply_success (rc,
- wc);
- return true;
-}
-
-
/**
* The request was parsed successfully. Prepare
* our side for the main DB transaction.
@@ -691,8 +702,7 @@ parse_planchets (const struct TEH_RequestContext *rc,
ksh = TEH_keys_get_state ();
if (NULL == ksh)
{
- if (! check_request_idempotent (rc,
- wc,
+ if (! check_request_idempotent (wc,
&mret))
{
return TALER_MHD_reply_with_error (rc->connection,
@@ -713,8 +723,7 @@ parse_planchets (const struct TEH_RequestContext *rc,
NULL);
if (NULL == dk)
{
- if (! check_request_idempotent (rc,
- wc,
+ if (! check_request_idempotent (wc,
&mret))
{
return TEH_RESPONSE_reply_unknown_denom_pub_hash (
@@ -726,8 +735,7 @@ parse_planchets (const struct TEH_RequestContext *rc,
if (GNUNET_TIME_absolute_is_past (dk->meta.expire_withdraw.abs_time))
{
/* This denomination is past the expiration time for withdraws */
- if (! check_request_idempotent (rc,
- wc,
+ if (! check_request_idempotent (wc,
&mret))
{
return TEH_RESPONSE_reply_expired_denom_pub_hash (
@@ -751,8 +759,7 @@ parse_planchets (const struct TEH_RequestContext *rc,
if (dk->recoup_possible)
{
/* This denomination has been revoked */
- if (! check_request_idempotent (rc,
- wc,
+ if (! check_request_idempotent (wc,
&mret))
{
return TEH_RESPONSE_reply_expired_denom_pub_hash (
@@ -832,7 +839,10 @@ TEH_handler_batch_withdraw (struct TEH_RequestContext *rc,
const struct TALER_ReservePublicKeyP *reserve_pub,
const json_t *root)
{
- struct BatchWithdrawContext wc;
+ struct BatchWithdrawContext wc = {
+ .reserve_pub = reserve_pub,
+ .rc = rc
+ };
json_t *planchets;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("planchets",
@@ -840,13 +850,9 @@ TEH_handler_batch_withdraw (struct TEH_RequestContext *rc,
GNUNET_JSON_spec_end ()
};
- memset (&wc,
- 0,
- sizeof (wc));
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TEH_currency,
&wc.batch_total));
- wc.reserve_pub = reserve_pub;
{
enum GNUNET_GenericReturnValue res;
diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c b/src/exchange/taler-exchange-httpd_kyc-check.c
index c88859268..bf4e4dea1 100644
--- a/src/exchange/taler-exchange-httpd_kyc-check.c
+++ b/src/exchange/taler-exchange-httpd_kyc-check.c
@@ -112,6 +112,11 @@ struct KycPoller
*/
const char *section_name;
+ /**
+ * Set to AML status of the account.
+ */
+ enum TALER_AmlDecisionState aml_status;
+
/**
* Set to error encountered with KYC logic, if any.
*/
@@ -303,6 +308,7 @@ kyc_check (void *cls,
TEH_plugin->cls,
kyp->requirement_row,
&requirements,
+ &kyp->aml_status,
&h_payto);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
@@ -580,6 +586,17 @@ TEH_handler_kyc_check (
if ( (NULL == kyp->ih) &&
(! kyp->kyc_required) )
{
+ if (TALER_AML_NORMAL != kyp->aml_status)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "KYC is OK, but AML active: %d\n",
+ (int) kyp->aml_status);
+ return TALER_MHD_REPLY_JSON_PACK (
+ rc->connection,
+ MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
+ GNUNET_JSON_pack_uint64 ("aml_status",
+ kyp->aml_status));
+ }
/* KYC not required */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"KYC not required %llu\n",
@@ -628,6 +645,8 @@ TEH_handler_kyc_check (
return TALER_MHD_REPLY_JSON_PACK (
rc->connection,
MHD_HTTP_ACCEPTED,
+ GNUNET_JSON_pack_uint64 ("aml_status",
+ kyp->aml_status),
GNUNET_JSON_pack_string ("kyc_url",
kyp->kyc_url));
}
@@ -665,6 +684,8 @@ TEH_handler_kyc_check (
&sig),
GNUNET_JSON_pack_data_auto ("exchange_pub",
&pub),
+ GNUNET_JSON_pack_uint64 ("aml_status",
+ kyp->aml_status),
GNUNET_JSON_pack_object_incref ("kyc_details",
kyp->kyc_details),
GNUNET_JSON_pack_timestamp ("now",
diff --git a/src/exchange/taler-exchange-httpd_reserves_get.c b/src/exchange/taler-exchange-httpd_reserves_get.c
index 88f7aca9c..c22e62bf5 100644
--- a/src/exchange/taler-exchange-httpd_reserves_get.c
+++ b/src/exchange/taler-exchange-httpd_reserves_get.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2022 Taler Systems SA
+ Copyright (C) 2014-2023 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
@@ -62,6 +62,16 @@ struct ReservePoller
*/
struct GNUNET_TIME_Absolute timeout;
+ /**
+ * Public key of the reserve the inquiry is about.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * Balance of the reserve, set in the callback.
+ */
+ struct TALER_Amount balance;
+
/**
* True if we are still suspended.
*/
@@ -84,13 +94,10 @@ static struct ReservePoller *rp_tail;
void
TEH_reserves_get_cleanup ()
{
- struct ReservePoller *rp;
-
- while (NULL != (rp = rp_head))
+ for (struct ReservePoller *rp = rp_head;
+ NULL != rp;
+ rp = rp->next)
{
- GNUNET_CONTAINER_DLL_remove (rp_head,
- rp_tail,
- rp);
if (rp->suspended)
{
rp->suspended = false;
@@ -115,11 +122,14 @@ rp_cleanup (struct TEH_RequestContext *rc)
if (NULL != rp->eh)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Cancelling DB event listening\n");
+ "Cancelling DB event listening on cleanup (odd unless during shutdown)\n");
TEH_plugin->event_listen_cancel (TEH_plugin->cls,
rp->eh);
rp->eh = NULL;
}
+ GNUNET_CONTAINER_DLL_remove (rp_head,
+ rp_tail,
+ rp);
GNUNET_free (rp);
}
@@ -137,26 +147,15 @@ db_event_cb (void *cls,
const void *extra,
size_t extra_size)
{
- struct TEH_RequestContext *rc = cls;
- struct ReservePoller *rp = rc->rh_ctx;
+ struct ReservePoller *rp = cls;
struct GNUNET_AsyncScopeSave old_scope;
(void) extra;
(void) extra_size;
- if (NULL == rp)
- return; /* event triggered while main transaction
- was still running */
if (! rp->suspended)
return; /* might get multiple wake-up events */
- rp->suspended = false;
- GNUNET_async_scope_enter (&rc->async_scope_id,
- &old_scope);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Resuming from long-polling on reserve\n");
TEH_check_invariants ();
- GNUNET_CONTAINER_DLL_remove (rp_head,
- rp_tail,
- rp);
+ rp->suspended = false;
MHD_resume_connection (rp->connection);
TALER_MHD_daemon_trigger ();
TEH_check_invariants ();
@@ -164,191 +163,133 @@ db_event_cb (void *cls,
}
-/**
- * Closure for #reserve_history_transaction.
- */
-struct ReserveHistoryContext
-{
- /**
- * Public key of the reserve the inquiry is about.
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * Balance of the reserve, set in the callback.
- */
- struct TALER_Amount balance;
-
- /**
- * Set to true if we did not find the reserve.
- */
- bool not_found;
-};
-
-
-/**
- * Function implementing /reserves/ GET transaction.
- * Execute a /reserves/ GET. 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 ReserveHistoryContext *`
- * @param connection MHD request which triggered the transaction
- * @param[out] mhd_ret set to MHD response status for @a connection,
- * if transaction failed (!)
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-reserve_balance_transaction (void *cls,
- struct MHD_Connection *connection,
- MHD_RESULT *mhd_ret)
-{
- struct ReserveHistoryContext *rsc = cls;
- enum GNUNET_DB_QueryStatus qs;
-
- qs = TEH_plugin->get_reserve_balance (TEH_plugin->cls,
- &rsc->reserve_pub,
- &rsc->balance);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- {
- GNUNET_break (0);
- *mhd_ret
- = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "get_reserve_balance");
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- rsc->not_found = true;
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
- rsc->not_found = false;
- return qs;
-}
-
-
MHD_RESULT
TEH_handler_reserves_get (struct TEH_RequestContext *rc,
const char *const args[1])
{
- struct ReserveHistoryContext rsc;
- struct GNUNET_TIME_Relative timeout = GNUNET_TIME_UNIT_ZERO;
- struct GNUNET_DB_EventHandler *eh = NULL;
+ struct ReservePoller *rp = rc->rh_ctx;
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (args[0],
- strlen (args[0]),
- &rsc.reserve_pub,
- sizeof (rsc.reserve_pub)))
+ if (NULL == rp)
{
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_RESERVE_PUB_MALFORMED,
- args[0]);
- }
- {
- const char *long_poll_timeout_ms;
+ struct GNUNET_TIME_Relative timeout
+ = GNUNET_TIME_UNIT_ZERO;
- long_poll_timeout_ms
- = MHD_lookup_connection_value (rc->connection,
- MHD_GET_ARGUMENT_KIND,
- "timeout_ms");
- if (NULL != long_poll_timeout_ms)
+ rp = GNUNET_new (struct ReservePoller);
+ rp->connection = rc->connection;
+ rc->rh_ctx = rp;
+ rc->rh_cleaner = &rp_cleanup;
+ GNUNET_CONTAINER_DLL_insert (rp_head,
+ rp_tail,
+ rp);
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[0],
+ strlen (args[0]),
+ &rp->reserve_pub,
+ sizeof (rp->reserve_pub)))
{
- unsigned int timeout_ms;
- char dummy;
-
- if (1 != sscanf (long_poll_timeout_ms,
- "%u%c",
- &timeout_ms,
- &dummy))
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "timeout_ms (must be non-negative number)");
- }
- timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
- timeout_ms);
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_RESERVE_PUB_MALFORMED,
+ args[0]);
}
+ {
+ const char *long_poll_timeout_ms;
+
+ long_poll_timeout_ms
+ = MHD_lookup_connection_value (rc->connection,
+ MHD_GET_ARGUMENT_KIND,
+ "timeout_ms");
+ if (NULL != long_poll_timeout_ms)
+ {
+ unsigned int timeout_ms;
+ char dummy;
+
+ if (1 != sscanf (long_poll_timeout_ms,
+ "%u%c",
+ &timeout_ms,
+ &dummy))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "timeout_ms (must be non-negative number)");
+ }
+ timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
+ timeout_ms);
+ }
+ }
+ rp->timeout = GNUNET_TIME_relative_to_absolute (timeout);
}
- if ( (! GNUNET_TIME_relative_is_zero (timeout)) &&
- (NULL == rc->rh_ctx) )
+
+ if ( (GNUNET_TIME_absolute_is_future (rp->timeout)) &&
+ (NULL == rp->eh) )
{
struct TALER_ReserveEventP rep = {
.header.size = htons (sizeof (rep)),
.header.type = htons (TALER_DBEVENT_EXCHANGE_RESERVE_INCOMING),
- .reserve_pub = rsc.reserve_pub
+ .reserve_pub = rp->reserve_pub
};
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Starting DB event listening\n");
- eh = TEH_plugin->event_listen (TEH_plugin->cls,
- timeout,
- &rep.header,
- &db_event_cb,
- rc);
+ "Starting DB event listening until %s\n",
+ GNUNET_TIME_absolute2s (rp->timeout));
+ rp->eh = TEH_plugin->event_listen (
+ TEH_plugin->cls,
+ GNUNET_TIME_absolute_get_remaining (rp->timeout),
+ &rep.header,
+ &db_event_cb,
+ rp);
}
{
- MHD_RESULT mhd_ret;
+ enum GNUNET_DB_QueryStatus qs;
- if (GNUNET_OK !=
- TEH_DB_run_transaction (rc->connection,
- "get reserve balance",
- TEH_MT_REQUEST_OTHER,
- &mhd_ret,
- &reserve_balance_transaction,
- &rsc))
- {
- if (NULL != eh)
- TEH_plugin->event_listen_cancel (TEH_plugin->cls,
- eh);
- return mhd_ret;
- }
- }
- /* generate proper response */
- if (rsc.not_found)
- {
- struct ReservePoller *rp = rc->rh_ctx;
-
- if ( (NULL != rp) ||
- (GNUNET_TIME_relative_is_zero (timeout)) )
+ qs = TEH_plugin->get_reserve_balance (TEH_plugin->cls,
+ &rp->reserve_pub,
+ &rp->balance);
+ switch (qs)
{
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ GNUNET_break (0); /* single-shot query should never have soft-errors */
return TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_EXCHANGE_RESERVES_STATUS_UNKNOWN,
- args[0]);
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_SOFT_FAILURE,
+ "get_reserve_balance");
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "get_reserve_balance");
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Got reserve balance of %s\n",
+ TALER_amount2s (&rp->balance));
+ return TALER_MHD_REPLY_JSON_PACK (rc->connection,
+ MHD_HTTP_OK,
+ TALER_JSON_pack_amount ("balance",
+ &rp->balance));
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ if (! GNUNET_TIME_absolute_is_future (rp->timeout))
+ {
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_EXCHANGE_RESERVES_STATUS_UNKNOWN,
+ args[0]);
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Long-polling on reserve for %s\n",
+ GNUNET_STRINGS_relative_time_to_string (
+ GNUNET_TIME_absolute_get_remaining (rp->timeout),
+ true));
+ rp->suspended = true;
+ MHD_suspend_connection (rc->connection);
+ return MHD_YES;
}
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Long-polling on reserve for %s\n",
- GNUNET_STRINGS_relative_time_to_string (timeout,
- GNUNET_YES));
- rp = GNUNET_new (struct ReservePoller);
- rp->connection = rc->connection;
- rp->timeout = GNUNET_TIME_relative_to_absolute (timeout);
- rp->eh = eh;
- rc->rh_ctx = rp;
- rc->rh_cleaner = &rp_cleanup;
- rp->suspended = true;
- GNUNET_CONTAINER_DLL_insert (rp_head,
- rp_tail,
- rp);
- MHD_suspend_connection (rc->connection);
- return MHD_YES;
}
- if (NULL != eh)
- TEH_plugin->event_listen_cancel (TEH_plugin->cls,
- eh);
- return TALER_MHD_REPLY_JSON_PACK (
- rc->connection,
- MHD_HTTP_OK,
- TALER_JSON_pack_amount ("balance",
- &rsc.balance));
+ GNUNET_break (0);
+ return MHD_NO;
}
diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c
index 168e7b9b7..235c0153f 100644
--- a/src/exchange/taler-exchange-wirewatch.c
+++ b/src/exchange/taler-exchange-wirewatch.c
@@ -57,6 +57,12 @@ static struct TALER_BANK_CreditHistoryHandle *hh;
*/
static bool hh_returned_data;
+/**
+ * Set to true if the request for history did not
+ * succeed because the account was unknown.
+ */
+static bool hh_account_404;
+
/**
* When did we start the last @e hh request?
*/
@@ -472,9 +478,9 @@ transaction_completed (void)
GNUNET_SCHEDULER_shutdown ();
return;
}
- if (! hh_returned_data)
+ if (! (hh_returned_data || hh_account_404) )
{
- /* Enforce long polling delay even if the server ignored it
+ /* Enforce long-polling delay even if the server ignored it
and returned earlier */
struct GNUNET_TIME_Relative latency;
struct GNUNET_TIME_Relative left;
@@ -482,8 +488,17 @@ transaction_completed (void)
latency = GNUNET_TIME_absolute_get_duration (hh_start_time);
left = GNUNET_TIME_relative_subtract (longpoll_timeout,
latency);
+ if (! (test_mode ||
+ GNUNET_TIME_relative_is_zero (left)) )
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, // WARNING,
+ "Server did not respect long-polling, enforcing client-side by sleeping for %s\n",
+ GNUNET_TIME_relative2s (left,
+ true));
delayed_until = GNUNET_TIME_relative_to_absolute (left);
}
+ if (hh_account_404)
+ delayed_until = GNUNET_TIME_relative_to_absolute (
+ GNUNET_TIME_UNIT_MILLISECONDS);
if (test_mode)
delayed_until = GNUNET_TIME_UNIT_ZERO_ABS;
GNUNET_assert (NULL == task);
@@ -495,12 +510,12 @@ transaction_completed (void)
* We got incoming transaction details from the bank. Add them
* to the database.
*
- * @param batch_size desired batch size
+ * @param wrap_size desired bulk insert size
* @param details array of transaction details
* @param details_length length of the @a details array
*/
static void
-process_reply (unsigned int batch_size,
+process_reply (unsigned int wrap_size,
const struct TALER_BANK_CreditDetails *details,
unsigned int details_length)
{
@@ -570,7 +585,7 @@ process_reply (unsigned int batch_size,
qs = db_plugin->reserves_in_insert (db_plugin->cls,
reserves,
details_length,
- batch_size,
+ wrap_size,
qss);
switch (qs)
{
@@ -581,7 +596,7 @@ process_reply (unsigned int batch_size,
case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Got DB soft error for batch2_reserves_in_insert (%u). Rolling back.\n",
- batch_size);
+ wrap_size);
handle_soft_error ();
return;
default:
@@ -686,36 +701,36 @@ static void
history_cb (void *cls,
const struct TALER_BANK_CreditHistoryResponse *reply)
{
- static int batch_mode = -2;
+ static int wrap_size = -2;
(void) cls;
- if (-2 == batch_mode)
+ if (-2 == wrap_size)
{
- const char *mode = getenv ("TALER_WIREWATCH_BATCH_SIZE");
+ const char *mode = getenv ("TALER_WIREWATCH_WARP_SIZE");
char dummy;
if ( (NULL == mode) ||
(1 != sscanf (mode,
"%d%c",
- &batch_mode,
+ &wrap_size,
&dummy)) )
{
if (NULL != mode)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Bad batch mode `%s' specified\n",
mode);
- batch_mode = 8; /* maximum supported is currently 8 */
+ wrap_size = 8; /* maximum supported is currently 8 */
}
}
GNUNET_assert (NULL == task);
hh = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"History request returned with HTTP status %u\n",
reply->http_status);
switch (reply->http_status)
{
case MHD_HTTP_OK:
- process_reply (batch_mode,
+ process_reply (wrap_size,
reply->details.success.details,
reply->details.success.details_length);
return;
@@ -723,6 +738,7 @@ history_cb (void *cls,
transaction_completed ();
return;
case MHD_HTTP_NOT_FOUND:
+ hh_account_404 = true;
if (ignore_account_404)
{
transaction_completed ();
@@ -761,6 +777,7 @@ continue_with_shard (void *cls)
(unsigned long long) latest_row_off);
hh_start_time = GNUNET_TIME_absolute_get ();
hh_returned_data = false;
+ hh_account_404 = false;
hh = TALER_BANK_credit_history (ctx,
ai->auth,
latest_row_off,
@@ -857,6 +874,17 @@ lock_shard (void *cls)
job_name,
GNUNET_STRINGS_relative_time_to_string (rdelay,
true));
+#if 1
+ if (GNUNET_TIME_relative_cmp (rdelay,
+ >,
+ GNUNET_TIME_UNIT_SECONDS))
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Delay would have been for %s\n",
+ GNUNET_TIME_relative2s (rdelay,
+ true));
+ rdelay = GNUNET_TIME_relative_min (rdelay,
+ GNUNET_TIME_UNIT_SECONDS);
+#endif
delayed_until = GNUNET_TIME_relative_to_absolute (rdelay);
}
GNUNET_assert (NULL == task);
@@ -869,7 +897,7 @@ lock_shard (void *cls)
job_name,
GNUNET_STRINGS_relative_time_to_string (
wirewatch_idle_sleep_interval,
- GNUNET_YES));
+ true));
delayed_until = GNUNET_TIME_relative_to_absolute (
wirewatch_idle_sleep_interval);
shard_open = false;
diff --git a/src/exchangedb/.gitignore b/src/exchangedb/.gitignore
index 264217a3d..fa833d81f 100644
--- a/src/exchangedb/.gitignore
+++ b/src/exchangedb/.gitignore
@@ -7,3 +7,9 @@ perf_select_refunds_by_coin-postgres
exchange-0002.sql
procedures.sql
exchange-0003.sql
+perf-exchangedb-reserves-in-insert-postgres
+test-exchangedb-batch-reserves-in-insert-postgres
+test-exchangedb-by-j-postgres
+test-exchangedb-populate-link-data-postgres
+test-exchangedb-populate-ready-deposit-postgres
+test-exchangedb-populate-select-refunds-by-coin-postgres
\ No newline at end of file
diff --git a/src/exchangedb/0002-refresh_revealed_coins.sql b/src/exchangedb/0002-refresh_revealed_coins.sql
index 912e4bbbd..5fd315ba3 100644
--- a/src/exchangedb/0002-refresh_revealed_coins.sql
+++ b/src/exchangedb/0002-refresh_revealed_coins.sql
@@ -62,6 +62,9 @@ BEGIN
,table_name
,partition_suffix
);
+ --
+ -- FIXME: Add comment for link_sig
+ --
PERFORM comment_partitioned_column(
'envelope of the new coin to be signed'
,'coin_ev'
diff --git a/src/exchangedb/0003-withdraw_age_commitments.sql b/src/exchangedb/0003-withdraw_age_commitments.sql
index 6c153598d..b8451129a 100644
--- a/src/exchangedb/0003-withdraw_age_commitments.sql
+++ b/src/exchangedb/0003-withdraw_age_commitments.sql
@@ -33,7 +33,6 @@ BEGIN
',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32)'
',reserve_sig BYTEA CHECK (LENGTH(reserve_sig)=64)'
',noreveal_index INT4 NOT NULL'
- ',timestamp INT8 NOT NULL'
') %s ;'
,table_name
,'PARTITION BY HASH (reserve_pub)'
@@ -51,7 +50,7 @@ BEGIN
,partition_suffix
);
PERFORM comment_partitioned_column(
- 'The maximum age that the client commits to with this request'
+ 'The maximum age (in years) that the client commits to with this request'
,'max_age'
,table_name
,partition_suffix
@@ -74,12 +73,6 @@ BEGIN
,table_name
,partition_suffix
);
- PERFORM comment_partitioned_column(
- 'Timestamp with the time when the withdraw-age request was received by the exchange'
- ,'timestamp'
- ,table_name
- ,partition_suffix
- );
END
$$;
diff --git a/src/exchangedb/0003-withdraw_age_reveals.sql b/src/exchangedb/0003-withdraw_age_reveals.sql
index 3353d9367..af66eab75 100644
--- a/src/exchangedb/0003-withdraw_age_reveals.sql
+++ b/src/exchangedb/0003-withdraw_age_reveals.sql
@@ -14,22 +14,25 @@
-- TALER; see the file COPYING. If not, see
--
-CREATE FUNCTION create_table_withdraw_age_reveals(
+CREATE FUNCTION create_table_withdraw_age_revealed_coins(
IN partition_suffix VARCHAR DEFAULT NULL
)
RETURNS VOID
LANGUAGE plpgsql
AS $$
DECLARE
- table_name VARCHAR DEFAULT 'withdraw_age_reveals';
+ table_name VARCHAR DEFAULT 'withdraw_age_revealed_coins';
BEGIN
PERFORM create_partitioned_table(
'CREATE TABLE %I'
- '(withdraw_age_reveals_id BIGINT GENERATED BY DEFAULT AS IDENTITY' -- UNIQUE
- ',h_commitment BYTEA NOT NULL CHECK (LENGTH(h_commitment)=32)'
+ '(withdraw_age_revealed_coins_id BIGINT GENERATED BY DEFAULT AS IDENTITY' -- UNIQUE
+ ',h_commitment BYTEA NOT NULL CHECK (LENGTH(h_commitment)=64)'
',freshcoin_index INT4 NOT NULL'
',denominations_serial INT8 NOT NULL'
- ',h_coin_ev BYTEA CHECK (LENGTH(h_coin_ev)=32)'
+ ',coin_ev BYTEA NOT NULL'
+ ',h_coin_ev BYTEA CHECK (LENGTH(h_coin_ev)=64)'
+ ',ev_sig BYTEA NOT NULL'
+ ',ewv BYTEA NOT NULL'
') %s ;'
,table_name
,'PARTITION BY HASH (h_commitment)'
@@ -59,29 +62,47 @@ BEGIN
,partition_suffix
);
PERFORM comment_partitioned_column(
- 'Hash of the blinded coins'
+ 'Envelope of the new coin to be signed'
+ ,'coin_ev'
+ ,table_name
+ ,partition_suffix
+ );
+ PERFORM comment_partitioned_column(
+ 'Hash of the envelope of the new coin to be signed (for lookups)'
,'h_coin_ev'
,table_name
,partition_suffix
);
+ PERFORM comment_partitioned_column(
+ 'Exchange signature over the envelope'
+ ,'ev_sig'
+ ,table_name
+ ,partition_suffix
+ );
+ PERFORM comment_partitioned_column(
+ 'Exchange contributed values in the creation of the fresh coin (see /csr)'
+ ,'ewv'
+ ,table_name
+ ,partition_suffix
+ );
END
$$;
-CREATE FUNCTION constrain_table_withdraw_age_reveals(
+CREATE FUNCTION constrain_table_withdraw_age_revealed_coins(
IN partition_suffix VARCHAR
)
RETURNS void
LANGUAGE plpgsql
AS $$
DECLARE
- table_name VARCHAR DEFAULT 'withdraw_age_reveals';
+ table_name VARCHAR DEFAULT 'withdraw_age_revealed_coins';
BEGIN
table_name = concat_ws('_', table_name, partition_suffix);
EXECUTE FORMAT (
'ALTER TABLE ' || table_name ||
- ' ADD CONSTRAINT ' || table_name || '_withdraw_age_reveals_id_key'
- ' UNIQUE (withdraw_age_reveals_id);'
+ ' ADD CONSTRAINT ' || table_name || '_withdraw_age_revealed_coins_id_key'
+ ' UNIQUE (withdraw_age_revealed_coins_id);'
);
EXECUTE FORMAT (
'ALTER TABLE ' || table_name ||
@@ -91,12 +112,12 @@ BEGIN
END
$$;
-CREATE FUNCTION foreign_table_withdraw_age_reveals()
+CREATE FUNCTION foreign_table_withdraw_age_revealed_coins()
RETURNS void
LANGUAGE plpgsql
AS $$
DECLARE
- table_name VARCHAR DEFAULT 'withdraw_age_reveals';
+ table_name VARCHAR DEFAULT 'withdraw_age_revealed_coins';
BEGIN
EXECUTE FORMAT (
'ALTER TABLE ' || table_name ||
@@ -121,17 +142,17 @@ INSERT INTO exchange_tables
,partitioned
,by_range)
VALUES
- ('withdraw_age_reveals'
+ ('withdraw_age_revealed_coins'
,'exchange-0003'
,'create'
,TRUE
,FALSE),
- ('withdraw_age_reveals'
+ ('withdraw_age_revealed_coins'
,'exchange-0003'
,'constrain'
,TRUE
,FALSE),
- ('withdraw_age_reveals'
+ ('withdraw_age_revealed_coins'
,'exchange-0003'
,'foreign'
,TRUE
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index 9757aefff..de76997cb 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -116,6 +116,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
pg_reserves_in_insert.h pg_reserves_in_insert.c \
pg_get_withdraw_info.h pg_get_withdraw_info.c \
pg_get_age_withdraw_info.c pg_get_age_withdraw_info.h \
+ pg_batch_ensure_coin_known.h pg_batch_ensure_coin_known.c \
pg_do_batch_withdraw.h pg_do_batch_withdraw.c \
pg_get_policy_details.h pg_get_policy_details.c \
pg_persist_policy_details.h pg_persist_policy_details.c \
diff --git a/src/exchangedb/exchange_do_batch2_reserves_in_insert.sql b/src/exchangedb/exchange_do_batch2_reserves_in_insert.sql
deleted file mode 100644
index 6df8b7554..000000000
--- a/src/exchangedb/exchange_do_batch2_reserves_in_insert.sql
+++ /dev/null
@@ -1,186 +0,0 @@
---
--- This file is part of TALER
--- Copyright (C) 2014--2022 Taler Systems SA
---
--- 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, see
---
-
-DROP FUNCTION IF EXISTS exchange_do_batch2_reserves_insert;
-CREATE OR REPLACE FUNCTION exchange_do_batch2_reserves_insert(
- IN in_reserve_pub BYTEA,
- IN in_expiration_date INT8,
- IN in_gc_date INT8,
- IN in_wire_ref INT8,
- IN in_credit_val INT8,
- IN in_credit_frac INT4,
- IN in_exchange_account_name VARCHAR,
- IN in_execution_date INT8,
- IN in_wire_source_h_payto BYTEA, ---h_payto
- IN in_payto_uri VARCHAR,
- IN in_reserve_expiration INT8,
- IN in_notify text,
- IN in2_notify text,
- IN in2_reserve_pub BYTEA,
- IN in2_wire_ref INT8,
- IN in2_credit_val INT8,
- IN in2_credit_frac INT4,
- IN in2_exchange_account_name VARCHAR,
- IN in2_execution_date INT8,
- IN in2_wire_source_h_payto BYTEA, ---h_payto
- IN in2_payto_uri VARCHAR,
- IN in2_reserve_expiration INT8,
- OUT out_reserve_found BOOLEAN,
- OUT out_reserve_found2 BOOLEAN,
- OUT transaction_duplicate BOOLEAN,
- OUT transaction_duplicate2 BOOLEAN,
- OUT ruuid INT8,
- OUT ruuid2 INT8)
-LANGUAGE plpgsql
-AS $$
-DECLARE
- curs_reserve_exist REFCURSOR;
-DECLARE
- curs_transaction_exist refcursor;
-DECLARE
- i RECORD;
-DECLARE
- r RECORD;
-DECLARE
- k INT8;
-BEGIN
- transaction_duplicate=TRUE;
- transaction_duplicate2=TRUE;
- out_reserve_found = TRUE;
- out_reserve_found2 = TRUE;
- ruuid=0;
- ruuid2=0;
- k=0;
- INSERT INTO wire_targets
- (wire_target_h_payto
- ,payto_uri)
- VALUES
- (in_wire_source_h_payto
- ,in_payto_uri),
- (in2_wire_source_h_payto
- ,in2_payto_uri)
- ON CONFLICT DO NOTHING;
-
- OPEN curs_reserve_exist FOR
- WITH reserve_changes AS (
- INSERT INTO reserves
- (reserve_pub
- ,current_balance_val
- ,current_balance_frac
- ,expiration_date
- ,gc_date)
- VALUES
- (in_reserve_pub
- ,in_credit_val
- ,in_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in2_reserve_pub
- ,in2_credit_val
- ,in2_credit_frac
- ,in_expiration_date
- ,in_gc_date)
- ON CONFLICT DO NOTHING
- RETURNING reserve_uuid,reserve_pub)
- SELECT * FROM reserve_changes;
- WHILE k < 2 LOOP
- FETCH FROM curs_reserve_exist INTO i;
- IF FOUND
- THEN
- IF in_reserve_pub = i.reserve_pub
- THEN
- ruuid = i.reserve_uuid;
- IF in_reserve_pub <> in2_reserve_pub
- THEN
- out_reserve_found = FALSE;
- END IF;
- END IF;
- IF in2_reserve_pub = i.reserve_pub
- THEN
- out_reserve_found2 = FALSE;
- ruuid2 = i.reserve_uuid;
- END IF;
- END IF;
- k=k+1;
- END LOOP;
- CLOSE curs_reserve_exist;
-
--- FIXME: must be changed to EXECUTE FORMAT!
- PERFORM pg_notify(in_notify, NULL);
- PERFORM pg_notify(in2_notify, NULL);
-
- OPEN curs_transaction_exist FOR
- WITH reserve_in_exist AS (
- INSERT INTO reserves_in
- (reserve_pub
- ,wire_reference
- ,credit_val
- ,credit_frac
- ,exchange_account_section
- ,wire_source_h_payto
- ,execution_date)
- VALUES
- (in_reserve_pub
- ,in_wire_ref
- ,in_credit_val
- ,in_credit_frac
- ,in_exchange_account_name
- ,in_wire_source_h_payto
- ,in_execution_date),
- (in2_reserve_pub
- ,in2_wire_ref
- ,in2_credit_val
- ,in2_credit_frac
- ,in2_exchange_account_name
- ,in2_wire_source_h_payto
- ,in_execution_date)
- ON CONFLICT DO NOTHING
- RETURNING reserve_pub)
- SELECT * FROM reserve_in_exist;
- FETCH FROM curs_transaction_exist INTO r;
- IF FOUND
- THEN
- IF in_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate = FALSE;
- END IF;
- IF in2_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate2 = FALSE;
- END IF;
- FETCH FROM curs_transaction_exist INTO r;
- IF FOUND
- THEN
- IF in_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate = FALSE;
- END IF;
- IF in2_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate2 = FALSE;
- END IF;
- END IF;
- END IF;
-/* IF transaction_duplicate
- OR transaction_duplicate2
- THEN
- CLOSE curs_transaction_exist;
- ROLLBACK;
- RETURN;
- END IF;*/
- CLOSE curs_transaction_exist;
- RETURN;
-END $$;
diff --git a/src/exchangedb/exchange_do_batch4_reserves_in_insert.sql b/src/exchangedb/exchange_do_batch4_reserves_in_insert.sql
deleted file mode 100644
index 6a5707109..000000000
--- a/src/exchangedb/exchange_do_batch4_reserves_in_insert.sql
+++ /dev/null
@@ -1,287 +0,0 @@
---
--- This file is part of TALER
--- Copyright (C) 2014--2022 Taler Systems SA
---
--- 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, see
---
-
-DROP FUNCTION IF EXISTS exchange_do_batch4_reserves_insert;
-CREATE OR REPLACE FUNCTION exchange_do_batch4_reserves_insert(
- IN in_reserve_pub BYTEA,
- IN in_expiration_date INT8,
- IN in_gc_date INT8,
- IN in_wire_ref INT8,
- IN in_credit_val INT8,
- IN in_credit_frac INT4,
- IN in_exchange_account_name VARCHAR,
- IN in_execution_date INT8,
- IN in_wire_source_h_payto BYTEA, ---h_payto
- IN in_payto_uri VARCHAR,
- IN in_reserve_expiration INT8,
- IN in_notify text,
- IN in2_notify text,
- IN in3_notify text,
- IN in4_notify text,
- IN in2_reserve_pub BYTEA,
- IN in2_wire_ref INT8,
- IN in2_credit_val INT8,
- IN in2_credit_frac INT4,
- IN in2_exchange_account_name VARCHAR,
- IN in2_execution_date INT8,
- IN in2_wire_source_h_payto BYTEA, ---h_payto
- IN in2_payto_uri VARCHAR,
- IN in2_reserve_expiration INT8,
- IN in3_reserve_pub BYTEA,
- IN in3_wire_ref INT8,
- IN in3_credit_val INT8,
- IN in3_credit_frac INT4,
- IN in3_exchange_account_name VARCHAR,
- IN in3_execution_date INT8,
- IN in3_wire_source_h_payto BYTEA, ---h_payto
- IN in3_payto_uri VARCHAR,
- IN in3_reserve_expiration INT8,
- IN in4_reserve_pub BYTEA,
- IN in4_wire_ref INT8,
- IN in4_credit_val INT8,
- IN in4_credit_frac INT4,
- IN in4_exchange_account_name VARCHAR,
- IN in4_execution_date INT8,
- IN in4_wire_source_h_payto BYTEA, ---h_payto
- IN in4_payto_uri VARCHAR,
- IN in4_reserve_expiration INT8,
- OUT out_reserve_found BOOLEAN,
- OUT out_reserve_found2 BOOLEAN,
- OUT out_reserve_found3 BOOLEAN,
- OUT out_reserve_found4 BOOLEAN,
- OUT transaction_duplicate BOOLEAN,
- OUT transaction_duplicate2 BOOLEAN,
- OUT transaction_duplicate3 BOOLEAN,
- OUT transaction_duplicate4 BOOLEAN,
- OUT ruuid INT8,
- OUT ruuid2 INT8,
- OUT ruuid3 INT8,
- OUT ruuid4 INT8)
-LANGUAGE plpgsql
-AS $$
-DECLARE
- curs_reserve_exist refcursor;
-DECLARE
- k INT8;
-DECLARE
- curs_transaction_exist refcursor;
-DECLARE
- i RECORD;
-
-BEGIN
---INITIALIZATION
- transaction_duplicate=TRUE;
- transaction_duplicate2=TRUE;
- transaction_duplicate3=TRUE;
- transaction_duplicate4=TRUE;
- out_reserve_found = TRUE;
- out_reserve_found2 = TRUE;
- out_reserve_found3 = TRUE;
- out_reserve_found4 = TRUE;
- ruuid=0;
- ruuid2=0;
- ruuid3=0;
- ruuid4=0;
- k=0;
- --SIMPLE INSERT ON CONFLICT DO NOTHING
- INSERT INTO wire_targets
- (wire_target_h_payto
- ,payto_uri)
- VALUES
- (in_wire_source_h_payto
- ,in_payto_uri),
- (in2_wire_source_h_payto
- ,in2_payto_uri),
- (in3_wire_source_h_payto
- ,in3_payto_uri),
- (in4_wire_source_h_payto
- ,in4_payto_uri)
- ON CONFLICT DO NOTHING;
-
- OPEN curs_reserve_exist FOR
- WITH reserve_changes AS (
- INSERT INTO reserves
- (reserve_pub
- ,current_balance_val
- ,current_balance_frac
- ,expiration_date
- ,gc_date)
- VALUES
- (in_reserve_pub
- ,in_credit_val
- ,in_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in2_reserve_pub
- ,in2_credit_val
- ,in2_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in3_reserve_pub
- ,in3_credit_val
- ,in3_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in4_reserve_pub
- ,in4_credit_val
- ,in4_credit_frac
- ,in_expiration_date
- ,in_gc_date)
- ON CONFLICT DO NOTHING
- RETURNING reserve_uuid,reserve_pub)
- SELECT * FROM reserve_changes;
-
- WHILE k < 4 LOOP
- FETCH FROM curs_reserve_exist INTO i;
- IF FOUND
- THEN
- IF in_reserve_pub = i.reserve_pub
- THEN
- ruuid = i.reserve_uuid;
- IF in_reserve_pub
- NOT IN (in2_reserve_pub
- ,in3_reserve_pub
- ,in4_reserve_pub)
- THEN
- out_reserve_found = FALSE;
- END IF;
- END IF;
- IF in2_reserve_pub = i.reserve_pub
- THEN
- ruuid2 = i.reserve_uuid;
- IF in2_reserve_pub
- NOT IN (in_reserve_pub
- ,in3_reserve_pub
- ,in4_reserve_pub)
- THEN
- out_reserve_found2 = FALSE;
- END IF;
- END IF;
- IF in3_reserve_pub = i.reserve_pub
- THEN
- ruuid3 = i.reserve_uuid;
- IF in3_reserve_pub
- NOT IN (in_reserve_pub
- ,in2_reserve_pub
- ,in4_reserve_pub)
- THEN
- out_reserve_found3 = FALSE;
- END IF;
- END IF;
- IF in4_reserve_pub = i.reserve_pub
- THEN
- ruuid4 = i.reserve_uuid;
- IF in4_reserve_pub
- NOT IN (in_reserve_pub
- ,in2_reserve_pub
- ,in3_reserve_pub)
- THEN
- out_reserve_found4 = FALSE;
- END IF;
- END IF;
- END IF;
- k=k+1;
- END LOOP;
- CLOSE curs_reserve_exist;
-
-
--- FIXME: must be changed to EXECUTE FORMAT!
- PERFORM pg_notify(in_notify, NULL);
- PERFORM pg_notify(in2_notify, NULL);
- PERFORM pg_notify(in3_notify, NULL);
- PERFORM pg_notify(in4_notify, NULL);
-
- k=0;
- OPEN curs_transaction_exist FOR
- WITH reserve_in_changes AS (
- INSERT INTO reserves_in
- (reserve_pub
- ,wire_reference
- ,credit_val
- ,credit_frac
- ,exchange_account_section
- ,wire_source_h_payto
- ,execution_date)
- VALUES
- (in_reserve_pub
- ,in_wire_ref
- ,in_credit_val
- ,in_credit_frac
- ,in_exchange_account_name
- ,in_wire_source_h_payto
- ,in_execution_date),
- (in2_reserve_pub
- ,in2_wire_ref
- ,in2_credit_val
- ,in2_credit_frac
- ,in2_exchange_account_name
- ,in2_wire_source_h_payto
- ,in_execution_date),
- (in3_reserve_pub
- ,in3_wire_ref
- ,in3_credit_val
- ,in3_credit_frac
- ,in3_exchange_account_name
- ,in3_wire_source_h_payto
- ,in_execution_date),
- (in4_reserve_pub
- ,in4_wire_ref
- ,in4_credit_val
- ,in4_credit_frac
- ,in4_exchange_account_name
- ,in4_wire_source_h_payto
- ,in_execution_date)
- ON CONFLICT DO NOTHING
- RETURNING reserve_pub)
- SELECT * FROM reserve_in_changes;
- WHILE k < 4 LOOP
- FETCH FROM curs_transaction_exist INTO i;
- IF FOUND
- THEN
- IF in_reserve_pub = i.reserve_pub
- THEN
- transaction_duplicate = FALSE;
- END IF;
- IF in2_reserve_pub = i.reserve_pub
- THEN
- transaction_duplicate2 = FALSE;
- END IF;
- IF in3_reserve_pub = i.reserve_pub
- THEN
- transaction_duplicate3 = FALSE;
- END IF;
- IF in4_reserve_pub = i.reserve_pub
- THEN
- transaction_duplicate4 = FALSE;
- END IF;
- END IF;
- k=k+1;
- END LOOP;
- /**ROLLBACK TRANSACTION IN SORTED PROCEDURE IS IT PROSSIBLE ?**/
- /*IF transaction_duplicate
- OR transaction_duplicate2
- OR transaction_duplicate3
- OR transaction_duplicate4
- THEN
- RAISE EXCEPTION 'Reserve did not exist, but INSERT into reserves_in gave conflict';
- ROLLBACK;
- CLOSE curs_transaction_exist;
- RETURN;
- END IF;*/
- CLOSE curs_transaction_exist;
- RETURN;
-
-END $$;
diff --git a/src/exchangedb/exchange_do_batch8_reserves_in_insert.sql b/src/exchangedb/exchange_do_batch8_reserves_in_insert.sql
deleted file mode 100644
index a9f34b897..000000000
--- a/src/exchangedb/exchange_do_batch8_reserves_in_insert.sql
+++ /dev/null
@@ -1,509 +0,0 @@
---
--- This file is part of TALER
--- Copyright (C) 2014--2022 Taler Systems SA
---
--- 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, see
---
-
-DROP FUNCTION IF EXISTS exchange_do_batch8_reserves_insert;
-CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
- IN in_reserve_pub BYTEA,
- IN in_expiration_date INT8,
- IN in_gc_date INT8,
- IN in_wire_ref INT8,
- IN in_credit_val INT8,
- IN in_credit_frac INT4,
- IN in_exchange_account_name VARCHAR,
- IN in_execution_date INT8,
- IN in_wire_source_h_payto BYTEA, ---h_payto
- IN in_payto_uri VARCHAR,
- IN in_reserve_expiration INT8,
- IN in_notify text,
- IN in2_notify text,
- IN in3_notify text,
- IN in4_notify text,
- IN in5_notify text,
- IN in6_notify text,
- IN in7_notify text,
- IN in8_notify text,
- IN in2_reserve_pub BYTEA,
- IN in2_wire_ref INT8,
- IN in2_credit_val INT8,
- IN in2_credit_frac INT4,
- IN in2_exchange_account_name VARCHAR,
- IN in2_execution_date INT8,
- IN in2_wire_source_h_payto BYTEA, ---h_payto
- IN in2_payto_uri VARCHAR,
- IN in2_reserve_expiration INT8,
- IN in3_reserve_pub BYTEA,
- IN in3_wire_ref INT8,
- IN in3_credit_val INT8,
- IN in3_credit_frac INT4,
- IN in3_exchange_account_name VARCHAR,
- IN in3_execution_date INT8,
- IN in3_wire_source_h_payto BYTEA, ---h_payto
- IN in3_payto_uri VARCHAR,
- IN in3_reserve_expiration INT8,
- IN in4_reserve_pub BYTEA,
- IN in4_wire_ref INT8,
- IN in4_credit_val INT8,
- IN in4_credit_frac INT4,
- IN in4_exchange_account_name VARCHAR,
- IN in4_execution_date INT8,
- IN in4_wire_source_h_payto BYTEA, ---h_payto
- IN in4_payto_uri VARCHAR,
- IN in4_reserve_expiration INT8,
- IN in5_reserve_pub BYTEA,
- IN in5_wire_ref INT8,
- IN in5_credit_val INT8,
- IN in5_credit_frac INT4,
- IN in5_exchange_account_name VARCHAR,
- IN in5_execution_date INT8,
- IN in5_wire_source_h_payto BYTEA, ---h_payto
- IN in5_payto_uri VARCHAR,
- IN in5_reserve_expiration INT8,
- IN in6_reserve_pub BYTEA,
- IN in6_wire_ref INT8,
- IN in6_credit_val INT8,
- IN in6_credit_frac INT4,
- IN in6_exchange_account_name VARCHAR,
- IN in6_execution_date INT8,
- IN in6_wire_source_h_payto BYTEA, ---h_payto
- IN in6_payto_uri VARCHAR,
- IN in6_reserve_expiration INT8,
- IN in7_reserve_pub BYTEA,
- IN in7_wire_ref INT8,
- IN in7_credit_val INT8,
- IN in7_credit_frac INT4,
- IN in7_exchange_account_name VARCHAR,
- IN in7_execution_date INT8,
- IN in7_wire_source_h_payto BYTEA, ---h_payto
- IN in7_payto_uri VARCHAR,
- IN in7_reserve_expiration INT8,
- IN in8_reserve_pub BYTEA,
- IN in8_wire_ref INT8,
- IN in8_credit_val INT8,
- IN in8_credit_frac INT4,
- IN in8_exchange_account_name VARCHAR,
- IN in8_execution_date INT8,
- IN in8_wire_source_h_payto BYTEA, ---h_payto
- IN in8_payto_uri VARCHAR,
- IN in8_reserve_expiration INT8,
- OUT out_reserve_found BOOLEAN,
- OUT out_reserve_found2 BOOLEAN,
- OUT out_reserve_found3 BOOLEAN,
- OUT out_reserve_found4 BOOLEAN,
- OUT out_reserve_found5 BOOLEAN,
- OUT out_reserve_found6 BOOLEAN,
- OUT out_reserve_found7 BOOLEAN,
- OUT out_reserve_found8 BOOLEAN,
- OUT transaction_duplicate BOOLEAN,
- OUT transaction_duplicate2 BOOLEAN,
- OUT transaction_duplicate3 BOOLEAN,
- OUT transaction_duplicate4 BOOLEAN,
- OUT transaction_duplicate5 BOOLEAN,
- OUT transaction_duplicate6 BOOLEAN,
- OUT transaction_duplicate7 BOOLEAN,
- OUT transaction_duplicate8 BOOLEAN,
- OUT ruuid INT8,
- OUT ruuid2 INT8,
- OUT ruuid3 INT8,
- OUT ruuid4 INT8,
- OUT ruuid5 INT8,
- OUT ruuid6 INT8,
- OUT ruuid7 INT8,
- OUT ruuid8 INT8)
-LANGUAGE plpgsql
-AS $$
-DECLARE
- curs_reserve_existed refcursor;
-DECLARE
- k INT8;
-DECLARE
- curs_transaction_existed refcursor;
-
-DECLARE
- i RECORD;
-DECLARE
- r RECORD;
-
-BEGIN
---INITIALIZATION
- transaction_duplicate=TRUE;
- transaction_duplicate2=TRUE;
- transaction_duplicate3=TRUE;
- transaction_duplicate4=TRUE;
- transaction_duplicate5=TRUE;
- transaction_duplicate6=TRUE;
- transaction_duplicate7=TRUE;
- transaction_duplicate8=TRUE;
- out_reserve_found = TRUE;
- out_reserve_found2 = TRUE;
- out_reserve_found3 = TRUE;
- out_reserve_found4 = TRUE;
- out_reserve_found5 = TRUE;
- out_reserve_found6 = TRUE;
- out_reserve_found7 = TRUE;
- out_reserve_found8 = TRUE;
- ruuid=0;
- ruuid2=0;
- ruuid3=0;
- ruuid4=0;
- ruuid5=0;
- ruuid6=0;
- ruuid7=0;
- ruuid8=0;
- k=0;
-
- --SIMPLE INSERT ON CONFLICT DO NOTHING
- INSERT INTO wire_targets
- (wire_target_h_payto
- ,payto_uri)
- VALUES
- (in_wire_source_h_payto
- ,in_payto_uri),
- (in2_wire_source_h_payto
- ,in2_payto_uri),
- (in3_wire_source_h_payto
- ,in3_payto_uri),
- (in4_wire_source_h_payto
- ,in4_payto_uri),
- (in5_wire_source_h_payto
- ,in5_payto_uri),
- (in6_wire_source_h_payto
- ,in6_payto_uri),
- (in7_wire_source_h_payto
- ,in7_payto_uri),
- (in8_wire_source_h_payto
- ,in8_payto_uri)
- ON CONFLICT DO NOTHING;
-
- OPEN curs_reserve_existed FOR
- WITH reserve_changes AS (
- INSERT INTO reserves
- (reserve_pub
- ,current_balance_val
- ,current_balance_frac
- ,expiration_date
- ,gc_date)
- VALUES
- (in_reserve_pub
- ,in_credit_val
- ,in_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in2_reserve_pub
- ,in2_credit_val
- ,in2_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in3_reserve_pub
- ,in3_credit_val
- ,in3_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in4_reserve_pub
- ,in4_credit_val
- ,in4_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in5_reserve_pub
- ,in5_credit_val
- ,in5_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in6_reserve_pub
- ,in6_credit_val
- ,in6_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in7_reserve_pub
- ,in7_credit_val
- ,in7_credit_frac
- ,in_expiration_date
- ,in_gc_date),
- (in8_reserve_pub
- ,in8_credit_val
- ,in8_credit_frac
- ,in_expiration_date
- ,in_gc_date)
- ON CONFLICT DO NOTHING
- RETURNING reserve_uuid,reserve_pub)
- SELECT * FROM reserve_changes;
-
- WHILE k < 8 LOOP
-
- FETCH FROM curs_reserve_existed INTO i;
- IF FOUND
- THEN
- IF in_reserve_pub = i.reserve_pub
- THEN
- ruuid = i.reserve_uuid;
- IF in_reserve_pub
- NOT IN (in2_reserve_pub
- ,in3_reserve_pub
- ,in4_reserve_pub
- ,in5_reserve_pub
- ,in6_reserve_pub
- ,in7_reserve_pub
- ,in8_reserve_pub)
- THEN
- out_reserve_found = FALSE;
- END IF;
- END IF;
- IF in2_reserve_pub = i.reserve_pub
- THEN
- ruuid2 = i.reserve_uuid;
- IF in2_reserve_pub
- NOT IN (in_reserve_pub
- ,in3_reserve_pub
- ,in4_reserve_pub
- ,in5_reserve_pub
- ,in6_reserve_pub
- ,in7_reserve_pub
- ,in8_reserve_pub)
- THEN
- out_reserve_found2 = FALSE;
- END IF;
- END IF;
- IF in3_reserve_pub = i.reserve_pub
- THEN
- ruuid3 = i.reserve_uuid;
- IF in3_reserve_pub
- NOT IN (in_reserve_pub
- ,in2_reserve_pub
- ,in4_reserve_pub
- ,in5_reserve_pub
- ,in6_reserve_pub
- ,in7_reserve_pub
- ,in8_reserve_pub)
- THEN
- out_reserve_found3 = FALSE;
- END IF;
- END IF;
- IF in4_reserve_pub = i.reserve_pub
- THEN
- ruuid4 = i.reserve_uuid;
- IF in4_reserve_pub
- NOT IN (in_reserve_pub
- ,in2_reserve_pub
- ,in3_reserve_pub
- ,in5_reserve_pub
- ,in6_reserve_pub
- ,in7_reserve_pub
- ,in8_reserve_pub)
- THEN
- out_reserve_found4 = FALSE;
- END IF;
- END IF;
- IF in5_reserve_pub = i.reserve_pub
- THEN
- ruuid5 = i.reserve_uuid;
- IF in5_reserve_pub
- NOT IN (in_reserve_pub
- ,in2_reserve_pub
- ,in3_reserve_pub
- ,in4_reserve_pub
- ,in6_reserve_pub
- ,in7_reserve_pub
- ,in8_reserve_pub)
- THEN
- out_reserve_found5 = FALSE;
- END IF;
- END IF;
- IF in6_reserve_pub = i.reserve_pub
- THEN
- ruuid6 = i.reserve_uuid;
- IF in6_reserve_pub
- NOT IN (in_reserve_pub
- ,in2_reserve_pub
- ,in3_reserve_pub
- ,in4_reserve_pub
- ,in5_reserve_pub
- ,in7_reserve_pub
- ,in8_reserve_pub)
- THEN
- out_reserve_found6 = FALSE;
- END IF;
- END IF;
- IF in7_reserve_pub = i.reserve_pub
- THEN
- ruuid7 = i.reserve_uuid;
- IF in7_reserve_pub
- NOT IN (in_reserve_pub
- ,in2_reserve_pub
- ,in3_reserve_pub
- ,in4_reserve_pub
- ,in5_reserve_pub
- ,in6_reserve_pub
- ,in8_reserve_pub)
- THEN
- out_reserve_found7 = FALSE;
- END IF;
- END IF;
- IF in8_reserve_pub = i.reserve_pub
- THEN
- ruuid8 = i.reserve_uuid;
- IF in8_reserve_pub
- NOT IN (in_reserve_pub
- ,in2_reserve_pub
- ,in3_reserve_pub
- ,in4_reserve_pub
- ,in5_reserve_pub
- ,in6_reserve_pub
- ,in7_reserve_pub)
- THEN
- out_reserve_found8 = FALSE;
- END IF;
- END IF;
- END IF;
- k=k+1;
- END LOOP;
-
- CLOSE curs_reserve_existed;
-
--- FIXME: must be changed to EXECUTE FORMAT!
- PERFORM pg_notify(in_notify, NULL);
- PERFORM pg_notify(in2_notify, NULL);
- PERFORM pg_notify(in3_notify, NULL);
- PERFORM pg_notify(in4_notify, NULL);
- PERFORM pg_notify(in5_notify, NULL);
- PERFORM pg_notify(in6_notify, NULL);
- PERFORM pg_notify(in7_notify, NULL);
- PERFORM pg_notify(in8_notify, NULL);
- k=0;
- OPEN curs_transaction_existed FOR
- WITH reserve_in_changes AS (
- INSERT INTO reserves_in
- (reserve_pub
- ,wire_reference
- ,credit_val
- ,credit_frac
- ,exchange_account_section
- ,wire_source_h_payto
- ,execution_date)
- VALUES
- (in_reserve_pub
- ,in_wire_ref
- ,in_credit_val
- ,in_credit_frac
- ,in_exchange_account_name
- ,in_wire_source_h_payto
- ,in_execution_date),
- (in2_reserve_pub
- ,in2_wire_ref
- ,in2_credit_val
- ,in2_credit_frac
- ,in2_exchange_account_name
- ,in2_wire_source_h_payto
- ,in_execution_date),
- (in3_reserve_pub
- ,in3_wire_ref
- ,in3_credit_val
- ,in3_credit_frac
- ,in3_exchange_account_name
- ,in3_wire_source_h_payto
- ,in_execution_date),
- (in4_reserve_pub
- ,in4_wire_ref
- ,in4_credit_val
- ,in4_credit_frac
- ,in4_exchange_account_name
- ,in4_wire_source_h_payto
- ,in_execution_date),
- (in5_reserve_pub
- ,in5_wire_ref
- ,in5_credit_val
- ,in5_credit_frac
- ,in5_exchange_account_name
- ,in5_wire_source_h_payto
- ,in_execution_date),
- (in6_reserve_pub
- ,in6_wire_ref
- ,in6_credit_val
- ,in6_credit_frac
- ,in6_exchange_account_name
- ,in6_wire_source_h_payto
- ,in_execution_date),
- (in7_reserve_pub
- ,in7_wire_ref
- ,in7_credit_val
- ,in7_credit_frac
- ,in7_exchange_account_name
- ,in7_wire_source_h_payto
- ,in_execution_date),
- (in8_reserve_pub
- ,in8_wire_ref
- ,in8_credit_val
- ,in8_credit_frac
- ,in8_exchange_account_name
- ,in8_wire_source_h_payto
- ,in_execution_date)
- ON CONFLICT DO NOTHING
- RETURNING reserve_pub)
- SELECT * FROM reserve_in_changes;
-
- WHILE k < 8 LOOP
- FETCH FROM curs_transaction_existed INTO r;
- IF FOUND
- THEN
- IF in_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate = FALSE;
- END IF;
- IF in2_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate2 = FALSE;
- END IF;
- IF in3_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate3 = FALSE;
- END IF;
- IF in4_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate4 = FALSE;
- END IF;
- IF in5_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate5 = FALSE;
- END IF;
- IF in6_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate6 = FALSE;
- END IF;
- IF in7_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate7 = FALSE;
- END IF;
- IF in8_reserve_pub = r.reserve_pub
- THEN
- transaction_duplicate8 = FALSE;
- END IF;
- END IF;
- k=k+1;
- END LOOP;
- /* IF transaction_duplicate
- OR transaction_duplicate2
- OR transaction_duplicate3
- OR transaction_duplicate4
- OR transaction_duplicate5
- OR transaction_duplicate6
- OR transaction_duplicate7
- OR transaction_duplicate8
- THEN
- CLOSE curs_transaction_existed;
- ROLLBACK;
- RETURN;
- END IF;*/
- CLOSE curs_transaction_existed;
- RETURN;
-END $$;
diff --git a/src/exchangedb/exchange_do_batch_coin_known.sql b/src/exchangedb/exchange_do_batch_coin_known.sql
new file mode 100644
index 000000000..f6a14cfab
--- /dev/null
+++ b/src/exchangedb/exchange_do_batch_coin_known.sql
@@ -0,0 +1,477 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2014--2022 Taler Systems SA
+--
+-- 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, see
+--
+
+CREATE OR REPLACE FUNCTION exchange_do_batch4_known_coin(
+ IN in_coin_pub1 BYTEA,
+ IN in_denom_pub_hash1 BYTEA,
+ IN in_h_age_commitment1 BYTEA,
+ IN in_denom_sig1 BYTEA,
+ IN in_coin_pub2 BYTEA,
+ IN in_denom_pub_hash2 BYTEA,
+ IN in_h_age_commitment2 BYTEA,
+ IN in_denom_sig2 BYTEA,
+ IN in_coin_pub3 BYTEA,
+ IN in_denom_pub_hash3 BYTEA,
+ IN in_h_age_commitment3 BYTEA,
+ IN in_denom_sig3 BYTEA,
+ IN in_coin_pub4 BYTEA,
+ IN in_denom_pub_hash4 BYTEA,
+ IN in_h_age_commitment4 BYTEA,
+ IN in_denom_sig4 BYTEA,
+ OUT existed1 BOOLEAN,
+ OUT existed2 BOOLEAN,
+ OUT existed3 BOOLEAN,
+ OUT existed4 BOOLEAN,
+ OUT known_coin_id1 INT8,
+ OUT known_coin_id2 INT8,
+ OUT known_coin_id3 INT8,
+ OUT known_coin_id4 INT8,
+ OUT denom_pub_hash1 BYTEA,
+ OUT denom_pub_hash2 BYTEA,
+ OUT denom_pub_hash3 BYTEA,
+ OUT denom_pub_hash4 BYTEA,
+ OUT age_commitment_hash1 BYTEA,
+ OUT age_commitment_hash2 BYTEA,
+ OUT age_commitment_hash3 BYTEA,
+ OUT age_commitment_hash4 BYTEA)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+WITH dd AS (
+SELECT
+ denominations_serial,
+ coin_val, coin_frac
+ FROM denominations
+ WHERE denom_pub_hash
+ IN
+ (in_denom_pub_hash1,
+ in_denom_pub_hash2,
+ in_denom_pub_hash3,
+ in_denom_pub_hash4)
+ ),--dd
+ input_rows AS (
+ VALUES
+ (in_coin_pub1,
+ in_denom_pub_hash1,
+ in_h_age_commitment1,
+ in_denom_sig1),
+ (in_coin_pub2,
+ in_denom_pub_hash2,
+ in_h_age_commitment2,
+ in_denom_sig2),
+ (in_coin_pub3,
+ in_denom_pub_hash3,
+ in_h_age_commitment3,
+ in_denom_sig3),
+ (in_coin_pub4,
+ in_denom_pub_hash4,
+ in_h_age_commitment4,
+ in_denom_sig4)
+ ),--ir
+ ins AS (
+ INSERT INTO known_coins (
+ coin_pub,
+ denominations_serial,
+ age_commitment_hash,
+ denom_sig,
+ remaining_val,
+ remaining_frac
+ )
+ SELECT
+ ir.coin_pub,
+ dd.denominations_serial,
+ ir.age_commitment_hash,
+ ir.denom_sig,
+ dd.coin_val,
+ dd.coin_frac
+ FROM input_rows ir
+ JOIN dd
+ ON dd.denom_pub_hash = ir.denom_pub_hash
+ ON CONFLICT DO NOTHING
+ RETURNING known_coin_id
+ ),--kc
+ exists AS (
+ SELECT
+ CASE
+ WHEN
+ ins.known_coin_id IS NOT NULL
+ THEN
+ FALSE
+ ELSE
+ TRUE
+ END AS existed,
+ ins.known_coin_id,
+ dd.denom_pub_hash,
+ kc.age_commitment_hash
+ FROM input_rows ir
+ LEFT JOIN ins
+ ON ins.coin_pub = ir.coin_pub
+ LEFT JOIN known_coins kc
+ ON kc.coin_pub = ir.coin_pub
+ LEFT JOIN dd
+ ON dd.denom_pub_hash = ir.denom_pub_hash
+ )--exists
+SELECT
+ exists.existed AS existed1,
+ exists.known_coin_id AS known_coin_id1,
+ exists.denom_pub_hash AS denom_pub_hash1,
+ exists.age_commitment_hash AS age_commitment_hash1,
+ (
+ SELECT exists.existed
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash2
+ ) AS existed2,
+ (
+ SELECT exists.known_coin_id
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash2
+ ) AS known_coin_id2,
+ (
+ SELECT exists.denom_pub_hash
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash2
+ ) AS denom_pub_hash2,
+ (
+ SELECT exists.age_commitment_hash
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash2
+ )AS age_commitment_hash2,
+ (
+ SELECT exists.existed
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash3
+ ) AS existed3,
+ (
+ SELECT exists.known_coin_id
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash3
+ ) AS known_coin_id3,
+ (
+ SELECT exists.denom_pub_hash
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash3
+ ) AS denom_pub_hash3,
+ (
+ SELECT exists.age_commitment_hash
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash3
+ )AS age_commitment_hash3,
+ (
+ SELECT exists.existed
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash4
+ ) AS existed4,
+ (
+ SELECT exists.known_coin_id
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash4
+ ) AS known_coin_id4,
+ (
+ SELECT exists.denom_pub_hash
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash4
+ ) AS denom_pub_hash4,
+ (
+ SELECT exists.age_commitment_hash
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash4
+ )AS age_commitment_hash4
+FROM exists;
+
+RETURN;
+END $$;
+
+
+CREATE OR REPLACE FUNCTION exchange_do_batch2_known_coin(
+ IN in_coin_pub1 BYTEA,
+ IN in_denom_pub_hash1 BYTEA,
+ IN in_h_age_commitment1 BYTEA,
+ IN in_denom_sig1 BYTEA,
+ IN in_coin_pub2 BYTEA,
+ IN in_denom_pub_hash2 BYTEA,
+ IN in_h_age_commitment2 BYTEA,
+ IN in_denom_sig2 BYTEA,
+ OUT existed1 BOOLEAN,
+ OUT existed2 BOOLEAN,
+ OUT known_coin_id1 INT8,
+ OUT known_coin_id2 INT8,
+ OUT denom_pub_hash1 BYTEA,
+ OUT denom_pub_hash2 BYTEA,
+ OUT age_commitment_hash1 BYTEA,
+ OUT age_commitment_hash2 BYTEA)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+WITH dd AS (
+SELECT
+ denominations_serial,
+ coin_val, coin_frac
+ FROM denominations
+ WHERE denom_pub_hash
+ IN
+ (in_denom_pub_hash1,
+ in_denom_pub_hash2)
+ ),--dd
+ input_rows AS (
+ VALUES
+ (in_coin_pub1,
+ in_denom_pub_hash1,
+ in_h_age_commitment1,
+ in_denom_sig1),
+ (in_coin_pub2,
+ in_denom_pub_hash2,
+ in_h_age_commitment2,
+ in_denom_sig2)
+ ),--ir
+ ins AS (
+ INSERT INTO known_coins (
+ coin_pub,
+ denominations_serial,
+ age_commitment_hash,
+ denom_sig,
+ remaining_val,
+ remaining_frac
+ )
+ SELECT
+ ir.coin_pub,
+ dd.denominations_serial,
+ ir.age_commitment_hash,
+ ir.denom_sig,
+ dd.coin_val,
+ dd.coin_frac
+ FROM input_rows ir
+ JOIN dd
+ ON dd.denom_pub_hash = ir.denom_pub_hash
+ ON CONFLICT DO NOTHING
+ RETURNING known_coin_id
+ ),--kc
+ exists AS (
+ SELECT
+ CASE
+ WHEN ins.known_coin_id IS NOT NULL
+ THEN
+ FALSE
+ ELSE
+ TRUE
+ END AS existed,
+ ins.known_coin_id,
+ dd.denom_pub_hash,
+ kc.age_commitment_hash
+ FROM input_rows ir
+ LEFT JOIN ins
+ ON ins.coin_pub = ir.coin_pub
+ LEFT JOIN known_coins kc
+ ON kc.coin_pub = ir.coin_pub
+ LEFT JOIN dd
+ ON dd.denom_pub_hash = ir.denom_pub_hash
+ )--exists
+SELECT
+ exists.existed AS existed1,
+ exists.known_coin_id AS known_coin_id1,
+ exists.denom_pub_hash AS denom_pub_hash1,
+ exists.age_commitment_hash AS age_commitment_hash1,
+ (
+ SELECT exists.existed
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash2
+ ) AS existed2,
+ (
+ SELECT exists.known_coin_id
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash2
+ ) AS known_coin_id2,
+ (
+ SELECT exists.denom_pub_hash
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash2
+ ) AS denom_pub_hash2,
+ (
+ SELECT exists.age_commitment_hash
+ FROM exists
+ WHERE exists.denom_pub_hash = in_denom_pub_hash2
+ )AS age_commitment_hash2
+FROM exists;
+
+RETURN;
+END $$;
+
+
+CREATE OR REPLACE FUNCTION exchange_do_batch1_known_coin(
+ IN in_coin_pub1 BYTEA,
+ IN in_denom_pub_hash1 BYTEA,
+ IN in_h_age_commitment1 BYTEA,
+ IN in_denom_sig1 BYTEA,
+ OUT existed1 BOOLEAN,
+ OUT known_coin_id1 INT8,
+ OUT denom_pub_hash1 BYTEA,
+ OUT age_commitment_hash1 BYTEA)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+WITH dd AS (
+SELECT
+ denominations_serial,
+ coin_val, coin_frac
+ FROM denominations
+ WHERE denom_pub_hash
+ IN
+ (in_denom_pub_hash1,
+ in_denom_pub_hash2)
+ ),--dd
+ input_rows AS (
+ VALUES
+ (in_coin_pub1,
+ in_denom_pub_hash1,
+ in_h_age_commitment1,
+ in_denom_sig1)
+ ),--ir
+ ins AS (
+ INSERT INTO known_coins (
+ coin_pub,
+ denominations_serial,
+ age_commitment_hash,
+ denom_sig,
+ remaining_val,
+ remaining_frac
+ )
+ SELECT
+ ir.coin_pub,
+ dd.denominations_serial,
+ ir.age_commitment_hash,
+ ir.denom_sig,
+ dd.coin_val,
+ dd.coin_frac
+ FROM input_rows ir
+ JOIN dd
+ ON dd.denom_pub_hash = ir.denom_pub_hash
+ ON CONFLICT DO NOTHING
+ RETURNING known_coin_id
+ ),--kc
+ exists AS (
+ SELECT
+ CASE
+ WHEN ins.known_coin_id IS NOT NULL
+ THEN
+ FALSE
+ ELSE
+ TRUE
+ END AS existed,
+ ins.known_coin_id,
+ dd.denom_pub_hash,
+ kc.age_commitment_hash
+ FROM input_rows ir
+ LEFT JOIN ins
+ ON ins.coin_pub = ir.coin_pub
+ LEFT JOIN known_coins kc
+ ON kc.coin_pub = ir.coin_pub
+ LEFT JOIN dd
+ ON dd.denom_pub_hash = ir.denom_pub_hash
+ )--exists
+SELECT
+ exists.existed AS existed1,
+ exists.known_coin_id AS known_coin_id1,
+ exists.denom_pub_hash AS denom_pub_hash1,
+ exists.age_commitment_hash AS age_commitment_hash1
+FROM exists;
+
+RETURN;
+END $$;
+
+/*** Experiment using a loop ***/
+/*
+CREATE OR REPLACE FUNCTION exchange_do_batch2_known_coin(
+ IN in_coin_pub1 BYTEA,
+ IN in_denom_pub_hash1 TEXT,
+ IN in_h_age_commitment1 TEXT,
+ IN in_denom_sig1 TEXT,
+ IN in_coin_pub2 BYTEA,
+ IN in_denom_pub_hash2 TEXT,
+ IN in_h_age_commitment2 TEXT,
+ IN in_denom_sig2 TEXT,
+ OUT existed1 BOOLEAN,
+ OUT existed2 BOOLEAN,
+ OUT known_coin_id1 INT8,
+ OUT known_coin_id2 INT8,
+ OUT denom_pub_hash1 TEXT,
+ OUT denom_pub_hash2 TEXT,
+ OUT age_commitment_hash1 TEXT,
+ OUT age_commitment_hash2 TEXT)
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ ins_values RECORD;
+BEGIN
+ FOR i IN 1..2 LOOP
+ ins_values := (
+ SELECT
+ in_coin_pub1 AS coin_pub,
+ in_denom_pub_hash1 AS denom_pub_hash,
+ in_h_age_commitment1 AS age_commitment_hash,
+ in_denom_sig1 AS denom_sig
+ WHERE i = 1
+ UNION
+ SELECT
+ in_coin_pub2 AS coin_pub,
+ in_denom_pub_hash2 AS denom_pub_hash,
+ in_h_age_commitment2 AS age_commitment_hash,
+ in_denom_sig2 AS denom_sig
+ WHERE i = 2
+ );
+ WITH dd (denominations_serial, coin_val, coin_frac) AS (
+ SELECT denominations_serial, coin_val, coin_frac
+ FROM denominations
+ WHERE denom_pub_hash = ins_values.denom_pub_hash
+ ),
+ input_rows(coin_pub) AS (
+ VALUES (ins_values.coin_pub)
+ ),
+ ins AS (
+ INSERT INTO known_coins (
+ coin_pub,
+ denominations_serial,
+ age_commitment_hash,
+ denom_sig,
+ remaining_val,
+ remaining_frac
+ ) SELECT
+ input_rows.coin_pub,
+ dd.denominations_serial,
+ ins_values.age_commitment_hash,
+ ins_values.denom_sig,
+ coin_val,
+ coin_frac
+ FROM dd
+ CROSS JOIN input_rows
+ ON CONFLICT DO NOTHING
+ RETURNING known_coin_id, denom_pub_hash
+ )
+ SELECT
+ CASE i
+ WHEN 1 THEN
+ COALESCE(ins.known_coin_id, 0) <> 0 AS existed1,
+ ins.known_coin_id AS known_coin_id1,
+ ins.denom_pub_hash AS denom_pub_hash1,
+ ins.age_commitment_hash AS age_commitment_hash1
+ WHEN 2 THEN
+ COALESCE(ins.known_coin_id, 0) <> 0 AS existed2,
+ ins.known_coin_id AS known_coin_id2,
+ ins.denom_pub_hash AS denom_pub_hash2,
+ ins.age_commitment_hash AS age_commitment_hash2
+ END
+ FROM ins;
+ END LOOP;
+END;
+$$;*/
diff --git a/src/exchangedb/exchange_do_batch_reserves_in_insert.sql b/src/exchangedb/exchange_do_batch_reserves_in_insert.sql
deleted file mode 100644
index 5ee819229..000000000
--- a/src/exchangedb/exchange_do_batch_reserves_in_insert.sql
+++ /dev/null
@@ -1,120 +0,0 @@
---
--- This file is part of TALER
--- Copyright (C) 2014--2022 Taler Systems SA
---
--- 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, see
---
-
-DROP FUNCTION IF EXISTS exchange_do_batch_reserves_in_insert;
-CREATE OR REPLACE FUNCTION exchange_do_batch_reserves_in_insert(
- IN in_reserve_pub BYTEA,
- IN in_expiration_date INT8,
- IN in_gc_date INT8,
- IN in_wire_ref INT8,
- IN in_credit_val INT8,
- IN in_credit_frac INT4,
- IN in_exchange_account_name VARCHAR,
- IN in_execution_date INT8,
- IN in_wire_source_h_payto BYTEA, ---h_payto
- IN in_payto_uri VARCHAR,
- IN in_reserve_expiration INT8,
- IN in_notify text,
- OUT out_reserve_found BOOLEAN,
- OUT transaction_duplicate BOOLEAN,
- OUT ruuid INT8)
-LANGUAGE plpgsql
-AS $$
-DECLARE
- curs refcursor;
-DECLARE
- i RECORD;
-DECLARE
- curs_trans refcursor;
-BEGIN
- ruuid = 0;
- out_reserve_found = TRUE;
- transaction_duplicate = TRUE;
-
---SIMPLE INSERT ON CONFLICT DO NOTHING
- INSERT INTO wire_targets
- (wire_target_h_payto
- ,payto_uri)
- VALUES
- (in_wire_source_h_payto
- ,in_payto_uri)
- ON CONFLICT DO NOTHING;
-
- OPEN curs FOR
- WITH reserve_changes AS (
- INSERT INTO reserves
- (reserve_pub
- ,current_balance_val
- ,current_balance_frac
- ,expiration_date
- ,gc_date)
- VALUES
- (in_reserve_pub
- ,in_credit_val
- ,in_credit_frac
- ,in_expiration_date
- ,in_gc_date)
- ON CONFLICT DO NOTHING
- RETURNING reserve_uuid, reserve_pub)
- SELECT * FROM reserve_changes;
- FETCH FROM curs INTO i;
- IF FOUND
- THEN
- -- We made a change, so the reserve did not previously exist.
- IF in_reserve_pub = i.reserve_pub
- THEN
- out_reserve_found = FALSE;
- ruuid = i.reserve_uuid;
- END IF;
- END IF;
- CLOSE curs;
-
- OPEN curs_trans FOR
- WITH reserve_transaction AS(
- INSERT INTO reserves_in
- (reserve_pub
- ,wire_reference
- ,credit_val
- ,credit_frac
- ,exchange_account_section
- ,wire_source_h_payto
- ,execution_date)
- VALUES
- (in_reserve_pub
- ,in_wire_ref
- ,in_credit_val
- ,in_credit_frac
- ,in_exchange_account_name
- ,in_wire_source_h_payto
- ,in_execution_date)
- ON CONFLICT DO NOTHING
- RETURNING reserve_pub)
- SELECT * FROM reserve_transaction;
- FETCH FROM curs_trans INTO i;
- IF FOUND
- THEN
- IF i.reserve_pub = in_reserve_pub
- THEN
- -- HAPPY PATH THERE IS NO DUPLICATE TRANS
- transaction_duplicate = FALSE;
- EXECUTE FORMAT (
- 'NOTIFY %s'
- ,in_notify);
- END IF;
- END IF;
- CLOSE curs_trans;
- RETURN;
-END $$;
diff --git a/src/exchangedb/exchange_do_deposit.sql b/src/exchangedb/exchange_do_deposit.sql
index a2f5ba53a..6e522b354 100644
--- a/src/exchangedb/exchange_do_deposit.sql
+++ b/src/exchangedb/exchange_do_deposit.sql
@@ -123,6 +123,7 @@ THEN
-- Deposit exists, but with differences. Not allowed.
out_balance_ok=FALSE;
out_conflict=TRUE;
+ out_exchange_timestamp=0;
RETURN;
END IF;
diff --git a/src/exchangedb/exchange_do_reserves_in_insert.sql b/src/exchangedb/exchange_do_reserves_in_insert.sql
new file mode 100644
index 000000000..dffcd8b55
--- /dev/null
+++ b/src/exchangedb/exchange_do_reserves_in_insert.sql
@@ -0,0 +1,965 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2014--2023 Taler Systems SA
+--
+-- 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, see
+--
+
+CREATE OR REPLACE FUNCTION exchange_do_batch_reserves_in_insert(
+ IN in_gc_date INT8,
+ IN in_reserve_expiration INT8,
+ IN in_reserve_pub BYTEA,
+ IN in_wire_ref INT8,
+ IN in_credit_val INT8,
+ IN in_credit_frac INT4,
+ IN in_exchange_account_name VARCHAR,
+ IN in_execution_date INT8,
+ IN in_wire_source_h_payto BYTEA,
+ IN in_payto_uri VARCHAR,
+ IN in_notify TEXT,
+ OUT transaction_duplicate0 BOOLEAN,
+ OUT ruuid0 INT8)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+
+ INSERT INTO wire_targets
+ (wire_target_h_payto
+ ,payto_uri)
+ VALUES
+ (in_wire_source_h_payto
+ ,in_payto_uri)
+ ON CONFLICT DO NOTHING;
+
+ INSERT INTO reserves
+ (reserve_pub
+ ,current_balance_val
+ ,current_balance_frac
+ ,expiration_date
+ ,gc_date)
+ VALUES
+ (in_reserve_pub
+ ,in_credit_val
+ ,in_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date)
+ ON CONFLICT DO NOTHING
+ RETURNING reserve_uuid
+ INTO ruuid0;
+
+ INSERT INTO reserves_in
+ (reserve_pub
+ ,wire_reference
+ ,credit_val
+ ,credit_frac
+ ,exchange_account_section
+ ,wire_source_h_payto
+ ,execution_date)
+ VALUES
+ (in_reserve_pub
+ ,in_wire_ref
+ ,in_credit_val
+ ,in_credit_frac
+ ,in_exchange_account_name
+ ,in_wire_source_h_payto
+ ,in_execution_date)
+ ON CONFLICT DO NOTHING;
+
+ transaction_duplicate0 = NOT FOUND;
+ IF FOUND
+ THEN
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in_notify);
+ END IF;
+ RETURN;
+END $$;
+
+
+CREATE OR REPLACE FUNCTION exchange_do_batch2_reserves_insert(
+ IN in_gc_date INT8,
+ IN in_reserve_expiration INT8,
+ IN in0_reserve_pub BYTEA,
+ IN in0_wire_ref INT8,
+ IN in0_credit_val INT8,
+ IN in0_credit_frac INT4,
+ IN in0_exchange_account_name VARCHAR,
+ IN in0_execution_date INT8,
+ IN in0_wire_source_h_payto BYTEA,
+ IN in0_payto_uri VARCHAR,
+ IN in0_notify TEXT,
+ IN in1_reserve_pub BYTEA,
+ IN in1_wire_ref INT8,
+ IN in1_credit_val INT8,
+ IN in1_credit_frac INT4,
+ IN in1_exchange_account_name VARCHAR,
+ IN in1_execution_date INT8,
+ IN in1_wire_source_h_payto BYTEA,
+ IN in1_payto_uri VARCHAR,
+ IN in1_notify TEXT,
+ OUT transaction_duplicate0 BOOLEAN,
+ OUT transaction_duplicate1 BOOLEAN,
+ OUT ruuid0 INT8,
+ OUT ruuid1 INT8)
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ curs_reserve_exist REFCURSOR;
+DECLARE
+ k INT8;
+DECLARE
+ curs_transaction_exist REFCURSOR;
+DECLARE
+ i RECORD;
+BEGIN
+ transaction_duplicate0 = TRUE;
+ transaction_duplicate1 = TRUE;
+
+ INSERT INTO wire_targets
+ (wire_target_h_payto
+ ,payto_uri)
+ VALUES
+ (in0_wire_source_h_payto
+ ,in0_payto_uri),
+ (in1_wire_source_h_payto
+ ,in1_payto_uri)
+ ON CONFLICT DO NOTHING;
+
+ OPEN curs_reserve_exist FOR
+ WITH reserve_changes AS (
+ INSERT INTO reserves
+ (reserve_pub
+ ,current_balance_val
+ ,current_balance_frac
+ ,expiration_date
+ ,gc_date)
+ VALUES
+ (in0_reserve_pub
+ ,in0_credit_val
+ ,in0_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in1_reserve_pub
+ ,in1_credit_val
+ ,in1_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date)
+ ON CONFLICT DO NOTHING
+ RETURNING reserve_uuid, reserve_pub)
+ SELECT reserve_uuid, reserve_pub FROM reserve_changes;
+
+ k=0;
+ <> LOOP
+ FETCH FROM curs_reserve_exist INTO i;
+ IF NOT FOUND
+ THEN
+ EXIT loop_reserve;
+ END IF;
+
+ <> LOOP
+ CASE k
+ WHEN 0 THEN
+ k = k + 1;
+ IF in0_reserve_pub = i.reserve_pub
+ THEN
+ ruuid0 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 1 THEN
+ IF in1_reserve_pub = i.reserve_pub
+ THEN
+ ruuid1 = i.reserve_uuid;
+ END IF;
+ EXIT loop_reserve;
+ END CASE;
+ END LOOP loop_k;
+ END LOOP loop_reserve;
+
+ CLOSE curs_reserve_exist;
+
+ OPEN curs_transaction_exist FOR
+ WITH reserve_transaction AS (
+ INSERT INTO reserves_in
+ (reserve_pub
+ ,wire_reference
+ ,credit_val
+ ,credit_frac
+ ,exchange_account_section
+ ,wire_source_h_payto
+ ,execution_date)
+ VALUES
+ (in0_reserve_pub
+ ,in0_wire_ref
+ ,in0_credit_val
+ ,in0_credit_frac
+ ,in0_exchange_account_name
+ ,in0_wire_source_h_payto
+ ,in0_execution_date),
+ (in1_reserve_pub
+ ,in1_wire_ref
+ ,in1_credit_val
+ ,in1_credit_frac
+ ,in1_exchange_account_name
+ ,in1_wire_source_h_payto
+ ,in1_execution_date)
+ ON CONFLICT DO NOTHING
+ RETURNING reserve_pub)
+ SELECT reserve_pub FROM reserve_transaction;
+
+ k=0;
+ <> LOOP
+ FETCH FROM curs_transaction_exist INTO i;
+ IF NOT FOUND
+ THEN
+ EXIT loop_transaction;
+ END IF;
+
+ <> LOOP
+ CASE k
+ WHEN 0 THEN
+ k = k + 1;
+ IF in0_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate0 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in0_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 1 THEN
+ IF in1_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate1 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in1_notify);
+ END IF;
+ EXIT loop_transaction;
+ END CASE;
+ END LOOP loop2_k;
+ END LOOP loop_transaction;
+
+ CLOSE curs_transaction_exist;
+
+ RETURN;
+END $$;
+
+
+CREATE OR REPLACE FUNCTION exchange_do_batch4_reserves_insert(
+ IN in_gc_date INT8,
+ IN in_reserve_expiration INT8,
+ IN in0_reserve_pub BYTEA,
+ IN in0_wire_ref INT8,
+ IN in0_credit_val INT8,
+ IN in0_credit_frac INT4,
+ IN in0_exchange_account_name VARCHAR,
+ IN in0_execution_date INT8,
+ IN in0_wire_source_h_payto BYTEA,
+ IN in0_payto_uri VARCHAR,
+ IN in0_notify TEXT,
+ IN in1_reserve_pub BYTEA,
+ IN in1_wire_ref INT8,
+ IN in1_credit_val INT8,
+ IN in1_credit_frac INT4,
+ IN in1_exchange_account_name VARCHAR,
+ IN in1_execution_date INT8,
+ IN in1_wire_source_h_payto BYTEA,
+ IN in1_payto_uri VARCHAR,
+ IN in1_notify TEXT,
+ IN in2_reserve_pub BYTEA,
+ IN in2_wire_ref INT8,
+ IN in2_credit_val INT8,
+ IN in2_credit_frac INT4,
+ IN in2_exchange_account_name VARCHAR,
+ IN in2_execution_date INT8,
+ IN in2_wire_source_h_payto BYTEA,
+ IN in2_payto_uri VARCHAR,
+ IN in2_notify TEXT,
+ IN in3_reserve_pub BYTEA,
+ IN in3_wire_ref INT8,
+ IN in3_credit_val INT8,
+ IN in3_credit_frac INT4,
+ IN in3_exchange_account_name VARCHAR,
+ IN in3_execution_date INT8,
+ IN in3_wire_source_h_payto BYTEA,
+ IN in3_payto_uri VARCHAR,
+ IN in3_notify TEXT,
+ OUT transaction_duplicate0 BOOLEAN,
+ OUT transaction_duplicate1 BOOLEAN,
+ OUT transaction_duplicate2 BOOLEAN,
+ OUT transaction_duplicate3 BOOLEAN,
+ OUT ruuid0 INT8,
+ OUT ruuid1 INT8,
+ OUT ruuid2 INT8,
+ OUT ruuid3 INT8)
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ curs_reserve_exist REFCURSOR;
+DECLARE
+ k INT8;
+DECLARE
+ curs_transaction_exist REFCURSOR;
+DECLARE
+ i RECORD;
+BEGIN
+ transaction_duplicate0=TRUE;
+ transaction_duplicate1=TRUE;
+ transaction_duplicate2=TRUE;
+ transaction_duplicate3=TRUE;
+
+ INSERT INTO wire_targets
+ (wire_target_h_payto
+ ,payto_uri)
+ VALUES
+ (in0_wire_source_h_payto
+ ,in0_payto_uri),
+ (in1_wire_source_h_payto
+ ,in1_payto_uri),
+ (in2_wire_source_h_payto
+ ,in2_payto_uri),
+ (in3_wire_source_h_payto
+ ,in3_payto_uri)
+ ON CONFLICT DO NOTHING;
+
+ OPEN curs_reserve_exist FOR
+ WITH reserve_changes AS (
+ INSERT INTO reserves
+ (reserve_pub
+ ,current_balance_val
+ ,current_balance_frac
+ ,expiration_date
+ ,gc_date)
+ VALUES
+ (in0_reserve_pub
+ ,in0_credit_val
+ ,in0_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in1_reserve_pub
+ ,in1_credit_val
+ ,in1_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in2_reserve_pub
+ ,in2_credit_val
+ ,in2_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in3_reserve_pub
+ ,in3_credit_val
+ ,in3_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date)
+ ON CONFLICT DO NOTHING
+ RETURNING reserve_uuid,reserve_pub)
+ SELECT reserve_uuid, reserve_pub FROM reserve_changes;
+
+ k=0;
+ <> LOOP
+ FETCH FROM curs_reserve_exist INTO i;
+ IF NOT FOUND
+ THEN
+ EXIT loop_reserve;
+ END IF;
+
+ <> LOOP
+ CASE k
+ WHEN 0 THEN
+ k = k + 1;
+ IF in0_reserve_pub = i.reserve_pub
+ THEN
+ ruuid0 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 1 THEN
+ k = k + 1;
+ IF in1_reserve_pub = i.reserve_pub
+ THEN
+ ruuid1 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 2 THEN
+ k = k + 1;
+ IF in2_reserve_pub = i.reserve_pub
+ THEN
+ ruuid2 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 3 THEN
+ IF in3_reserve_pub = i.reserve_pub
+ THEN
+ ruuid3 = i.reserve_uuid;
+ END IF;
+ EXIT loop_reserve;
+ END CASE;
+ END LOOP loop_k;
+ END LOOP loop_reserve;
+
+ CLOSE curs_reserve_exist;
+
+ OPEN curs_transaction_exist FOR
+ WITH reserve_transaction AS (
+ INSERT INTO reserves_in
+ (reserve_pub
+ ,wire_reference
+ ,credit_val
+ ,credit_frac
+ ,exchange_account_section
+ ,wire_source_h_payto
+ ,execution_date)
+ VALUES
+ (in0_reserve_pub
+ ,in0_wire_ref
+ ,in0_credit_val
+ ,in0_credit_frac
+ ,in0_exchange_account_name
+ ,in0_wire_source_h_payto
+ ,in0_execution_date),
+ (in1_reserve_pub
+ ,in1_wire_ref
+ ,in1_credit_val
+ ,in1_credit_frac
+ ,in1_exchange_account_name
+ ,in1_wire_source_h_payto
+ ,in1_execution_date),
+ (in2_reserve_pub
+ ,in2_wire_ref
+ ,in2_credit_val
+ ,in2_credit_frac
+ ,in2_exchange_account_name
+ ,in2_wire_source_h_payto
+ ,in2_execution_date),
+ (in3_reserve_pub
+ ,in3_wire_ref
+ ,in3_credit_val
+ ,in3_credit_frac
+ ,in3_exchange_account_name
+ ,in3_wire_source_h_payto
+ ,in3_execution_date)
+ ON CONFLICT DO NOTHING
+ RETURNING reserve_pub)
+ SELECT reserve_pub FROM reserve_transaction;
+
+ k=0;
+ <> LOOP
+ FETCH FROM curs_transaction_exist INTO i;
+ IF NOT FOUND
+ THEN
+ EXIT loop_transaction;
+ END IF;
+
+ <> LOOP
+ CASE k
+ WHEN 0 THEN
+ k = k + 1;
+ IF in0_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate0 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in0_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 1 THEN
+ k = k + 1;
+ IF in1_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate1 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in1_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 2 THEN
+ k = k + 1;
+ IF in2_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate2 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in2_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 3 THEN
+ IF in3_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate3 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in3_notify);
+ END IF;
+ EXIT loop_transaction;
+ END CASE;
+ END LOOP loop2_k;
+ END LOOP loop_transaction;
+
+ CLOSE curs_transaction_exist;
+
+ RETURN;
+END $$;
+
+
+CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
+ IN in_gc_date INT8,
+ IN in_reserve_expiration INT8,
+ IN in0_reserve_pub BYTEA,
+ IN in0_wire_ref INT8,
+ IN in0_credit_val INT8,
+ IN in0_credit_frac INT4,
+ IN in0_exchange_account_name VARCHAR,
+ IN in0_execution_date INT8,
+ IN in0_wire_source_h_payto BYTEA,
+ IN in0_payto_uri VARCHAR,
+ IN in0_notify TEXT,
+ IN in1_reserve_pub BYTEA,
+ IN in1_wire_ref INT8,
+ IN in1_credit_val INT8,
+ IN in1_credit_frac INT4,
+ IN in1_exchange_account_name VARCHAR,
+ IN in1_execution_date INT8,
+ IN in1_wire_source_h_payto BYTEA,
+ IN in1_payto_uri VARCHAR,
+ IN in1_notify TEXT,
+ IN in2_reserve_pub BYTEA,
+ IN in2_wire_ref INT8,
+ IN in2_credit_val INT8,
+ IN in2_credit_frac INT4,
+ IN in2_exchange_account_name VARCHAR,
+ IN in2_execution_date INT8,
+ IN in2_wire_source_h_payto BYTEA,
+ IN in2_payto_uri VARCHAR,
+ IN in2_notify TEXT,
+ IN in3_reserve_pub BYTEA,
+ IN in3_wire_ref INT8,
+ IN in3_credit_val INT8,
+ IN in3_credit_frac INT4,
+ IN in3_exchange_account_name VARCHAR,
+ IN in3_execution_date INT8,
+ IN in3_wire_source_h_payto BYTEA,
+ IN in3_payto_uri VARCHAR,
+ IN in3_notify TEXT,
+ IN in4_reserve_pub BYTEA,
+ IN in4_wire_ref INT8,
+ IN in4_credit_val INT8,
+ IN in4_credit_frac INT4,
+ IN in4_exchange_account_name VARCHAR,
+ IN in4_execution_date INT8,
+ IN in4_wire_source_h_payto BYTEA,
+ IN in4_payto_uri VARCHAR,
+ IN in4_notify TEXT,
+ IN in5_reserve_pub BYTEA,
+ IN in5_wire_ref INT8,
+ IN in5_credit_val INT8,
+ IN in5_credit_frac INT4,
+ IN in5_exchange_account_name VARCHAR,
+ IN in5_execution_date INT8,
+ IN in5_wire_source_h_payto BYTEA,
+ IN in5_payto_uri VARCHAR,
+ IN in5_notify TEXT,
+ IN in6_reserve_pub BYTEA,
+ IN in6_wire_ref INT8,
+ IN in6_credit_val INT8,
+ IN in6_credit_frac INT4,
+ IN in6_exchange_account_name VARCHAR,
+ IN in6_execution_date INT8,
+ IN in6_wire_source_h_payto BYTEA,
+ IN in6_payto_uri VARCHAR,
+ IN in6_notify TEXT,
+ IN in7_reserve_pub BYTEA,
+ IN in7_wire_ref INT8,
+ IN in7_credit_val INT8,
+ IN in7_credit_frac INT4,
+ IN in7_exchange_account_name VARCHAR,
+ IN in7_execution_date INT8,
+ IN in7_wire_source_h_payto BYTEA,
+ IN in7_payto_uri VARCHAR,
+ IN in7_notify TEXT,
+ OUT transaction_duplicate0 BOOLEAN,
+ OUT transaction_duplicate1 BOOLEAN,
+ OUT transaction_duplicate2 BOOLEAN,
+ OUT transaction_duplicate3 BOOLEAN,
+ OUT transaction_duplicate4 BOOLEAN,
+ OUT transaction_duplicate5 BOOLEAN,
+ OUT transaction_duplicate6 BOOLEAN,
+ OUT transaction_duplicate7 BOOLEAN,
+ OUT ruuid0 INT8,
+ OUT ruuid1 INT8,
+ OUT ruuid2 INT8,
+ OUT ruuid3 INT8,
+ OUT ruuid4 INT8,
+ OUT ruuid5 INT8,
+ OUT ruuid6 INT8,
+ OUT ruuid7 INT8)
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ curs_reserve_exist REFCURSOR;
+DECLARE
+ k INT8;
+DECLARE
+ curs_transaction_exist REFCURSOR;
+DECLARE
+ i RECORD;
+DECLARE
+ r RECORD;
+
+BEGIN
+ transaction_duplicate0=TRUE;
+ transaction_duplicate1=TRUE;
+ transaction_duplicate2=TRUE;
+ transaction_duplicate3=TRUE;
+ transaction_duplicate4=TRUE;
+ transaction_duplicate5=TRUE;
+ transaction_duplicate6=TRUE;
+ transaction_duplicate7=TRUE;
+
+ INSERT INTO wire_targets
+ (wire_target_h_payto
+ ,payto_uri)
+ VALUES
+ (in0_wire_source_h_payto
+ ,in0_payto_uri),
+ (in1_wire_source_h_payto
+ ,in1_payto_uri),
+ (in2_wire_source_h_payto
+ ,in2_payto_uri),
+ (in3_wire_source_h_payto
+ ,in3_payto_uri),
+ (in4_wire_source_h_payto
+ ,in4_payto_uri),
+ (in5_wire_source_h_payto
+ ,in5_payto_uri),
+ (in6_wire_source_h_payto
+ ,in6_payto_uri),
+ (in7_wire_source_h_payto
+ ,in7_payto_uri)
+ ON CONFLICT DO NOTHING;
+
+ OPEN curs_reserve_exist FOR
+ WITH reserve_changes AS (
+ INSERT INTO reserves
+ (reserve_pub
+ ,current_balance_val
+ ,current_balance_frac
+ ,expiration_date
+ ,gc_date)
+ VALUES
+ (in0_reserve_pub
+ ,in0_credit_val
+ ,in0_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in1_reserve_pub
+ ,in1_credit_val
+ ,in1_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in2_reserve_pub
+ ,in2_credit_val
+ ,in2_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in3_reserve_pub
+ ,in3_credit_val
+ ,in3_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in4_reserve_pub
+ ,in4_credit_val
+ ,in4_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in5_reserve_pub
+ ,in5_credit_val
+ ,in5_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in6_reserve_pub
+ ,in6_credit_val
+ ,in6_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date),
+ (in7_reserve_pub
+ ,in7_credit_val
+ ,in7_credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date)
+ ON CONFLICT DO NOTHING
+ RETURNING
+ reserve_uuid
+ ,reserve_pub)
+ SELECT
+ reserve_uuid
+ ,reserve_pub
+ FROM reserve_changes;
+
+ k=0;
+ <> LOOP
+ FETCH FROM curs_reserve_exist INTO i;
+ IF NOT FOUND
+ THEN
+ EXIT loop_reserve;
+ END IF;
+
+ <> LOOP
+ CASE k
+ WHEN 0 THEN
+ k = k + 1;
+ IF in0_reserve_pub = i.reserve_pub
+ THEN
+ ruuid0 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 1 THEN
+ k = k + 1;
+ IF in1_reserve_pub = i.reserve_pub
+ THEN
+ ruuid1 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 2 THEN
+ k = k + 1;
+ IF in2_reserve_pub = i.reserve_pub
+ THEN
+ ruuid2 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 3 THEN
+ k = k + 1;
+ IF in3_reserve_pub = i.reserve_pub
+ THEN
+ ruuid3 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 4 THEN
+ k = k + 1;
+ IF in4_reserve_pub = i.reserve_pub
+ THEN
+ ruuid4 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 5 THEN
+ k = k + 1;
+ IF in5_reserve_pub = i.reserve_pub
+ THEN
+ ruuid5 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 6 THEN
+ k = k + 1;
+ IF in6_reserve_pub = i.reserve_pub
+ THEN
+ ruuid6 = i.reserve_uuid;
+ CONTINUE loop_reserve;
+ END IF;
+ CONTINUE loop_k;
+ WHEN 7 THEN
+ IF in7_reserve_pub = i.reserve_pub
+ THEN
+ ruuid7 = i.reserve_uuid;
+ END IF;
+ EXIT loop_reserve;
+ END CASE;
+ END LOOP loop_k;
+ END LOOP loop_reserve;
+
+ CLOSE curs_reserve_exist;
+
+ OPEN curs_transaction_exist FOR
+ WITH reserve_transaction AS (
+ INSERT INTO reserves_in
+ (reserve_pub
+ ,wire_reference
+ ,credit_val
+ ,credit_frac
+ ,exchange_account_section
+ ,wire_source_h_payto
+ ,execution_date)
+ VALUES
+ (in0_reserve_pub
+ ,in0_wire_ref
+ ,in0_credit_val
+ ,in0_credit_frac
+ ,in0_exchange_account_name
+ ,in0_wire_source_h_payto
+ ,in0_execution_date),
+ (in1_reserve_pub
+ ,in1_wire_ref
+ ,in1_credit_val
+ ,in1_credit_frac
+ ,in1_exchange_account_name
+ ,in1_wire_source_h_payto
+ ,in1_execution_date),
+ (in2_reserve_pub
+ ,in2_wire_ref
+ ,in2_credit_val
+ ,in2_credit_frac
+ ,in2_exchange_account_name
+ ,in2_wire_source_h_payto
+ ,in2_execution_date),
+ (in3_reserve_pub
+ ,in3_wire_ref
+ ,in3_credit_val
+ ,in3_credit_frac
+ ,in3_exchange_account_name
+ ,in3_wire_source_h_payto
+ ,in3_execution_date),
+ (in4_reserve_pub
+ ,in4_wire_ref
+ ,in4_credit_val
+ ,in4_credit_frac
+ ,in4_exchange_account_name
+ ,in4_wire_source_h_payto
+ ,in4_execution_date),
+ (in5_reserve_pub
+ ,in5_wire_ref
+ ,in5_credit_val
+ ,in5_credit_frac
+ ,in5_exchange_account_name
+ ,in5_wire_source_h_payto
+ ,in5_execution_date),
+ (in6_reserve_pub
+ ,in6_wire_ref
+ ,in6_credit_val
+ ,in6_credit_frac
+ ,in6_exchange_account_name
+ ,in6_wire_source_h_payto
+ ,in6_execution_date),
+ (in7_reserve_pub
+ ,in7_wire_ref
+ ,in7_credit_val
+ ,in7_credit_frac
+ ,in7_exchange_account_name
+ ,in7_wire_source_h_payto
+ ,in7_execution_date)
+ ON CONFLICT DO NOTHING
+ RETURNING reserve_pub)
+ SELECT reserve_pub FROM reserve_transaction;
+
+ k=0;
+ <> LOOP
+ FETCH FROM curs_transaction_exist INTO i;
+ IF NOT FOUND
+ THEN
+ EXIT loop_transaction;
+ END IF;
+
+ <> LOOP
+ CASE k
+ WHEN 0 THEN
+ k = k + 1;
+ IF in0_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate0 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in0_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 1 THEN
+ k = k + 1;
+ IF in1_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate1 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in1_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 2 THEN
+ k = k + 1;
+ IF in2_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate2 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in2_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 3 THEN
+ k = k + 1;
+ IF in3_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate3 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in3_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 4 THEN
+ k = k + 1;
+ IF in4_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate4 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in4_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 5 THEN
+ k = k + 1;
+ IF in5_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate5 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in5_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 6 THEN
+ k = k + 1;
+ IF in6_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate6 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in6_notify);
+ CONTINUE loop_transaction;
+ END IF;
+ CONTINUE loop2_k;
+ WHEN 7 THEN
+ IF in7_reserve_pub = i.reserve_pub
+ THEN
+ transaction_duplicate7 = FALSE;
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,in7_notify);
+ END IF;
+ EXIT loop_transaction;
+ END CASE;
+ END LOOP loop2_k;
+ END LOOP loop_transaction;
+
+ CLOSE curs_transaction_exist;
+ RETURN;
+END $$;
diff --git a/src/exchangedb/exchange_get_ready_deposit.sql b/src/exchangedb/exchange_get_ready_deposit.sql
new file mode 100644
index 000000000..4f76463fc
--- /dev/null
+++ b/src/exchangedb/exchange_get_ready_deposit.sql
@@ -0,0 +1,60 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2014--2022 Taler Systems SA
+--
+-- 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, see
+--
+CREATE OR REPLACE FUNCTION exchange_do_get_ready_deposit(
+ IN in_now INT8,
+ IN in_start_shard_now INT8,
+ IN in_end_shard_now INT8,
+ OUT out_payto_uri VARCHAR,
+ OUT out_merchant_pub BYTEA
+)
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ curs CURSOR
+ FOR
+ SELECT
+ coin_pub
+ ,deposit_serial_id
+ ,wire_deadline
+ ,shard
+ FROM deposits_by_ready dbr
+ WHERE wire_deadline <= in_now
+ AND shard >= in_start_shard_now
+ AND shard <=in_end_shard_now
+ ORDER BY
+ wire_deadline ASC
+ ,shard ASC
+ LIMIT 1;
+DECLARE
+ i RECORD;
+BEGIN
+OPEN curs;
+FETCH FROM curs INTO i;
+SELECT
+ payto_uri
+ ,merchant_pub
+ INTO
+ out_payto_uri
+ ,out_merchant_pub
+ FROM deposits
+ JOIN wire_targets wt
+ USING (wire_target_h_payto)
+ WHERE
+ i.coin_pub = coin_pub
+ AND i.deposit_serial_id=deposit_serial_id;
+CLOSE curs;
+RETURN;
+END $$;
diff --git a/src/exchangedb/pg_abort_shard.h b/src/exchangedb/pg_abort_shard.h
index 070b48dab..e52ace5f6 100644
--- a/src/exchangedb/pg_abort_shard.h
+++ b/src/exchangedb/pg_abort_shard.h
@@ -36,7 +36,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_abort_shard (void *cls,
- const char *job_name,
- uint64_t start_row,
+ const char *job_name,
+ uint64_t start_row,
uint64_t end_row);
+
#endif
diff --git a/src/exchangedb/pg_add_denomination_key.c b/src/exchangedb/pg_add_denomination_key.c
index e115a44ec..fa6d92ed6 100644
--- a/src/exchangedb/pg_add_denomination_key.c
+++ b/src/exchangedb/pg_add_denomination_key.c
@@ -56,8 +56,8 @@ TEH_PG_add_denomination_key (
GNUNET_assert (GNUNET_YES ==
TALER_denom_fee_check_currency (meta->value.currency,
&meta->fees));
- /* Used in #postgres_insert_denomination_info() and
- #postgres_add_denomination_key() */
+ /* Used in #postgres_insert_denomination_info() and
+ #postgres_add_denomination_key() */
PREPARE (pg,
"denomination_insert",
"INSERT INTO denominations "
@@ -86,4 +86,3 @@ TEH_PG_add_denomination_key (
"denomination_insert",
iparams);
}
-
diff --git a/src/exchangedb/pg_add_policy_fulfillment_proof.c b/src/exchangedb/pg_add_policy_fulfillment_proof.c
index bb06206ae..103de7ad2 100644
--- a/src/exchangedb/pg_add_policy_fulfillment_proof.c
+++ b/src/exchangedb/pg_add_policy_fulfillment_proof.c
@@ -94,7 +94,7 @@ TEH_PG_add_policy_fulfillment_proof (
GNUNET_PQ_result_spec_end
};
-
+
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"insert_proof_into_policy_fulfillments",
params,
diff --git a/src/exchangedb/pg_batch_ensure_coin_known.c b/src/exchangedb/pg_batch_ensure_coin_known.c
new file mode 100644
index 000000000..e49813064
--- /dev/null
+++ b/src/exchangedb/pg_batch_ensure_coin_known.c
@@ -0,0 +1,470 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ 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, see
+ */
+/**
+ * @file exchangedb/pg_batch_ensure_coin_known.c
+ * @brief Implementation of the batch_ensure_coin_known function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_batch_ensure_coin_known.h"
+#include "pg_helper.h"
+
+
+static enum GNUNET_DB_QueryStatus
+insert1 (struct PostgresClosure *pg,
+ const struct TALER_CoinPublicInfo coin[1],
+ struct TALER_EXCHANGEDB_CoinInfo result[1])
+{
+ enum GNUNET_DB_QueryStatus qs;
+ bool is_denom_pub_hash_null = false;
+ bool is_age_hash_null = false;
+ PREPARE (pg,
+ "batch1_known_coin",
+ "SELECT"
+ " existed1 AS existed"
+ ",known_coin_id1 AS known_coin_id"
+ ",denom_pub_hash1 AS denom_hash"
+ ",age_commitment_hash1 AS h_age_commitment"
+ " FROM exchange_do_batch1_known_coin"
+ " ($1, $2, $3, $4);"
+ );
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash),
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment),
+ TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("existed",
+ &result[0].existed),
+ GNUNET_PQ_result_spec_uint64 ("known_coin_id",
+ &result[0].known_coin_id),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+ &result[0].denom_hash),
+ &is_denom_pub_hash_null),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
+ &result[0].h_age_commitment),
+ &is_age_hash_null),
+ GNUNET_PQ_result_spec_end
+ };
+
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "batch1_known_coin",
+ params,
+ rs);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ GNUNET_break (0);
+ return qs;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ return qs;
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ GNUNET_break (0); /* should be impossible */
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ break; /* continued below */
+ }
+
+ if ( (! is_denom_pub_hash_null) &&
+ (0 != GNUNET_memcmp (&result[0].denom_hash,
+ &coin->denom_pub_hash)) )
+ {
+ GNUNET_break_op (0);
+ result[0].denom_conflict = true;
+ }
+
+ if ( (! is_age_hash_null) &&
+ (0 != GNUNET_memcmp (&result[0].h_age_commitment,
+ &coin->h_age_commitment)) )
+ {
+ GNUNET_break (GNUNET_is_zero (&result[0].h_age_commitment));
+ GNUNET_break_op (0);
+ result[0].age_conflict = true;
+ }
+ return qs;
+}
+
+
+static enum GNUNET_DB_QueryStatus
+insert2 (struct PostgresClosure *pg,
+ const struct TALER_CoinPublicInfo coin[2],
+ struct TALER_EXCHANGEDB_CoinInfo result[2])
+{
+ enum GNUNET_DB_QueryStatus qs;
+ bool is_denom_pub_hash_null = false;
+ bool is_age_hash_null = false;
+ bool is_denom_pub_hash_null2 = false;
+ bool is_age_hash_null2 = false;
+
+ PREPARE (pg,
+ "batch2_known_coin",
+ "SELECT"
+ " existed1 AS existed"
+ ",known_coin_id1 AS known_coin_id"
+ ",denom_pub_hash1 AS denom_hash"
+ ",age_commitment_hash1 AS h_age_commitment"
+ ",existed2 AS existed2"
+ ",known_coin_id2 AS known_coin_id2"
+ ",denom_pub_hash2 AS denom_hash2"
+ ",age_commitment_hash2 AS h_age_commitment2"
+ " FROM exchange_do_batch2_known_coin"
+ " ($1, $2, $3, $4, $5, $6, $7, $8);"
+ );
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash),
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment),
+ TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
+
+ GNUNET_PQ_query_param_auto_from_type (&coin[1].coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&coin[1].denom_pub_hash),
+ GNUNET_PQ_query_param_auto_from_type (&coin[1].h_age_commitment),
+ TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("existed",
+ &result[0].existed),
+ GNUNET_PQ_result_spec_uint64 ("known_coin_id",
+ &result[0].known_coin_id),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+ &result[0].denom_hash),
+ &is_denom_pub_hash_null),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
+ &result[0].h_age_commitment),
+ &is_age_hash_null),
+ GNUNET_PQ_result_spec_bool ("existed2",
+ &result[1].existed),
+ GNUNET_PQ_result_spec_uint64 ("known_coin_id2",
+ &result[1].known_coin_id),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash2",
+ &result[1].denom_hash),
+ &is_denom_pub_hash_null2),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash2",
+ &result[1].h_age_commitment),
+ &is_age_hash_null2),
+ GNUNET_PQ_result_spec_end
+ };
+
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "batch2_known_coin",
+ params,
+ rs);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ GNUNET_break (0);
+ return qs;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ return qs;
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ GNUNET_break (0); /* should be impossible */
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ break; /* continued below */
+ }
+
+ if ( (! is_denom_pub_hash_null) &&
+ (0 != GNUNET_memcmp (&result[0].denom_hash,
+ &coin[0].denom_pub_hash)) )
+ {
+ GNUNET_break_op (0);
+ result[0].denom_conflict = true;
+ }
+
+ if ( (! is_age_hash_null) &&
+ (0 != GNUNET_memcmp (&result[0].h_age_commitment,
+ &coin[0].h_age_commitment)) )
+ {
+ GNUNET_break (GNUNET_is_zero (&result[0].h_age_commitment));
+ GNUNET_break_op (0);
+ result[0].age_conflict = true;
+ }
+ if ( (! is_denom_pub_hash_null2) &&
+ (0 != GNUNET_memcmp (&result[1].denom_hash,
+ &coin[1].denom_pub_hash)) )
+ {
+ GNUNET_break_op (0);
+ result[1].denom_conflict = true;
+ }
+
+ if ( (! is_age_hash_null) &&
+ (0 != GNUNET_memcmp (&result[1].h_age_commitment,
+ &coin[1].h_age_commitment)) )
+ {
+ GNUNET_break (GNUNET_is_zero (&result[1].h_age_commitment));
+ GNUNET_break_op (0);
+ result[1].age_conflict = true;
+ }
+ return qs;
+}
+
+
+static enum GNUNET_DB_QueryStatus
+insert4 (struct PostgresClosure *pg,
+ const struct TALER_CoinPublicInfo coin[4],
+ struct TALER_EXCHANGEDB_CoinInfo result[4])
+{
+ enum GNUNET_DB_QueryStatus qs;
+ bool is_denom_pub_hash_null = false;
+ bool is_age_hash_null = false;
+ bool is_denom_pub_hash_null2 = false;
+ bool is_age_hash_null2 = false;
+ bool is_denom_pub_hash_null3 = false;
+ bool is_age_hash_null3 = false;
+ bool is_denom_pub_hash_null4 = false;
+ bool is_age_hash_null4 = false;
+ PREPARE (pg,
+ "batch4_known_coin",
+ "SELECT"
+ " existed1 AS existed"
+ ",known_coin_id1 AS known_coin_id"
+ ",denom_pub_hash1 AS denom_hash"
+ ",age_commitment_hash1 AS h_age_commitment"
+ ",existed2 AS existed2"
+ ",known_coin_id2 AS known_coin_id2"
+ ",denom_pub_hash2 AS denom_hash2"
+ ",age_commitment_hash2 AS h_age_commitment2"
+ ",existed3 AS existed3"
+ ",known_coin_id3 AS known_coin_id3"
+ ",denom_pub_hash3 AS denom_hash3"
+ ",age_commitment_hash3 AS h_age_commitment3"
+ ",existed4 AS existed4"
+ ",known_coin_id4 AS known_coin_id4"
+ ",denom_pub_hash4 AS denom_hash4"
+ ",age_commitment_hash4 AS h_age_commitment4"
+ " FROM exchange_do_batch2_known_coin"
+ " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);"
+ );
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash),
+ GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment),
+ TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
+
+ GNUNET_PQ_query_param_auto_from_type (&coin[1].coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&coin[1].denom_pub_hash),
+ GNUNET_PQ_query_param_auto_from_type (&coin[1].h_age_commitment),
+ TALER_PQ_query_param_denom_sig (&coin[0].denom_sig),
+
+ GNUNET_PQ_query_param_auto_from_type (&coin[2].coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&coin[2].denom_pub_hash),
+ GNUNET_PQ_query_param_auto_from_type (&coin[2].h_age_commitment),
+ TALER_PQ_query_param_denom_sig (&coin[2].denom_sig),
+
+ GNUNET_PQ_query_param_auto_from_type (&coin[3].coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&coin[3].denom_pub_hash),
+ GNUNET_PQ_query_param_auto_from_type (&coin[3].h_age_commitment),
+ TALER_PQ_query_param_denom_sig (&coin[3].denom_sig),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("existed",
+ &result[0].existed),
+ GNUNET_PQ_result_spec_uint64 ("known_coin_id",
+ &result[0].known_coin_id),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+ &result[0].denom_hash),
+ &is_denom_pub_hash_null),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
+ &result[0].h_age_commitment),
+ &is_age_hash_null),
+ GNUNET_PQ_result_spec_bool ("existed2",
+ &result[1].existed),
+ GNUNET_PQ_result_spec_uint64 ("known_coin_id2",
+ &result[1].known_coin_id),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash2",
+ &result[1].denom_hash),
+ &is_denom_pub_hash_null2),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash2",
+ &result[1].h_age_commitment),
+ &is_age_hash_null2),
+ GNUNET_PQ_result_spec_bool ("existed3",
+ &result[2].existed),
+ GNUNET_PQ_result_spec_uint64 ("known_coin_id3",
+ &result[2].known_coin_id),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash3",
+ &result[2].denom_hash),
+ &is_denom_pub_hash_null3),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash3",
+ &result[2].h_age_commitment),
+ &is_age_hash_null3),
+ GNUNET_PQ_result_spec_bool ("existed4",
+ &result[3].existed),
+ GNUNET_PQ_result_spec_uint64 ("known_coin_id4",
+ &result[3].known_coin_id),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash4",
+ &result[3].denom_hash),
+ &is_denom_pub_hash_null4),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash4",
+ &result[3].h_age_commitment),
+ &is_age_hash_null4),
+ GNUNET_PQ_result_spec_end
+ };
+
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "batch4_known_coin",
+ params,
+ rs);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ GNUNET_break (0);
+ return qs;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ return qs;
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ GNUNET_break (0); /* should be impossible */
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ break; /* continued below */
+ }
+
+ if ( (! is_denom_pub_hash_null) &&
+ (0 != GNUNET_memcmp (&result[0].denom_hash,
+ &coin[0].denom_pub_hash)) )
+ {
+ GNUNET_break_op (0);
+ result[0].denom_conflict = true;
+ }
+ if ( (! is_age_hash_null) &&
+ (0 != GNUNET_memcmp (&result[0].h_age_commitment,
+ &coin[0].h_age_commitment)) )
+ {
+ GNUNET_break (GNUNET_is_zero (&result[0].h_age_commitment));
+ GNUNET_break_op (0);
+ result[0].age_conflict = true;
+ }
+
+ if ( (! is_denom_pub_hash_null2) &&
+ (0 != GNUNET_memcmp (&result[1].denom_hash,
+ &coin[1].denom_pub_hash)) )
+ {
+ GNUNET_break_op (0);
+ result[1].denom_conflict = true;
+ }
+ if ( (! is_age_hash_null2) &&
+ (0 != GNUNET_memcmp (&result[1].h_age_commitment,
+ &coin[1].h_age_commitment)) )
+ {
+ GNUNET_break (GNUNET_is_zero (&result[1].h_age_commitment));
+ GNUNET_break_op (0);
+ result[1].age_conflict = true;
+ }
+
+ if ( (! is_denom_pub_hash_null3) &&
+ (0 != GNUNET_memcmp (&result[2].denom_hash,
+ &coin[2].denom_pub_hash)) )
+ {
+ GNUNET_break_op (0);
+ result[2].denom_conflict = true;
+ }
+ if ( (! is_age_hash_null3) &&
+ (0 != GNUNET_memcmp (&result[2].h_age_commitment,
+ &coin[2].h_age_commitment)) )
+ {
+ GNUNET_break (GNUNET_is_zero (&result[2].h_age_commitment));
+ GNUNET_break_op (0);
+ result[2].age_conflict = true;
+ }
+
+ if ( (! is_denom_pub_hash_null4) &&
+ (0 != GNUNET_memcmp (&result[3].denom_hash,
+ &coin[3].denom_pub_hash)) )
+ {
+ GNUNET_break_op (0);
+ result[3].denom_conflict = true;
+ }
+ if ( (! is_age_hash_null4) &&
+ (0 != GNUNET_memcmp (&result[3].h_age_commitment,
+ &coin[3].h_age_commitment)) )
+ {
+ GNUNET_break (GNUNET_is_zero (&result[3].h_age_commitment));
+ GNUNET_break_op (0);
+ result[3].age_conflict = true;
+ }
+ return qs;
+}
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_batch_ensure_coin_known (
+ void *cls,
+ const struct TALER_CoinPublicInfo *coin,
+ struct TALER_EXCHANGEDB_CoinInfo *result,
+ unsigned int coin_length,
+ unsigned int batch_size)
+{
+ struct PostgresClosure *pg = cls;
+ enum GNUNET_DB_QueryStatus qs = 0;
+ unsigned int i = 0;
+
+ while ( (qs >= 0) &&
+ (i < coin_length) )
+ {
+ unsigned int bs = GNUNET_MIN (batch_size,
+ coin_length - i);
+ if (bs >= 4)
+ {
+ qs = insert4 (pg,
+ &coin[i],
+ &result[i]);
+ i += 4;
+ continue;
+ }
+ switch (bs)
+ {
+ case 3:
+ case 2:
+ qs = insert2 (pg,
+ &coin[i],
+ &result[i]);
+ i += 2;
+ break;
+ case 1:
+ qs = insert1 (pg,
+ &coin[i],
+ &result[i]);
+ i += 1;
+ break;
+ case 0:
+ GNUNET_assert (0);
+ break;
+ }
+ } /* end while */
+ if (qs < 0)
+ return qs;
+ return i;
+}
diff --git a/src/exchangedb/pg_batch_ensure_coin_known.h b/src/exchangedb/pg_batch_ensure_coin_known.h
new file mode 100644
index 000000000..2c53676d9
--- /dev/null
+++ b/src/exchangedb/pg_batch_ensure_coin_known.h
@@ -0,0 +1,47 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022, 2023 Taler Systems SA
+
+ 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, see
+ */
+/**
+ * @file exchangedb/pg_batch_ensure_coin_known.h
+ * @brief implementation of the batch_ensure_coin_known function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef PG_BATCH_ENSURE_COIN_KNOWN_H
+#define PG_BATCH_ENSURE_COIN_KNOWN_H
+
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_exchangedb_plugin.h"
+
+
+/**
+ * Make sure the array of given @a coin is known to the database.
+ *
+ * @param cls database connection plugin state
+ * @param coin array of coins that must be made known
+ * @param[out] result array where to store information about each coin
+ * @param coin_length length of the @a coin and @a result arraysf
+ * @param batch_size desired (maximum) batch size
+ * @return database transaction status, non-negative on success
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_batch_ensure_coin_known (
+ void *cls,
+ const struct TALER_CoinPublicInfo *coin,
+ struct TALER_EXCHANGEDB_CoinInfo *result,
+ unsigned int coin_length,
+ unsigned int batch_size);
+
+#endif
diff --git a/src/exchangedb/pg_begin_revolving_shard.c b/src/exchangedb/pg_begin_revolving_shard.c
index 888d7fd20..86cdf80fd 100644
--- a/src/exchangedb/pg_begin_revolving_shard.c
+++ b/src/exchangedb/pg_begin_revolving_shard.c
@@ -30,11 +30,11 @@
enum GNUNET_DB_QueryStatus
TEH_PG_begin_revolving_shard (void *cls,
- const char *job_name,
- uint32_t shard_size,
- uint32_t shard_limit,
- uint32_t *start_row,
- uint32_t *end_row)
+ const char *job_name,
+ uint32_t shard_size,
+ uint32_t shard_limit,
+ uint32_t *start_row,
+ uint32_t *end_row)
{
struct PostgresClosure *pg = cls;
@@ -45,7 +45,7 @@ TEH_PG_begin_revolving_shard (void *cls,
{
if (GNUNET_OK !=
TEH_PG_start (pg,
- "begin_revolving_shard"))
+ "begin_revolving_shard"))
{
GNUNET_break (0);
return GNUNET_DB_STATUS_HARD_ERROR;
@@ -64,15 +64,15 @@ TEH_PG_begin_revolving_shard (void *cls,
&last_end),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_begin_revolving_shard() */
- PREPARE(pg,
- "get_last_revolving_shard",
- "SELECT"
- " end_row"
- " FROM revolving_work_shards"
- " WHERE job_name=$1"
- " ORDER BY end_row DESC"
- " LIMIT 1;");
+ /* Used in #postgres_begin_revolving_shard() */
+ PREPARE (pg,
+ "get_last_revolving_shard",
+ "SELECT"
+ " end_row"
+ " FROM revolving_work_shards"
+ " WHERE job_name=$1"
+ " ORDER BY end_row DESC"
+ " LIMIT 1;");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_last_revolving_shard",
params,
@@ -116,7 +116,7 @@ TEH_PG_begin_revolving_shard (void *cls,
(unsigned long long) *start_row,
(unsigned long long) *end_row);
- /* Used in #postgres_claim_revolving_shard() */
+ /* Used in #postgres_claim_revolving_shard() */
PREPARE (pg,
"create_revolving_shard",
"INSERT INTO revolving_work_shards"
@@ -164,7 +164,7 @@ TEH_PG_begin_revolving_shard (void *cls,
end_row),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_begin_revolving_shard() */
+ /* Used in #postgres_begin_revolving_shard() */
PREPARE (pg,
"get_open_revolving_shard",
"SELECT"
@@ -206,7 +206,7 @@ TEH_PG_begin_revolving_shard (void *cls,
now = GNUNET_TIME_timestamp_get ();
- /* Used in #postgres_begin_revolving_shard() */
+ /* Used in #postgres_begin_revolving_shard() */
PREPARE (pg,
"reclaim_revolving_shard",
"UPDATE revolving_work_shards"
diff --git a/src/exchangedb/pg_begin_revolving_shard.h b/src/exchangedb/pg_begin_revolving_shard.h
index bdbca4f11..0755f886b 100644
--- a/src/exchangedb/pg_begin_revolving_shard.h
+++ b/src/exchangedb/pg_begin_revolving_shard.h
@@ -40,9 +40,10 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_begin_revolving_shard (void *cls,
- const char *job_name,
- uint32_t shard_size,
- uint32_t shard_limit,
- uint32_t *start_row,
+ const char *job_name,
+ uint32_t shard_size,
+ uint32_t shard_limit,
+ uint32_t *start_row,
uint32_t *end_row);
+
#endif
diff --git a/src/exchangedb/pg_begin_shard.h b/src/exchangedb/pg_begin_shard.h
index 39bd834e9..16f19491d 100644
--- a/src/exchangedb/pg_begin_shard.h
+++ b/src/exchangedb/pg_begin_shard.h
@@ -38,10 +38,10 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_begin_shard (void *cls,
- const char *job_name,
- struct GNUNET_TIME_Relative delay,
- uint64_t shard_size,
- uint64_t *start_row,
+ const char *job_name,
+ struct GNUNET_TIME_Relative delay,
+ uint64_t shard_size,
+ uint64_t *start_row,
uint64_t *end_row);
#endif
diff --git a/src/exchangedb/pg_commit.c b/src/exchangedb/pg_commit.c
index f1e61ee34..8c4f87c90 100644
--- a/src/exchangedb/pg_commit.c
+++ b/src/exchangedb/pg_commit.c
@@ -45,7 +45,7 @@ TEH_PG_commit (void *cls)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Committing transaction `%s'\n",
pg->transaction_name);
- /* used in #postgres_commit */
+ /* used in #postgres_commit */
PREPARE (pg,
"do_commit",
"COMMIT");
diff --git a/src/exchangedb/pg_complete_shard.h b/src/exchangedb/pg_complete_shard.h
index 8693f402e..f06c0483b 100644
--- a/src/exchangedb/pg_complete_shard.h
+++ b/src/exchangedb/pg_complete_shard.h
@@ -36,7 +36,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_complete_shard (void *cls,
- const char *job_name,
- uint64_t start_row,
+ const char *job_name,
+ uint64_t start_row,
uint64_t end_row);
+
#endif
diff --git a/src/exchangedb/pg_count_known_coins.c b/src/exchangedb/pg_count_known_coins.c
index 28c4612fc..872965ac9 100644
--- a/src/exchangedb/pg_count_known_coins.c
+++ b/src/exchangedb/pg_count_known_coins.c
@@ -27,8 +27,8 @@
long long
TEH_PG_count_known_coins (void *cls,
- const struct
- TALER_DenominationHashP *denom_pub_hash)
+ const struct
+ TALER_DenominationHashP *denom_pub_hash)
{
struct PostgresClosure *pg = cls;
uint64_t count;
diff --git a/src/exchangedb/pg_count_known_coins.h b/src/exchangedb/pg_count_known_coins.h
index f5dd4f27f..69f07bdf4 100644
--- a/src/exchangedb/pg_count_known_coins.h
+++ b/src/exchangedb/pg_count_known_coins.h
@@ -33,7 +33,7 @@
*/
long long
TEH_PG_count_known_coins (void *cls,
- const struct
+ const struct
TALER_DenominationHashP *denom_pub_hash);
#endif
diff --git a/src/exchangedb/pg_create_aggregation_transient.c b/src/exchangedb/pg_create_aggregation_transient.c
index 4ced9da04..80fba8bf4 100644
--- a/src/exchangedb/pg_create_aggregation_transient.c
+++ b/src/exchangedb/pg_create_aggregation_transient.c
@@ -46,18 +46,18 @@ TEH_PG_create_aggregation_transient (
GNUNET_PQ_query_param_auto_from_type (wtid),
GNUNET_PQ_query_param_end
};
- /* Used in #postgres_create_aggregation_transient() */
+ /* Used in #postgres_create_aggregation_transient() */
PREPARE (pg,
- "create_aggregation_transient",
- "INSERT INTO aggregation_transient"
- " (amount_val"
- " ,amount_frac"
- " ,merchant_pub"
- " ,wire_target_h_payto"
- " ,legitimization_requirement_serial_id"
- " ,exchange_account_section"
- " ,wtid_raw)"
- " VALUES ($1, $2, $3, $4, $5, $6, $7);");
+ "create_aggregation_transient",
+ "INSERT INTO aggregation_transient"
+ " (amount_val"
+ " ,amount_frac"
+ " ,merchant_pub"
+ " ,wire_target_h_payto"
+ " ,legitimization_requirement_serial_id"
+ " ,exchange_account_section"
+ " ,wtid_raw)"
+ " VALUES ($1, $2, $3, $4, $5, $6, $7);");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"create_aggregation_transient",
params);
diff --git a/src/exchangedb/pg_delete_aggregation_transient.c b/src/exchangedb/pg_delete_aggregation_transient.c
index d0622c0f7..63c5c0a23 100644
--- a/src/exchangedb/pg_delete_aggregation_transient.c
+++ b/src/exchangedb/pg_delete_aggregation_transient.c
@@ -48,5 +48,3 @@ TEH_PG_delete_aggregation_transient (
"delete_aggregation_transient",
params);
}
-
-
diff --git a/src/exchangedb/pg_delete_shard_locks.c b/src/exchangedb/pg_delete_shard_locks.c
index e55cf25ff..dbb0f29ac 100644
--- a/src/exchangedb/pg_delete_shard_locks.c
+++ b/src/exchangedb/pg_delete_shard_locks.c
@@ -39,4 +39,3 @@ TEH_PG_delete_shard_locks (void *cls)
return GNUNET_PQ_exec_statements (pg->conn,
es);
}
-
diff --git a/src/exchangedb/pg_do_batch_withdraw.c b/src/exchangedb/pg_do_batch_withdraw.c
index 8ef1be268..3dee20d22 100644
--- a/src/exchangedb/pg_do_batch_withdraw.c
+++ b/src/exchangedb/pg_do_batch_withdraw.c
@@ -60,8 +60,8 @@ TEH_PG_do_batch_withdraw (
pg->legal_reserve_expiration_time));
- /* Used in #postgres_do_batch_withdraw() to
- update the reserve balance and check its status */
+ /* Used in #postgres_do_batch_withdraw() to
+ update the reserve balance and check its status */
PREPARE (pg,
"call_batch_withdraw",
"SELECT "
@@ -75,4 +75,3 @@ TEH_PG_do_batch_withdraw (
params,
rs);
}
-
diff --git a/src/exchangedb/pg_do_batch_withdraw_insert.c b/src/exchangedb/pg_do_batch_withdraw_insert.c
index 8d3aac688..8be18f7cc 100644
--- a/src/exchangedb/pg_do_batch_withdraw_insert.c
+++ b/src/exchangedb/pg_do_batch_withdraw_insert.c
@@ -59,9 +59,9 @@ TEH_PG_do_batch_withdraw_insert (
nonce_reuse),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_do_batch_withdraw_insert() to store
- the signature of a blinded coin with the blinded coin's
- details. */
+ /* Used in #postgres_do_batch_withdraw_insert() to store
+ the signature of a blinded coin with the blinded coin's
+ details. */
PREPARE (pg,
"call_batch_withdraw_insert",
"SELECT "
diff --git a/src/exchangedb/pg_do_deposit.c b/src/exchangedb/pg_do_deposit.c
index c8f25e5bc..f3d0856ac 100644
--- a/src/exchangedb/pg_do_deposit.c
+++ b/src/exchangedb/pg_do_deposit.c
@@ -25,6 +25,8 @@
#include "pg_do_deposit.h"
#include "pg_helper.h"
#include "pg_compute_shard.h"
+
+
enum GNUNET_DB_QueryStatus
TEH_PG_do_deposit (
void *cls,
@@ -69,8 +71,6 @@ TEH_PG_do_deposit (
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_do_deposit() to execute a deposit,
- checking the coin's balance in the process as needed. */
PREPARE (pg,
"call_deposit",
"SELECT "
diff --git a/src/exchangedb/pg_do_melt.c b/src/exchangedb/pg_do_melt.c
index 6f81ff38b..40a54d43b 100644
--- a/src/exchangedb/pg_do_melt.c
+++ b/src/exchangedb/pg_do_melt.c
@@ -63,7 +63,7 @@ TEH_PG_do_melt (
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_do_melt() to melt a coin. */
+ /* Used in #postgres_do_melt() to melt a coin. */
PREPARE (pg,
"call_melt",
"SELECT "
diff --git a/src/exchangedb/pg_do_purse_merge.c b/src/exchangedb/pg_do_purse_merge.c
index 518b66bf6..5d11b0565 100644
--- a/src/exchangedb/pg_do_purse_merge.c
+++ b/src/exchangedb/pg_do_purse_merge.c
@@ -75,7 +75,7 @@ TEH_PG_do_purse_merge (
&h_payto);
GNUNET_free (payto_uri);
}
- /* Used in #postgres_do_purse_merge() */
+ /* Used in #postgres_do_purse_merge() */
PREPARE (pg,
"call_purse_merge",
"SELECT"
diff --git a/src/exchangedb/pg_do_recoup.c b/src/exchangedb/pg_do_recoup.c
index 00f7bdd8b..1f74104ed 100644
--- a/src/exchangedb/pg_do_recoup.c
+++ b/src/exchangedb/pg_do_recoup.c
@@ -70,7 +70,6 @@ TEH_PG_do_recoup (
};
-
PREPARE (pg,
"call_recoup",
"SELECT "
diff --git a/src/exchangedb/pg_do_recoup_refresh.h b/src/exchangedb/pg_do_recoup_refresh.h
index 3ac0f0a07..fbd791d44 100644
--- a/src/exchangedb/pg_do_recoup_refresh.h
+++ b/src/exchangedb/pg_do_recoup_refresh.h
@@ -53,4 +53,5 @@ TEH_PG_do_recoup_refresh (
struct GNUNET_TIME_Timestamp *recoup_timestamp,
bool *recoup_ok,
bool *internal_failure);
+
#endif
diff --git a/src/exchangedb/pg_do_refund.c b/src/exchangedb/pg_do_refund.c
index 1059f9cbb..0b9665c48 100644
--- a/src/exchangedb/pg_do_refund.c
+++ b/src/exchangedb/pg_do_refund.c
@@ -72,7 +72,7 @@ TEH_PG_do_refund (
GNUNET_break (0);
return GNUNET_DB_STATUS_HARD_ERROR;
}
- /* Used in #postgres_do_refund() to refund a deposit. */
+ /* Used in #postgres_do_refund() to refund a deposit. */
PREPARE (pg,
"call_refund",
"SELECT "
diff --git a/src/exchangedb/pg_do_withdraw.c b/src/exchangedb/pg_do_withdraw.c
index 87e4dd1d0..01bbfff5b 100644
--- a/src/exchangedb/pg_do_withdraw.c
+++ b/src/exchangedb/pg_do_withdraw.c
@@ -82,5 +82,3 @@ TEH_PG_do_withdraw (
params,
rs);
}
-
-
diff --git a/src/exchangedb/pg_drain_kyc_alert.c b/src/exchangedb/pg_drain_kyc_alert.c
index d635d95e9..4388334e9 100644
--- a/src/exchangedb/pg_drain_kyc_alert.c
+++ b/src/exchangedb/pg_drain_kyc_alert.c
@@ -28,8 +28,8 @@
enum GNUNET_DB_QueryStatus
TEH_PG_drain_kyc_alert (void *cls,
- uint32_t trigger_type,
- struct TALER_PaytoHashP *h_payto)
+ uint32_t trigger_type,
+ struct TALER_PaytoHashP *h_payto)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
diff --git a/src/exchangedb/pg_drain_kyc_alert.h b/src/exchangedb/pg_drain_kyc_alert.h
index bfaf04892..7425f472d 100644
--- a/src/exchangedb/pg_drain_kyc_alert.h
+++ b/src/exchangedb/pg_drain_kyc_alert.h
@@ -34,7 +34,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_drain_kyc_alert (void *cls,
- uint32_t trigger_type,
+ uint32_t trigger_type,
struct TALER_PaytoHashP *h_payto);
#endif
diff --git a/src/exchangedb/pg_ensure_coin_known.c b/src/exchangedb/pg_ensure_coin_known.c
index 7ad37bf1d..721123fd3 100644
--- a/src/exchangedb/pg_ensure_coin_known.c
+++ b/src/exchangedb/pg_ensure_coin_known.c
@@ -28,10 +28,10 @@
enum TALER_EXCHANGEDB_CoinKnownStatus
TEH_PG_ensure_coin_known (void *cls,
- const struct TALER_CoinPublicInfo *coin,
- uint64_t *known_coin_id,
- struct TALER_DenominationHashP *denom_hash,
- struct TALER_AgeCommitmentHash *h_age_commitment)
+ const struct TALER_CoinPublicInfo *coin,
+ uint64_t *known_coin_id,
+ struct TALER_DenominationHashP *denom_hash,
+ struct TALER_AgeCommitmentHash *h_age_commitment)
{
struct PostgresClosure *pg = cls;
enum GNUNET_DB_QueryStatus qs;
diff --git a/src/exchangedb/pg_ensure_coin_known.h b/src/exchangedb/pg_ensure_coin_known.h
index 76581d4b7..68c101735 100644
--- a/src/exchangedb/pg_ensure_coin_known.h
+++ b/src/exchangedb/pg_ensure_coin_known.h
@@ -37,9 +37,9 @@
*/
enum TALER_EXCHANGEDB_CoinKnownStatus
TEH_PG_ensure_coin_known (void *cls,
- const struct TALER_CoinPublicInfo *coin,
- uint64_t *known_coin_id,
- struct TALER_DenominationHashP *denom_hash,
+ const struct TALER_CoinPublicInfo *coin,
+ uint64_t *known_coin_id,
+ struct TALER_DenominationHashP *denom_hash,
struct TALER_AgeCommitmentHash *h_age_commitment);
#endif
diff --git a/src/exchangedb/pg_event_listen.c b/src/exchangedb/pg_event_listen.c
index c557ed3c5..6e1d32843 100644
--- a/src/exchangedb/pg_event_listen.c
+++ b/src/exchangedb/pg_event_listen.c
@@ -38,10 +38,10 @@
*/
struct GNUNET_DB_EventHandler *
TEH_PG_event_listen (void *cls,
- struct GNUNET_TIME_Relative timeout,
- const struct GNUNET_DB_EventHeaderP *es,
- GNUNET_DB_EventCallback cb,
- void *cb_cls)
+ struct GNUNET_TIME_Relative timeout,
+ const struct GNUNET_DB_EventHeaderP *es,
+ GNUNET_DB_EventCallback cb,
+ void *cb_cls)
{
struct PostgresClosure *pg = cls;
diff --git a/src/exchangedb/pg_event_listen.h b/src/exchangedb/pg_event_listen.h
index 1be140776..7e1e83a0e 100644
--- a/src/exchangedb/pg_event_listen.h
+++ b/src/exchangedb/pg_event_listen.h
@@ -37,9 +37,9 @@
*/
struct GNUNET_DB_EventHandler *
TEH_PG_event_listen (void *cls,
- struct GNUNET_TIME_Relative timeout,
- const struct GNUNET_DB_EventHeaderP *es,
- GNUNET_DB_EventCallback cb,
+ struct GNUNET_TIME_Relative timeout,
+ const struct GNUNET_DB_EventHeaderP *es,
+ GNUNET_DB_EventCallback cb,
void *cb_cls);
#endif
diff --git a/src/exchangedb/pg_event_listen_cancel.c b/src/exchangedb/pg_event_listen_cancel.c
index 5d65827c2..9d776684d 100644
--- a/src/exchangedb/pg_event_listen_cancel.c
+++ b/src/exchangedb/pg_event_listen_cancel.c
@@ -26,10 +26,9 @@
#include "pg_helper.h"
-
void
TEH_PG_event_listen_cancel (void *cls,
- struct GNUNET_DB_EventHandler *eh)
+ struct GNUNET_DB_EventHandler *eh)
{
(void) cls;
diff --git a/src/exchangedb/pg_event_notify.c b/src/exchangedb/pg_event_notify.c
index 577f4acb8..188855775 100644
--- a/src/exchangedb/pg_event_notify.c
+++ b/src/exchangedb/pg_event_notify.c
@@ -28,9 +28,9 @@
void
TEH_PG_event_notify (void *cls,
- const struct GNUNET_DB_EventHeaderP *es,
- const void *extra,
- size_t extra_size)
+ const struct GNUNET_DB_EventHeaderP *es,
+ const void *extra,
+ size_t extra_size)
{
struct PostgresClosure *pg = cls;
diff --git a/src/exchangedb/pg_event_notify.h b/src/exchangedb/pg_event_notify.h
index 3b937cbab..85069659b 100644
--- a/src/exchangedb/pg_event_notify.h
+++ b/src/exchangedb/pg_event_notify.h
@@ -35,8 +35,8 @@
*/
void
TEH_PG_event_notify (void *cls,
- const struct GNUNET_DB_EventHeaderP *es,
- const void *extra,
+ const struct GNUNET_DB_EventHeaderP *es,
+ const void *extra,
size_t extra_size);
#endif
diff --git a/src/exchangedb/pg_find_aggregation_transient.c b/src/exchangedb/pg_find_aggregation_transient.c
index a5f367b5f..ecc6362cf 100644
--- a/src/exchangedb/pg_find_aggregation_transient.c
+++ b/src/exchangedb/pg_find_aggregation_transient.c
@@ -128,7 +128,7 @@ TEH_PG_find_aggregation_transient (
.pg = pg,
.status = GNUNET_OK
};
- /* Used in #postgres_find_aggregation_transient() */
+ /* Used in #postgres_find_aggregation_transient() */
PREPARE (pg,
"find_transient_aggregations",
"SELECT"
diff --git a/src/exchangedb/pg_gc.h b/src/exchangedb/pg_gc.h
index 9e6ffbc3d..803581488 100644
--- a/src/exchangedb/pg_gc.h
+++ b/src/exchangedb/pg_gc.h
@@ -35,4 +35,5 @@
*/
enum GNUNET_GenericReturnValue
TEH_PG_gc (void *cls);
+
#endif
diff --git a/src/exchangedb/pg_get_age_withdraw_info.c b/src/exchangedb/pg_get_age_withdraw_info.c
index 02ccc84ac..754b572c9 100644
--- a/src/exchangedb/pg_get_age_withdraw_info.c
+++ b/src/exchangedb/pg_get_age_withdraw_info.c
@@ -35,6 +35,7 @@ TEH_PG_get_age_withdraw_info (
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (reserve_pub),
GNUNET_PQ_query_param_auto_from_type (ach),
GNUNET_PQ_query_param_end
};
@@ -45,14 +46,12 @@ TEH_PG_get_age_withdraw_info (
&awc->reserve_sig),
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
&awc->reserve_pub),
- GNUNET_PQ_result_spec_uint32 ("max_age",
+ GNUNET_PQ_result_spec_uint16 ("max_age",
&awc->max_age),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
&awc->amount_with_fee),
GNUNET_PQ_result_spec_uint32 ("noreveal_index",
&awc->noreveal_index),
- GNUNET_PQ_result_spec_timestamp ("timtestamp",
- &awc->timestamp),
GNUNET_PQ_result_spec_end
};
@@ -70,9 +69,8 @@ TEH_PG_get_age_withdraw_info (
",amount_with_fee_val"
",amount_with_fee_frac"
",noreveal_index"
- ",timestamp"
" FROM withdraw_age_commitments"
- " WHERE h_commitment=$1;");
+ " WHERE reserve_pub=$1 and h_commitment=$2;");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_age_withdraw_info",
params,
diff --git a/src/exchangedb/pg_get_coin_denomination.c b/src/exchangedb/pg_get_coin_denomination.c
index e82b86aa9..9f9256f6f 100644
--- a/src/exchangedb/pg_get_coin_denomination.c
+++ b/src/exchangedb/pg_get_coin_denomination.c
@@ -49,9 +49,9 @@ TEH_PG_get_coin_denomination (
"Getting coin denomination of coin %s\n",
TALER_B2S (coin_pub));
- /* Used in #postgres_get_coin_denomination() to fetch
- the denomination public key hash for
- a coin known to the exchange. */
+ /* Used in #postgres_get_coin_denomination() to fetch
+ the denomination public key hash for
+ a coin known to the exchange. */
PREPARE (pg,
"get_coin_denomination",
"SELECT"
@@ -67,5 +67,3 @@ TEH_PG_get_coin_denomination (
params,
rs);
}
-
-
diff --git a/src/exchangedb/pg_get_denomination_revocation.c b/src/exchangedb/pg_get_denomination_revocation.c
index 4d29d88c4..5e7a3a322 100644
--- a/src/exchangedb/pg_get_denomination_revocation.c
+++ b/src/exchangedb/pg_get_denomination_revocation.c
@@ -46,15 +46,15 @@ TEH_PG_get_denomination_revocation (
};
PREPARE (pg,
- "denomination_revocation_get",
- "SELECT"
- " master_sig"
- ",denom_revocations_serial_id"
- " FROM denomination_revocations"
- " WHERE denominations_serial="
- " (SELECT denominations_serial"
- " FROM denominations"
- " WHERE denom_pub_hash=$1);");
+ "denomination_revocation_get",
+ "SELECT"
+ " master_sig"
+ ",denom_revocations_serial_id"
+ " FROM denomination_revocations"
+ " WHERE denominations_serial="
+ " (SELECT denominations_serial"
+ " FROM denominations"
+ " WHERE denom_pub_hash=$1);");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"denomination_revocation_get",
diff --git a/src/exchangedb/pg_get_denomination_revocation.h b/src/exchangedb/pg_get_denomination_revocation.h
index d022c822d..5f7f27227 100644
--- a/src/exchangedb/pg_get_denomination_revocation.h
+++ b/src/exchangedb/pg_get_denomination_revocation.h
@@ -41,4 +41,5 @@ TEH_PG_get_denomination_revocation (
const struct TALER_DenominationHashP *denom_pub_hash,
struct TALER_MasterSignatureP *master_sig,
uint64_t *rowid);
+
#endif
diff --git a/src/exchangedb/pg_get_extension_manifest.h b/src/exchangedb/pg_get_extension_manifest.h
index 3756b7f4c..e8331ad9b 100644
--- a/src/exchangedb/pg_get_extension_manifest.h
+++ b/src/exchangedb/pg_get_extension_manifest.h
@@ -36,6 +36,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_extension_manifest (void *cls,
- const char *extension_name,
+ const char *extension_name,
char **manifest);
+
#endif
diff --git a/src/exchangedb/pg_get_global_fee.c b/src/exchangedb/pg_get_global_fee.c
index 6f6bbafef..990113fed 100644
--- a/src/exchangedb/pg_get_global_fee.c
+++ b/src/exchangedb/pg_get_global_fee.c
@@ -28,14 +28,14 @@
enum GNUNET_DB_QueryStatus
TEH_PG_get_global_fee (void *cls,
- struct GNUNET_TIME_Timestamp date,
- struct GNUNET_TIME_Timestamp *start_date,
- struct GNUNET_TIME_Timestamp *end_date,
- struct TALER_GlobalFeeSet *fees,
- struct GNUNET_TIME_Relative *purse_timeout,
- struct GNUNET_TIME_Relative *history_expiration,
- uint32_t *purse_account_limit,
- struct TALER_MasterSignatureP *master_sig)
+ struct GNUNET_TIME_Timestamp date,
+ struct GNUNET_TIME_Timestamp *start_date,
+ struct GNUNET_TIME_Timestamp *end_date,
+ struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative *purse_timeout,
+ struct GNUNET_TIME_Relative *history_expiration,
+ uint32_t *purse_account_limit,
+ struct TALER_MasterSignatureP *master_sig)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -65,25 +65,25 @@ TEH_PG_get_global_fee (void *cls,
};
- /* Used in #postgres_get_global_fee() */
- PREPARE(pg,
- "get_global_fee",
- "SELECT "
- " start_date"
- ",end_date"
- ",history_fee_val"
- ",history_fee_frac"
- ",account_fee_val"
- ",account_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_timeout"
- ",history_expiration"
- ",purse_account_limit"
- ",master_sig"
- " FROM global_fee"
- " WHERE start_date <= $1"
- " AND end_date > $1;");
+ /* Used in #postgres_get_global_fee() */
+ PREPARE (pg,
+ "get_global_fee",
+ "SELECT "
+ " start_date"
+ ",end_date"
+ ",history_fee_val"
+ ",history_fee_frac"
+ ",account_fee_val"
+ ",account_fee_frac"
+ ",purse_fee_val"
+ ",purse_fee_frac"
+ ",purse_timeout"
+ ",history_expiration"
+ ",purse_account_limit"
+ ",master_sig"
+ " FROM global_fee"
+ " WHERE start_date <= $1"
+ " AND end_date > $1;");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_global_fee",
params,
diff --git a/src/exchangedb/pg_get_global_fee.h b/src/exchangedb/pg_get_global_fee.h
index 0887d54d2..1e7c9e94b 100644
--- a/src/exchangedb/pg_get_global_fee.h
+++ b/src/exchangedb/pg_get_global_fee.h
@@ -40,13 +40,13 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_global_fee (void *cls,
- struct GNUNET_TIME_Timestamp date,
- struct GNUNET_TIME_Timestamp *start_date,
- struct GNUNET_TIME_Timestamp *end_date,
- struct TALER_GlobalFeeSet *fees,
- struct GNUNET_TIME_Relative *purse_timeout,
- struct GNUNET_TIME_Relative *history_expiration,
- uint32_t *purse_account_limit,
+ struct GNUNET_TIME_Timestamp date,
+ struct GNUNET_TIME_Timestamp *start_date,
+ struct GNUNET_TIME_Timestamp *end_date,
+ struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative *purse_timeout,
+ struct GNUNET_TIME_Relative *history_expiration,
+ uint32_t *purse_account_limit,
struct TALER_MasterSignatureP *master_sig);
#endif
diff --git a/src/exchangedb/pg_get_global_fees.c b/src/exchangedb/pg_get_global_fees.c
index 0e1736bd4..e01eb2dab 100644
--- a/src/exchangedb/pg_get_global_fees.c
+++ b/src/exchangedb/pg_get_global_fees.c
@@ -121,11 +121,10 @@ global_fees_cb (void *cls,
}
-
enum GNUNET_DB_QueryStatus
TEH_PG_get_global_fees (void *cls,
- TALER_EXCHANGEDB_GlobalFeeCallback cb,
- void *cb_cls)
+ TALER_EXCHANGEDB_GlobalFeeCallback cb,
+ void *cb_cls)
{
struct PostgresClosure *pg = cls;
struct GNUNET_TIME_Timestamp date
@@ -144,7 +143,7 @@ TEH_PG_get_global_fees (void *cls,
.status = GNUNET_OK
};
- /* Used in #postgres_get_global_fees() */
+ /* Used in #postgres_get_global_fees() */
PREPARE (pg,
"get_global_fees",
"SELECT "
@@ -169,7 +168,3 @@ TEH_PG_get_global_fees (void *cls,
&global_fees_cb,
&gctx);
}
-
-
-
-
diff --git a/src/exchangedb/pg_get_global_fees.h b/src/exchangedb/pg_get_global_fees.h
index c8f6f02c2..80c9b812f 100644
--- a/src/exchangedb/pg_get_global_fees.h
+++ b/src/exchangedb/pg_get_global_fees.h
@@ -35,6 +35,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_global_fees (void *cls,
- TALER_EXCHANGEDB_GlobalFeeCallback cb,
+ TALER_EXCHANGEDB_GlobalFeeCallback cb,
void *cb_cls);
+
#endif
diff --git a/src/exchangedb/pg_get_known_coin.c b/src/exchangedb/pg_get_known_coin.c
index fe5c683bc..bab48c119 100644
--- a/src/exchangedb/pg_get_known_coin.c
+++ b/src/exchangedb/pg_get_known_coin.c
@@ -27,8 +27,8 @@
enum GNUNET_DB_QueryStatus
TEH_PG_get_known_coin (void *cls,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- struct TALER_CoinPublicInfo *coin_info)
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct TALER_CoinPublicInfo *coin_info)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -51,9 +51,9 @@ TEH_PG_get_known_coin (void *cls,
"Getting known coin data for coin %s\n",
TALER_B2S (coin_pub));
coin_info->coin_pub = *coin_pub;
- /* Used in #postgres_get_known_coin() to fetch
- the denomination public key and signature for
- a coin known to the exchange. */
+ /* Used in #postgres_get_known_coin() to fetch
+ the denomination public key and signature for
+ a coin known to the exchange. */
PREPARE (pg,
"get_known_coin",
"SELECT"
diff --git a/src/exchangedb/pg_get_known_coin.h b/src/exchangedb/pg_get_known_coin.h
index d7f55b33c..c34bd2a97 100644
--- a/src/exchangedb/pg_get_known_coin.h
+++ b/src/exchangedb/pg_get_known_coin.h
@@ -34,7 +34,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_known_coin (void *cls,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_CoinPublicInfo *coin_info);
#endif
diff --git a/src/exchangedb/pg_get_melt.c b/src/exchangedb/pg_get_melt.c
index f239c605b..8e5685ec3 100644
--- a/src/exchangedb/pg_get_melt.c
+++ b/src/exchangedb/pg_get_melt.c
@@ -28,9 +28,9 @@
enum GNUNET_DB_QueryStatus
TEH_PG_get_melt (void *cls,
- const struct TALER_RefreshCommitmentP *rc,
- struct TALER_EXCHANGEDB_Melt *melt,
- uint64_t *melt_serial_id)
+ const struct TALER_RefreshCommitmentP *rc,
+ struct TALER_EXCHANGEDB_Melt *melt,
+ uint64_t *melt_serial_id)
{
struct PostgresClosure *pg = cls;
bool h_age_commitment_is_null;
@@ -66,8 +66,8 @@ TEH_PG_get_melt (void *cls,
0,
sizeof (melt->session.coin.denom_sig));
- /* Used in #postgres_get_melt() to fetch
- high-level information about a melt operation */
+ /* Used in #postgres_get_melt() to fetch
+ high-level information about a melt operation */
PREPARE (pg,
"get_melt",
/* "SELECT"
diff --git a/src/exchangedb/pg_get_melt.h b/src/exchangedb/pg_get_melt.h
index 73d757a05..269960bad 100644
--- a/src/exchangedb/pg_get_melt.h
+++ b/src/exchangedb/pg_get_melt.h
@@ -37,8 +37,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_melt (void *cls,
- const struct TALER_RefreshCommitmentP *rc,
- struct TALER_EXCHANGEDB_Melt *melt,
+ const struct TALER_RefreshCommitmentP *rc,
+ struct TALER_EXCHANGEDB_Melt *melt,
uint64_t *melt_serial_id);
#endif
diff --git a/src/exchangedb/pg_get_old_coin_by_h_blind.c b/src/exchangedb/pg_get_old_coin_by_h_blind.c
index 385c3f1d1..dcce7b32f 100644
--- a/src/exchangedb/pg_get_old_coin_by_h_blind.c
+++ b/src/exchangedb/pg_get_old_coin_by_h_blind.c
@@ -26,7 +26,6 @@
#include "pg_helper.h"
-
enum GNUNET_DB_QueryStatus
TEH_PG_get_old_coin_by_h_blind (
void *cls,
@@ -47,7 +46,7 @@ TEH_PG_get_old_coin_by_h_blind (
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_get_old_coin_by_h_blind() */
+ /* Used in #postgres_get_old_coin_by_h_blind() */
PREPARE (pg,
"old_coin_by_h_blind",
"SELECT"
diff --git a/src/exchangedb/pg_get_old_coin_by_h_blind.h b/src/exchangedb/pg_get_old_coin_by_h_blind.h
index 1404990d9..93ed541b6 100644
--- a/src/exchangedb/pg_get_old_coin_by_h_blind.h
+++ b/src/exchangedb/pg_get_old_coin_by_h_blind.h
@@ -41,4 +41,5 @@ TEH_PG_get_old_coin_by_h_blind (
const struct TALER_BlindedCoinHashP *h_blind_ev,
struct TALER_CoinSpendPublicKeyP *old_coin_pub,
uint64_t *rrc_serial);
+
#endif
diff --git a/src/exchangedb/pg_get_policy_details.c b/src/exchangedb/pg_get_policy_details.c
index fafdca53c..6e1b5c5dc 100644
--- a/src/exchangedb/pg_get_policy_details.c
+++ b/src/exchangedb/pg_get_policy_details.c
@@ -57,7 +57,6 @@ TEH_PG_get_policy_details (
};
-
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_policy_details",
params,
diff --git a/src/exchangedb/pg_get_purse_deposit.c b/src/exchangedb/pg_get_purse_deposit.c
index 539bd5ece..8a135818d 100644
--- a/src/exchangedb/pg_get_purse_deposit.c
+++ b/src/exchangedb/pg_get_purse_deposit.c
@@ -61,7 +61,7 @@ TEH_PG_get_purse_deposit (
*partner_url = NULL;
- /* Used in #postgres_get_purse_deposit */
+ /* Used in #postgres_get_purse_deposit */
PREPARE (pg,
"select_purse_deposit_by_coin_pub",
"SELECT "
diff --git a/src/exchangedb/pg_get_purse_request.c b/src/exchangedb/pg_get_purse_request.c
index ba8182857..c5f5aac76 100644
--- a/src/exchangedb/pg_get_purse_request.c
+++ b/src/exchangedb/pg_get_purse_request.c
@@ -59,7 +59,7 @@ TEH_PG_get_purse_request (
purse_sig),
GNUNET_PQ_result_spec_end
};
-
+
PREPARE (pg,
"get_purse_request",
"SELECT "
@@ -80,4 +80,3 @@ TEH_PG_get_purse_request (
params,
rs);
}
-
diff --git a/src/exchangedb/pg_get_ready_deposit.h b/src/exchangedb/pg_get_ready_deposit.h
index 19b6dafe4..b1dd7a968 100644
--- a/src/exchangedb/pg_get_ready_deposit.h
+++ b/src/exchangedb/pg_get_ready_deposit.h
@@ -38,9 +38,9 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_ready_deposit (void *cls,
- uint64_t start_shard_row,
- uint64_t end_shard_row,
- struct TALER_MerchantPublicKeyP *merchant_pub,
+ uint64_t start_shard_row,
+ uint64_t end_shard_row,
+ struct TALER_MerchantPublicKeyP *merchant_pub,
char **payto_uri);
#endif
diff --git a/src/exchangedb/pg_get_refresh_reveal.c b/src/exchangedb/pg_get_refresh_reveal.c
index e2db082b7..07d632248 100644
--- a/src/exchangedb/pg_get_refresh_reveal.c
+++ b/src/exchangedb/pg_get_refresh_reveal.c
@@ -133,14 +133,11 @@ add_revealed_coins (void *cls,
}
-
-
-
enum GNUNET_DB_QueryStatus
TEH_PG_get_refresh_reveal (void *cls,
- const struct TALER_RefreshCommitmentP *rc,
- TALER_EXCHANGEDB_RefreshCallback cb,
- void *cb_cls)
+ const struct TALER_RefreshCommitmentP *rc,
+ TALER_EXCHANGEDB_RefreshCallback cb,
+ void *cb_cls)
{
struct PostgresClosure *pg = cls;
struct GetRevealContext grctx;
@@ -154,8 +151,8 @@ TEH_PG_get_refresh_reveal (void *cls,
0,
sizeof (grctx));
- /* Obtain information about the coins created in a refresh
- operation, used in #postgres_get_refresh_reveal() */
+ /* Obtain information about the coins created in a refresh
+ operation, used in #postgres_get_refresh_reveal() */
PREPARE (pg,
"get_refresh_revealed_coins",
"SELECT "
diff --git a/src/exchangedb/pg_get_refresh_reveal.h b/src/exchangedb/pg_get_refresh_reveal.h
index 0fcea26cd..15b57b343 100644
--- a/src/exchangedb/pg_get_refresh_reveal.h
+++ b/src/exchangedb/pg_get_refresh_reveal.h
@@ -37,8 +37,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_refresh_reveal (void *cls,
- const struct TALER_RefreshCommitmentP *rc,
- TALER_EXCHANGEDB_RefreshCallback cb,
+ const struct TALER_RefreshCommitmentP *rc,
+ TALER_EXCHANGEDB_RefreshCallback cb,
void *cb_cls);
#endif
diff --git a/src/exchangedb/pg_get_reserve_balance.c b/src/exchangedb/pg_get_reserve_balance.c
index e08261fc0..7d5eb58f8 100644
--- a/src/exchangedb/pg_get_reserve_balance.c
+++ b/src/exchangedb/pg_get_reserve_balance.c
@@ -27,8 +27,8 @@
enum GNUNET_DB_QueryStatus
TEH_PG_get_reserve_balance (void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- struct TALER_Amount *balance)
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ struct TALER_Amount *balance)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
diff --git a/src/exchangedb/pg_get_reserve_balance.h b/src/exchangedb/pg_get_reserve_balance.h
index fd15f0d80..6dc88d906 100644
--- a/src/exchangedb/pg_get_reserve_balance.h
+++ b/src/exchangedb/pg_get_reserve_balance.h
@@ -34,7 +34,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_reserve_balance (void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
struct TALER_Amount *balance);
#endif
diff --git a/src/exchangedb/pg_get_reserve_by_h_blind.c b/src/exchangedb/pg_get_reserve_by_h_blind.c
index 2105b4766..f87fe6cd4 100644
--- a/src/exchangedb/pg_get_reserve_by_h_blind.c
+++ b/src/exchangedb/pg_get_reserve_by_h_blind.c
@@ -45,7 +45,7 @@ TEH_PG_get_reserve_by_h_blind (
reserve_out_serial_id),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_get_reserve_by_h_blind() */
+ /* Used in #postgres_get_reserve_by_h_blind() */
PREPARE (pg,
"reserve_by_h_blind",
"SELECT"
diff --git a/src/exchangedb/pg_get_wire_accounts.c b/src/exchangedb/pg_get_wire_accounts.c
index 6986eaef2..43590acf8 100644
--- a/src/exchangedb/pg_get_wire_accounts.c
+++ b/src/exchangedb/pg_get_wire_accounts.c
@@ -92,12 +92,10 @@ get_wire_accounts_cb (void *cls,
}
-
-
enum GNUNET_DB_QueryStatus
TEH_PG_get_wire_accounts (void *cls,
- TALER_EXCHANGEDB_WireAccountCallback cb,
- void *cb_cls)
+ TALER_EXCHANGEDB_WireAccountCallback cb,
+ void *cb_cls)
{
struct PostgresClosure *pg = cls;
struct GetWireAccountsContext ctx = {
@@ -111,12 +109,12 @@ TEH_PG_get_wire_accounts (void *cls,
enum GNUNET_DB_QueryStatus qs;
PREPARE (pg,
- "get_wire_accounts",
- "SELECT"
- " payto_uri"
- ",master_sig"
- " FROM wire_accounts"
- " WHERE is_active");
+ "get_wire_accounts",
+ "SELECT"
+ " payto_uri"
+ ",master_sig"
+ " FROM wire_accounts"
+ " WHERE is_active");
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
"get_wire_accounts",
params,
diff --git a/src/exchangedb/pg_get_wire_accounts.h b/src/exchangedb/pg_get_wire_accounts.h
index 4ddda0ed3..f4dc97ce0 100644
--- a/src/exchangedb/pg_get_wire_accounts.h
+++ b/src/exchangedb/pg_get_wire_accounts.h
@@ -36,7 +36,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_wire_accounts (void *cls,
- TALER_EXCHANGEDB_WireAccountCallback cb,
+ TALER_EXCHANGEDB_WireAccountCallback cb,
void *cb_cls);
#endif
diff --git a/src/exchangedb/pg_get_wire_fee.c b/src/exchangedb/pg_get_wire_fee.c
index 4b4324766..4aab68b85 100644
--- a/src/exchangedb/pg_get_wire_fee.c
+++ b/src/exchangedb/pg_get_wire_fee.c
@@ -27,12 +27,12 @@
enum GNUNET_DB_QueryStatus
TEH_PG_get_wire_fee (void *cls,
- const char *type,
- struct GNUNET_TIME_Timestamp date,
- struct GNUNET_TIME_Timestamp *start_date,
- struct GNUNET_TIME_Timestamp *end_date,
- struct TALER_WireFeeSet *fees,
- struct TALER_MasterSignatureP *master_sig)
+ const char *type,
+ struct GNUNET_TIME_Timestamp date,
+ struct GNUNET_TIME_Timestamp *start_date,
+ struct GNUNET_TIME_Timestamp *end_date,
+ struct TALER_WireFeeSet *fees,
+ struct TALER_MasterSignatureP *master_sig)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -55,22 +55,21 @@ TEH_PG_get_wire_fee (void *cls,
};
-
- /* Used in #postgres_get_wire_fee() */
- PREPARE(pg,
- "get_wire_fee",
- "SELECT "
- " start_date"
- ",end_date"
- ",wire_fee_val"
- ",wire_fee_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",master_sig"
- " FROM wire_fee"
- " WHERE wire_method=$1"
- " AND start_date <= $2"
- " AND end_date > $2;");
+ /* Used in #postgres_get_wire_fee() */
+ PREPARE (pg,
+ "get_wire_fee",
+ "SELECT "
+ " start_date"
+ ",end_date"
+ ",wire_fee_val"
+ ",wire_fee_frac"
+ ",closing_fee_val"
+ ",closing_fee_frac"
+ ",master_sig"
+ " FROM wire_fee"
+ " WHERE wire_method=$1"
+ " AND start_date <= $2"
+ " AND end_date > $2;");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_wire_fee",
params,
diff --git a/src/exchangedb/pg_get_wire_fee.h b/src/exchangedb/pg_get_wire_fee.h
index 92107fe30..409a5c48b 100644
--- a/src/exchangedb/pg_get_wire_fee.h
+++ b/src/exchangedb/pg_get_wire_fee.h
@@ -39,11 +39,11 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_wire_fee (void *cls,
- const char *type,
- struct GNUNET_TIME_Timestamp date,
- struct GNUNET_TIME_Timestamp *start_date,
- struct GNUNET_TIME_Timestamp *end_date,
- struct TALER_WireFeeSet *fees,
+ const char *type,
+ struct GNUNET_TIME_Timestamp date,
+ struct GNUNET_TIME_Timestamp *start_date,
+ struct GNUNET_TIME_Timestamp *end_date,
+ struct TALER_WireFeeSet *fees,
struct TALER_MasterSignatureP *master_sig);
#endif
diff --git a/src/exchangedb/pg_get_wire_fees.c b/src/exchangedb/pg_get_wire_fees.c
index a83db151d..e34d44a9a 100644
--- a/src/exchangedb/pg_get_wire_fees.c
+++ b/src/exchangedb/pg_get_wire_fees.c
@@ -109,9 +109,9 @@ get_wire_fees_cb (void *cls,
enum GNUNET_DB_QueryStatus
TEH_PG_get_wire_fees (void *cls,
- const char *wire_method,
- TALER_EXCHANGEDB_WireFeeCallback cb,
- void *cb_cls)
+ const char *wire_method,
+ TALER_EXCHANGEDB_WireFeeCallback cb,
+ void *cb_cls)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
diff --git a/src/exchangedb/pg_get_wire_fees.h b/src/exchangedb/pg_get_wire_fees.h
index 83bacd674..798a514db 100644
--- a/src/exchangedb/pg_get_wire_fees.h
+++ b/src/exchangedb/pg_get_wire_fees.h
@@ -37,8 +37,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_get_wire_fees (void *cls,
- const char *wire_method,
- TALER_EXCHANGEDB_WireFeeCallback cb,
+ const char *wire_method,
+ TALER_EXCHANGEDB_WireFeeCallback cb,
void *cb_cls);
#endif
diff --git a/src/exchangedb/pg_get_withdraw_info.c b/src/exchangedb/pg_get_withdraw_info.c
index ef3936269..d6a180b00 100644
--- a/src/exchangedb/pg_get_withdraw_info.c
+++ b/src/exchangedb/pg_get_withdraw_info.c
@@ -55,10 +55,10 @@ TEH_PG_get_withdraw_info (
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_get_withdraw_info() to
- locate the response for a /reserve/withdraw request
- using the hash of the blinded message. Used to
- make sure /reserve/withdraw requests are idempotent. */
+ /* Used in #postgres_get_withdraw_info() to
+ locate the response for a /reserve/withdraw request
+ using the hash of the blinded message. Used to
+ make sure /reserve/withdraw requests are idempotent. */
PREPARE (pg,
"get_withdraw_info",
"SELECT"
diff --git a/src/exchangedb/pg_have_deposit2.c b/src/exchangedb/pg_have_deposit2.c
index 1616858c5..92c300605 100644
--- a/src/exchangedb/pg_have_deposit2.c
+++ b/src/exchangedb/pg_have_deposit2.c
@@ -71,29 +71,29 @@ TEH_PG_have_deposit2 (
"Getting deposits for coin %s\n",
TALER_B2S (coin_pub));
- /* Fetch an existing deposit request, used to ensure idempotency
- during /deposit processing. Used in #postgres_have_deposit(). */
+ /* Fetch an existing deposit request, used to ensure idempotency
+ during /deposit processing. Used in #postgres_have_deposit(). */
PREPARE (pg,
- "get_deposit",
- "SELECT"
- " dep.amount_with_fee_val"
- ",dep.amount_with_fee_frac"
- ",denominations.fee_deposit_val"
- ",denominations.fee_deposit_frac"
- ",dep.wallet_timestamp"
- ",dep.exchange_timestamp"
- ",dep.refund_deadline"
- ",dep.wire_deadline"
- ",dep.h_contract_terms"
- ",dep.wire_salt"
- ",wt.payto_uri AS receiver_wire_account"
- " FROM deposits dep"
- " JOIN known_coins kc ON (kc.coin_pub = dep.coin_pub)"
- " JOIN denominations USING (denominations_serial)"
- " JOIN wire_targets wt USING (wire_target_h_payto)"
- " WHERE dep.coin_pub=$1"
- " AND dep.merchant_pub=$3"
- " AND dep.h_contract_terms=$2;");
+ "get_deposit",
+ "SELECT"
+ " dep.amount_with_fee_val"
+ ",dep.amount_with_fee_frac"
+ ",denominations.fee_deposit_val"
+ ",denominations.fee_deposit_frac"
+ ",dep.wallet_timestamp"
+ ",dep.exchange_timestamp"
+ ",dep.refund_deadline"
+ ",dep.wire_deadline"
+ ",dep.h_contract_terms"
+ ",dep.wire_salt"
+ ",wt.payto_uri AS receiver_wire_account"
+ " FROM deposits dep"
+ " JOIN known_coins kc ON (kc.coin_pub = dep.coin_pub)"
+ " JOIN denominations USING (denominations_serial)"
+ " JOIN wire_targets wt USING (wire_target_h_payto)"
+ " WHERE dep.coin_pub=$1"
+ " AND dep.merchant_pub=$3"
+ " AND dep.h_contract_terms=$2;");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_deposit",
diff --git a/src/exchangedb/pg_insert_aggregation_tracking.c b/src/exchangedb/pg_insert_aggregation_tracking.c
index 01c5928ba..fe61b841d 100644
--- a/src/exchangedb/pg_insert_aggregation_tracking.c
+++ b/src/exchangedb/pg_insert_aggregation_tracking.c
@@ -51,4 +51,3 @@ TEH_PG_insert_aggregation_tracking (
"insert_aggregation_tracking",
params);
}
-
diff --git a/src/exchangedb/pg_insert_aggregation_tracking.h b/src/exchangedb/pg_insert_aggregation_tracking.h
index 4f0ac1aae..e67c0e8e7 100644
--- a/src/exchangedb/pg_insert_aggregation_tracking.h
+++ b/src/exchangedb/pg_insert_aggregation_tracking.h
@@ -40,4 +40,3 @@ TEH_PG_insert_aggregation_tracking (
unsigned long long deposit_serial_id);
#endif
-
diff --git a/src/exchangedb/pg_insert_auditor.c b/src/exchangedb/pg_insert_auditor.c
index 757dfa625..2f1de7ba7 100644
--- a/src/exchangedb/pg_insert_auditor.c
+++ b/src/exchangedb/pg_insert_auditor.c
@@ -27,10 +27,10 @@
enum GNUNET_DB_QueryStatus
TEH_PG_insert_auditor (void *cls,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const char *auditor_url,
- const char *auditor_name,
- struct GNUNET_TIME_Timestamp start_date)
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ const char *auditor_name,
+ struct GNUNET_TIME_Timestamp start_date)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -41,7 +41,7 @@ TEH_PG_insert_auditor (void *cls,
GNUNET_PQ_query_param_end
};
- /* used in #postgres_insert_auditor() */
+ /* used in #postgres_insert_auditor() */
PREPARE (pg,
"insert_auditor",
"INSERT INTO auditors "
diff --git a/src/exchangedb/pg_insert_auditor.h b/src/exchangedb/pg_insert_auditor.h
index 7523282e4..8de388f23 100644
--- a/src/exchangedb/pg_insert_auditor.h
+++ b/src/exchangedb/pg_insert_auditor.h
@@ -38,8 +38,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_insert_auditor (void *cls,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const char *auditor_url,
- const char *auditor_name,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ const char *auditor_name,
struct GNUNET_TIME_Timestamp start_date);
#endif
diff --git a/src/exchangedb/pg_insert_contract.c b/src/exchangedb/pg_insert_contract.c
index d3e6c23be..0274f8d93 100644
--- a/src/exchangedb/pg_insert_contract.c
+++ b/src/exchangedb/pg_insert_contract.c
@@ -45,20 +45,20 @@ TEH_PG_insert_contract (
};
*in_conflict = false;
- /* Used in #postgres_insert_contract() */
+ /* Used in #postgres_insert_contract() */
PREPARE (pg,
- "insert_contract",
- "INSERT INTO contracts"
- " (purse_pub"
- " ,pub_ckey"
- " ,e_contract"
- " ,contract_sig"
- " ,purse_expiration"
- " ) SELECT "
- " $1, $2, $3, $4, purse_expiration"
- " FROM purse_requests"
- " WHERE purse_pub=$1"
- " ON CONFLICT DO NOTHING;");
+ "insert_contract",
+ "INSERT INTO contracts"
+ " (purse_pub"
+ " ,pub_ckey"
+ " ,e_contract"
+ " ,contract_sig"
+ " ,purse_expiration"
+ " ) SELECT "
+ " $1, $2, $3, $4, purse_expiration"
+ " FROM purse_requests"
+ " WHERE purse_pub=$1"
+ " ON CONFLICT DO NOTHING;");
qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
"insert_contract",
params);
@@ -68,8 +68,8 @@ TEH_PG_insert_contract (
struct TALER_EncryptedContract econtract2;
qs = TEH_PG_select_contract_by_purse (pg,
- purse_pub,
- &econtract2);
+ purse_pub,
+ &econtract2);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
GNUNET_break (0);
diff --git a/src/exchangedb/pg_insert_denomination_revocation.c b/src/exchangedb/pg_insert_denomination_revocation.c
index 061d7adc0..49445f262 100644
--- a/src/exchangedb/pg_insert_denomination_revocation.c
+++ b/src/exchangedb/pg_insert_denomination_revocation.c
@@ -39,7 +39,7 @@ TEH_PG_insert_denomination_revocation (
GNUNET_PQ_query_param_end
};
- /* Used in #postgres_insert_denomination_revocation() */
+ /* Used in #postgres_insert_denomination_revocation() */
PREPARE (pg,
"denomination_revocation_insert",
"INSERT INTO denomination_revocations "
diff --git a/src/exchangedb/pg_insert_deposit.h b/src/exchangedb/pg_insert_deposit.h
index 15de39eff..82cbcd542 100644
--- a/src/exchangedb/pg_insert_deposit.h
+++ b/src/exchangedb/pg_insert_deposit.h
@@ -34,7 +34,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_insert_deposit (void *cls,
- struct GNUNET_TIME_Timestamp exchange_timestamp,
+ struct GNUNET_TIME_Timestamp exchange_timestamp,
const struct TALER_EXCHANGEDB_Deposit *deposit);
#endif
diff --git a/src/exchangedb/pg_insert_drain_profit.c b/src/exchangedb/pg_insert_drain_profit.c
index 19340eafb..34ab0332c 100644
--- a/src/exchangedb/pg_insert_drain_profit.c
+++ b/src/exchangedb/pg_insert_drain_profit.c
@@ -45,7 +45,7 @@ TEH_PG_insert_drain_profit (
GNUNET_PQ_query_param_auto_from_type (master_sig),
GNUNET_PQ_query_param_end
};
- /* Used in #postgres_insert_drain_profit() */
+ /* Used in #postgres_insert_drain_profit() */
PREPARE (pg,
"drain_profit_insert",
"INSERT INTO profit_drains "
diff --git a/src/exchangedb/pg_insert_global_fee.c b/src/exchangedb/pg_insert_global_fee.c
index c08fc23bb..1c34016a7 100644
--- a/src/exchangedb/pg_insert_global_fee.c
+++ b/src/exchangedb/pg_insert_global_fee.c
@@ -28,13 +28,13 @@
enum GNUNET_DB_QueryStatus
TEH_PG_insert_global_fee (void *cls,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- const struct TALER_GlobalFeeSet *fees,
- struct GNUNET_TIME_Relative purse_timeout,
- struct GNUNET_TIME_Relative history_expiration,
- uint32_t purse_account_limit,
- const struct TALER_MasterSignatureP *master_sig)
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
+ const struct TALER_MasterSignatureP *master_sig)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -59,14 +59,14 @@ TEH_PG_insert_global_fee (void *cls,
uint32_t pal;
qs = TEH_PG_get_global_fee (pg,
- start_date,
- &sd,
- &ed,
- &wx,
- &pt,
- &he,
- &pal,
- &sig);
+ start_date,
+ &sd,
+ &ed,
+ &wx,
+ &pt,
+ &he,
+ &pal,
+ &sig);
if (qs < 0)
return qs;
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
@@ -113,7 +113,7 @@ TEH_PG_insert_global_fee (void *cls,
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
- /* Used in #postgres_insert_global_fee */
+ /* Used in #postgres_insert_global_fee */
PREPARE (pg,
"insert_global_fee",
"INSERT INTO global_fee "
diff --git a/src/exchangedb/pg_insert_global_fee.h b/src/exchangedb/pg_insert_global_fee.h
index 9780d5322..411345dc4 100644
--- a/src/exchangedb/pg_insert_global_fee.h
+++ b/src/exchangedb/pg_insert_global_fee.h
@@ -40,11 +40,11 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_insert_global_fee (void *cls,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- const struct TALER_GlobalFeeSet *fees,
- struct GNUNET_TIME_Relative purse_timeout,
- struct GNUNET_TIME_Relative history_expiration,
- uint32_t purse_account_limit,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
const struct TALER_MasterSignatureP *master_sig);
#endif
diff --git a/src/exchangedb/pg_insert_history_request.c b/src/exchangedb/pg_insert_history_request.c
index 00270b1a1..ab3f39133 100644
--- a/src/exchangedb/pg_insert_history_request.c
+++ b/src/exchangedb/pg_insert_history_request.c
@@ -51,7 +51,7 @@ TEH_PG_insert_history_request (
idempotent),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_insert_history_request() */
+ /* Used in #postgres_insert_history_request() */
PREPARE (pg,
"call_history_request",
"SELECT"
diff --git a/src/exchangedb/pg_insert_kyc_requirement_for_account.c b/src/exchangedb/pg_insert_kyc_requirement_for_account.c
index be5cbac87..2552aae40 100644
--- a/src/exchangedb/pg_insert_kyc_requirement_for_account.c
+++ b/src/exchangedb/pg_insert_kyc_requirement_for_account.c
@@ -43,7 +43,7 @@ TEH_PG_insert_kyc_requirement_for_account (
requirement_row),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_insert_kyc_requirement_for_account() */
+ /* Used in #postgres_insert_kyc_requirement_for_account() */
PREPARE (pg,
"insert_legitimization_requirement",
"INSERT INTO legitimization_requirements"
diff --git a/src/exchangedb/pg_insert_kyc_requirement_for_account.h b/src/exchangedb/pg_insert_kyc_requirement_for_account.h
index 5f9bf6a48..c2f03b02a 100644
--- a/src/exchangedb/pg_insert_kyc_requirement_for_account.h
+++ b/src/exchangedb/pg_insert_kyc_requirement_for_account.h
@@ -41,4 +41,5 @@ TEH_PG_insert_kyc_requirement_for_account (
const char *provider_section,
const struct TALER_PaytoHashP *h_payto,
uint64_t *requirement_row);
+
#endif
diff --git a/src/exchangedb/pg_insert_kyc_requirement_process.c b/src/exchangedb/pg_insert_kyc_requirement_process.c
index d520ac59c..f1ea5b490 100644
--- a/src/exchangedb/pg_insert_kyc_requirement_process.c
+++ b/src/exchangedb/pg_insert_kyc_requirement_process.c
@@ -52,7 +52,7 @@ TEH_PG_insert_kyc_requirement_process (
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_insert_kyc_requirement_process() */
+ /* Used in #postgres_insert_kyc_requirement_process() */
PREPARE (pg,
"insert_legitimization_process",
"INSERT INTO legitimization_processes"
diff --git a/src/exchangedb/pg_insert_kyc_requirement_process.h b/src/exchangedb/pg_insert_kyc_requirement_process.h
index 3f354472e..df21db8cd 100644
--- a/src/exchangedb/pg_insert_kyc_requirement_process.h
+++ b/src/exchangedb/pg_insert_kyc_requirement_process.h
@@ -45,4 +45,5 @@ TEH_PG_insert_kyc_requirement_process (
const char *provider_account_id,
const char *provider_legitimization_id,
uint64_t *process_row);
+
#endif
diff --git a/src/exchangedb/pg_insert_partner.h b/src/exchangedb/pg_insert_partner.h
index eed40a80e..3ebae786c 100644
--- a/src/exchangedb/pg_insert_partner.h
+++ b/src/exchangedb/pg_insert_partner.h
@@ -40,12 +40,12 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_insert_partner (void *cls,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- struct GNUNET_TIME_Relative wad_frequency,
- const struct TALER_Amount *wad_fee,
- const char *partner_base_url,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ struct GNUNET_TIME_Relative wad_frequency,
+ const struct TALER_Amount *wad_fee,
+ const char *partner_base_url,
const struct TALER_MasterSignatureP *master_sig);
#endif
diff --git a/src/exchangedb/pg_insert_records_by_table.c b/src/exchangedb/pg_insert_records_by_table.c
index d6630797a..3ec9c77cc 100644
--- a/src/exchangedb/pg_insert_records_by_table.c
+++ b/src/exchangedb/pg_insert_records_by_table.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet
- Copyright (C) 2020, 2021, 2022 Taler Systems SA
+ Copyright (C) 2020-2023 Taler Systems SA
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -19,8 +19,9 @@
*/
/**
* @file exchangedb/pg_insert_records_by_table.c
- * @brief insert_records_by_table implementation
+ * @brief replicate_records_by_table implementation
* @author Christian Grothoff
+ * @author Özgür Kesim
*/
#include "platform.h"
#include "taler_error_codes.h"
@@ -28,6 +29,7 @@
#include "taler_pq_lib.h"
#include "pg_insert_records_by_table.h"
#include "pg_helper.h"
+#include
/**
@@ -1407,7 +1409,7 @@ irbt_cb_table_purse_decision (struct PostgresClosure *pg,
GNUNET_PQ_query_param_timestamp (
&td->details.purse_decision.action_timestamp),
GNUNET_PQ_query_param_bool (
- &td->details.purse_decision.refunded),
+ td->details.purse_decision.refunded),
GNUNET_PQ_query_param_end
};
@@ -1872,12 +1874,304 @@ irbt_cb_table_profit_drains (struct PostgresClosure *pg,
}
+/**
+ * Function called with aml_staff records to insert into table.
+ *
+ * @param pg plugin context
+ * @param td record to insert
+ */
+static enum GNUNET_DB_QueryStatus
+irbt_cb_table_aml_staff (struct PostgresClosure *pg,
+ const struct TALER_EXCHANGEDB_TableData *td)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&td->serial),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.aml_staff.decider_pub),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.aml_staff.master_sig),
+ GNUNET_PQ_query_param_string (
+ td->details.aml_staff.decider_name),
+ GNUNET_PQ_query_param_bool (
+ td->details.aml_staff.is_active),
+ GNUNET_PQ_query_param_bool (
+ td->details.aml_staff.read_only),
+ GNUNET_PQ_query_param_timestamp (
+ &td->details.aml_staff.last_change),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "insert_into_table_aml_staff",
+ "INSERT INTO aml_staff"
+ "(aml_staff_uuid"
+ ",decider_pub"
+ ",master_sig"
+ ",decider_name"
+ ",is_active"
+ ",read_only"
+ ",last_change"
+ ") VALUES "
+ "($1, $2, $3, $4, $5, $6, $7);");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_into_table_aml_staff",
+ params);
+}
+
+
+/**
+ * Function called with aml_history records to insert into table.
+ *
+ * @param pg plugin context
+ * @param td record to insert
+ */
+static enum GNUNET_DB_QueryStatus
+irbt_cb_table_aml_history (struct PostgresClosure *pg,
+ const struct TALER_EXCHANGEDB_TableData *td)
+{
+ uint32_t status32 = td->details.aml_history.new_status;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&td->serial),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.aml_history.h_payto),
+ TALER_PQ_query_param_amount (
+ &td->details.aml_history.new_threshold),
+ GNUNET_PQ_query_param_uint32 (
+ &status32),
+ GNUNET_PQ_query_param_timestamp (
+ &td->details.aml_history.decision_time),
+ GNUNET_PQ_query_param_string (
+ td->details.aml_history.justification),
+ (NULL == td->details.aml_history.kyc_requirements)
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (
+ td->details.aml_history.kyc_requirements),
+ GNUNET_PQ_query_param_uint64 (
+ &td->details.aml_history.kyc_req_row),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.aml_history.decider_pub),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.aml_history.decider_sig),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "insert_into_table_aml_history",
+ "INSERT INTO aml_history"
+ "(aml_history_serial_id"
+ ",h_payto"
+ ",new_threshold_val"
+ ",new_threshold_frac"
+ ",new_status"
+ ",decision_time"
+ ",justification"
+ ",kyc_requirements"
+ ",kyc_req_row"
+ ",decider_pub"
+ ",decider_sig"
+ ") VALUES "
+ "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_into_table_aml_history",
+ params);
+}
+
+
+/**
+ * Function called with kyc_attributes records to insert into table.
+ *
+ * @param pg plugin context
+ * @param td record to insert
+ */
+static enum GNUNET_DB_QueryStatus
+irbt_cb_table_kyc_attributes (struct PostgresClosure *pg,
+ const struct TALER_EXCHANGEDB_TableData *td)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&td->serial),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.kyc_attributes.h_payto),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.kyc_attributes.kyc_prox),
+ GNUNET_PQ_query_param_string (
+ td->details.kyc_attributes.provider),
+ (NULL == td->details.kyc_attributes.birthdate)
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (
+ td->details.kyc_attributes.birthdate),
+ GNUNET_PQ_query_param_timestamp (
+ &td->details.kyc_attributes.collection_time),
+ GNUNET_PQ_query_param_timestamp (
+ &td->details.kyc_attributes.expiration_time),
+ GNUNET_PQ_query_param_fixed_size (
+ &td->details.kyc_attributes.encrypted_attributes,
+ td->details.kyc_attributes.encrypted_attributes_size),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "insert_into_table_kyc_attributes",
+ "INSERT INTO kyc_attributes"
+ "(kyc_attributes_serial_id"
+ ",h_payto"
+ ",kyc_prox"
+ ",provider"
+ ",birthdate"
+ ",collection_time"
+ ",expiration_time"
+ ",encrypted_attributes"
+ ") VALUES "
+ "($1, $2, $3, $4, $5, $6, $7, $8);");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_into_table_kyc_attributes",
+ params);
+}
+
+
+/**
+ * Function called with purse_deletion records to insert into table.
+ *
+ * @param pg plugin context
+ * @param td record to insert
+ */
+static enum GNUNET_DB_QueryStatus
+irbt_cb_table_purse_deletion (struct PostgresClosure *pg,
+ const struct TALER_EXCHANGEDB_TableData *td)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&td->serial),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.purse_deletion.purse_pub),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.purse_deletion.purse_sig),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "insert_into_table_purse_deletion",
+ "INSERT INTO purse_deletion"
+ "(purse_deletion_serial_id"
+ ",purse_pub"
+ ",purse_sig"
+ ") VALUES "
+ "($1, $2, $3);");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_into_table_purse_deletion",
+ params);
+}
+
+
+/**
+ * Function called with withdraw_age_commitments records to insert into table.
+ *
+ * @param pg plugin context
+ * @param td record to insert
+ */
+static enum GNUNET_DB_QueryStatus
+irbt_cb_table_withdraw_age_commitments (struct PostgresClosure *pg,
+ const struct
+ TALER_EXCHANGEDB_TableData *td)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&td->serial),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.withdraw_age_commitments.h_commitment),
+ TALER_PQ_query_param_amount (
+ &td->details.withdraw_age_commitments.amount_with_fee),
+ GNUNET_PQ_query_param_uint16 (
+ &td->details.withdraw_age_commitments.max_age),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.withdraw_age_commitments.reserve_pub),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.withdraw_age_commitments.reserve_sig),
+ GNUNET_PQ_query_param_uint32 (
+ &td->details.withdraw_age_commitments.noreveal_index),
+ GNUNET_PQ_query_param_absolute_time (
+ &td->details.withdraw_age_commitments.timestamp),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "insert_into_table_withdraw_age_commitments",
+ "INSERT INTO withdraw_age_commitments"
+ "(withdraw_age_commitment_id"
+ ",h_commitment"
+ ",amount_with_fee_val"
+ ",amount_with_fee_frac"
+ ",max_age"
+ ",reserve_pub"
+ ",reserve_sig"
+ ",noreveal_index"
+ ",timestamp"
+ ") VALUES "
+ "($1, $2, $3, $4, $5, $6, $7, $8, $9);");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_into_table_withdraw_age_commitments",
+ params);
+}
+
+
+/**
+ * Function called with withdraw_age_revealed_coins records to insert into table.
+ *
+ * @param pg plugin context
+ * @param td record to insert
+ */
+static enum GNUNET_DB_QueryStatus
+irbt_cb_table_withdraw_age_revealed_coins (struct PostgresClosure *pg,
+ const struct
+ TALER_EXCHANGEDB_TableData *td)
+{
+ struct GNUNET_HashCode h_coin_ev;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&td->serial),
+ GNUNET_PQ_query_param_auto_from_type (
+ &td->details.withdraw_age_revealed_coins.h_commitment),
+ GNUNET_PQ_query_param_uint32 (
+ &td->details.withdraw_age_revealed_coins.freshcoin_index),
+ GNUNET_PQ_query_param_uint64 (
+ &td->details.withdraw_age_revealed_coins.denominations_serial),
+ GNUNET_PQ_query_param_fixed_size (
+ td->details.withdraw_age_revealed_coins.coin_ev,
+ td->details.withdraw_age_revealed_coins.coin_ev_size),
+ GNUNET_PQ_query_param_auto_from_type (&h_coin_ev),
+ TALER_PQ_query_param_blinded_denom_sig (
+ &td->details.withdraw_age_revealed_coins.ev_sig),
+ TALER_PQ_query_param_exchange_withdraw_values (
+ &td->details.withdraw_age_revealed_coins.ewv),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "insert_into_table_withdraw_age_revealed_coins",
+ "INSERT INTO withdraw_age_revealed_coins"
+ "(withdraw_age_revealed_coins_id"
+ ",h_commitment"
+ ",freshcoin_index"
+ ",denominations_serial"
+ ",coin_ev"
+ ",h_coin_ev"
+ ",ev_sig"
+ ",ewv"
+ ") VALUES "
+ "($1, $2, $3, $4, $5, $6, $7, $8);");
+
+ GNUNET_CRYPTO_hash (td->details.withdraw_age_revealed_coins.coin_ev,
+ td->details.withdraw_age_revealed_coins.coin_ev_size,
+ &h_coin_ev);
+
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_into_table_withdraw_age_revealed_coins",
+ params);
+}
+
+
enum GNUNET_DB_QueryStatus
TEH_PG_insert_records_by_table (void *cls,
const struct TALER_EXCHANGEDB_TableData *td)
{
struct PostgresClosure *pg = cls;
- InsertRecordCallback rh;
+ InsertRecordCallback rh = NULL;
switch (td->table)
{
@@ -2007,7 +2301,27 @@ TEH_PG_insert_records_by_table (void *cls,
case TALER_EXCHANGEDB_RT_PROFIT_DRAINS:
rh = &irbt_cb_table_profit_drains;
break;
- default:
+ case TALER_EXCHANGEDB_RT_AML_STAFF:
+ rh = &irbt_cb_table_aml_staff;
+ break;
+ case TALER_EXCHANGEDB_RT_AML_HISTORY:
+ rh = &irbt_cb_table_aml_history;
+ break;
+ case TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES:
+ rh = &irbt_cb_table_kyc_attributes;
+ break;
+ case TALER_EXCHANGEDB_RT_PURSE_DELETION:
+ rh = &irbt_cb_table_purse_deletion;
+ break;
+ case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS:
+ rh = &irbt_cb_table_withdraw_age_commitments;
+ break;
+ case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS:
+ rh = &irbt_cb_table_withdraw_age_revealed_coins;
+ break;
+ }
+ if (NULL == rh)
+ {
GNUNET_break (0);
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -2016,4 +2330,4 @@ TEH_PG_insert_records_by_table (void *cls,
}
-/* end of irbt_callbacks.c */
+/* end of pg_insert_records_by_table.c */
diff --git a/src/exchangedb/pg_insert_refund.c b/src/exchangedb/pg_insert_refund.c
index 047df0334..8f9466575 100644
--- a/src/exchangedb/pg_insert_refund.c
+++ b/src/exchangedb/pg_insert_refund.c
@@ -28,7 +28,7 @@
enum GNUNET_DB_QueryStatus
TEH_PG_insert_refund (void *cls,
- const struct TALER_EXCHANGEDB_Refund *refund)
+ const struct TALER_EXCHANGEDB_Refund *refund)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -45,7 +45,7 @@ TEH_PG_insert_refund (void *cls,
TALER_amount_cmp_currency (&refund->details.refund_amount,
&refund->details.refund_fee));
- /* Used in #postgres_insert_refund() to store refund information */
+ /* Used in #postgres_insert_refund() to store refund information */
PREPARE (pg,
"insert_refund",
"INSERT INTO refunds "
diff --git a/src/exchangedb/pg_insert_reserve_closed.c b/src/exchangedb/pg_insert_reserve_closed.c
index d17c37edc..963a38226 100644
--- a/src/exchangedb/pg_insert_reserve_closed.c
+++ b/src/exchangedb/pg_insert_reserve_closed.c
@@ -57,20 +57,20 @@ TEH_PG_insert_reserve_closed (
GNUNET_PQ_query_param_end
};
- /* Used in #postgres_insert_reserve_closed() */
+ /* Used in #postgres_insert_reserve_closed() */
PREPARE (pg,
- "reserves_close_insert",
- "INSERT INTO reserves_close "
- "(reserve_pub"
- ",execution_date"
- ",wtid"
- ",wire_target_h_payto"
- ",amount_val"
- ",amount_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",close_request_row"
- ") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9);");
+ "reserves_close_insert",
+ "INSERT INTO reserves_close "
+ "(reserve_pub"
+ ",execution_date"
+ ",wtid"
+ ",wire_target_h_payto"
+ ",amount_val"
+ ",amount_frac"
+ ",closing_fee_val"
+ ",closing_fee_frac"
+ ",close_request_row"
+ ") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9);");
qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
"reserves_close_insert",
@@ -83,7 +83,7 @@ TEH_PG_insert_reserve_closed (
reserve.pub = *reserve_pub;
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
(qs = TEH_PG_reserves_get (cls,
- &reserve)))
+ &reserve)))
{
/* Existence should have been checked before we got here... */
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -110,5 +110,5 @@ TEH_PG_insert_reserve_closed (
GNUNET_break (TALER_AAR_RESULT_ZERO == ret);
}
return TEH_PG_reserves_update (cls,
- &reserve);
+ &reserve);
}
diff --git a/src/exchangedb/pg_insert_wire.h b/src/exchangedb/pg_insert_wire.h
index 15ce08674..670928d7c 100644
--- a/src/exchangedb/pg_insert_wire.h
+++ b/src/exchangedb/pg_insert_wire.h
@@ -37,8 +37,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_insert_wire (void *cls,
- const char *payto_uri,
- struct GNUNET_TIME_Timestamp start_date,
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp start_date,
const struct TALER_MasterSignatureP *master_sig);
#endif
diff --git a/src/exchangedb/pg_insert_wire_fee.c b/src/exchangedb/pg_insert_wire_fee.c
index 278ec2bcb..ac14a8cbb 100644
--- a/src/exchangedb/pg_insert_wire_fee.c
+++ b/src/exchangedb/pg_insert_wire_fee.c
@@ -28,11 +28,11 @@
enum GNUNET_DB_QueryStatus
TEH_PG_insert_wire_fee (void *cls,
- const char *type,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- const struct TALER_WireFeeSet *fees,
- const struct TALER_MasterSignatureP *master_sig)
+ const char *type,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_WireFeeSet *fees,
+ const struct TALER_MasterSignatureP *master_sig)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -51,12 +51,12 @@ TEH_PG_insert_wire_fee (void *cls,
enum GNUNET_DB_QueryStatus qs;
qs = TEH_PG_get_wire_fee (pg,
- type,
- start_date,
- &sd,
- &ed,
- &wx,
- &sig);
+ type,
+ start_date,
+ &sd,
+ &ed,
+ &wx,
+ &sig);
if (qs < 0)
return qs;
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
@@ -88,7 +88,7 @@ TEH_PG_insert_wire_fee (void *cls,
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
- /* Used in #postgres_insert_wire_fee */
+ /* Used in #postgres_insert_wire_fee */
PREPARE (pg,
"insert_wire_fee",
"INSERT INTO wire_fee "
diff --git a/src/exchangedb/pg_insert_wire_fee.h b/src/exchangedb/pg_insert_wire_fee.h
index e53faf5a5..15c1a39f8 100644
--- a/src/exchangedb/pg_insert_wire_fee.h
+++ b/src/exchangedb/pg_insert_wire_fee.h
@@ -38,9 +38,9 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_insert_wire_fee (void *cls,
- const char *type,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- const struct TALER_WireFeeSet *fees,
+ const char *type,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_WireFeeSet *fees,
const struct TALER_MasterSignatureP *master_sig);
#endif
diff --git a/src/exchangedb/pg_iterate_active_auditors.h b/src/exchangedb/pg_iterate_active_auditors.h
index 1247d2d3d..f0e2808e9 100644
--- a/src/exchangedb/pg_iterate_active_auditors.h
+++ b/src/exchangedb/pg_iterate_active_auditors.h
@@ -36,6 +36,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_iterate_active_auditors (void *cls,
- TALER_EXCHANGEDB_AuditorsCallback cb,
+ TALER_EXCHANGEDB_AuditorsCallback cb,
void *cb_cls);
+
#endif
diff --git a/src/exchangedb/pg_iterate_active_signkeys.h b/src/exchangedb/pg_iterate_active_signkeys.h
index b99dfa8df..5ebba9f5a 100644
--- a/src/exchangedb/pg_iterate_active_signkeys.h
+++ b/src/exchangedb/pg_iterate_active_signkeys.h
@@ -37,7 +37,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_iterate_active_signkeys (void *cls,
- TALER_EXCHANGEDB_ActiveSignkeysCallback cb,
+ TALER_EXCHANGEDB_ActiveSignkeysCallback cb,
void *cb_cls);
#endif
diff --git a/src/exchangedb/pg_iterate_auditor_denominations.h b/src/exchangedb/pg_iterate_auditor_denominations.h
index da1f36701..1278e8a9f 100644
--- a/src/exchangedb/pg_iterate_auditor_denominations.h
+++ b/src/exchangedb/pg_iterate_auditor_denominations.h
@@ -41,4 +41,5 @@ TEH_PG_iterate_auditor_denominations (
void *cls,
TALER_EXCHANGEDB_AuditorDenominationsCallback cb,
void *cb_cls);
+
#endif
diff --git a/src/exchangedb/pg_iterate_denomination_info.h b/src/exchangedb/pg_iterate_denomination_info.h
index 57847a515..27c08d0a9 100644
--- a/src/exchangedb/pg_iterate_denomination_info.h
+++ b/src/exchangedb/pg_iterate_denomination_info.h
@@ -35,7 +35,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_iterate_denomination_info (void *cls,
- TALER_EXCHANGEDB_DenominationCallback cb,
+ TALER_EXCHANGEDB_DenominationCallback cb,
void *cb_cls);
#endif
diff --git a/src/exchangedb/pg_iterate_denominations.h b/src/exchangedb/pg_iterate_denominations.h
index a205fc6ba..9f59fc803 100644
--- a/src/exchangedb/pg_iterate_denominations.h
+++ b/src/exchangedb/pg_iterate_denominations.h
@@ -38,7 +38,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_iterate_denominations (void *cls,
- TALER_EXCHANGEDB_DenominationsCallback cb,
+ TALER_EXCHANGEDB_DenominationsCallback cb,
void *cb_cls);
#endif
diff --git a/src/exchangedb/pg_kyc_provider_account_lookup.c b/src/exchangedb/pg_kyc_provider_account_lookup.c
index 32cd65f7d..f3bd84c1a 100644
--- a/src/exchangedb/pg_kyc_provider_account_lookup.c
+++ b/src/exchangedb/pg_kyc_provider_account_lookup.c
@@ -26,7 +26,6 @@
#include "pg_helper.h"
-
enum GNUNET_DB_QueryStatus
TEH_PG_kyc_provider_account_lookup (
void *cls,
@@ -48,7 +47,7 @@ TEH_PG_kyc_provider_account_lookup (
process_row),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_kyc_provider_account_lookup() */
+ /* Used in #postgres_kyc_provider_account_lookup() */
PREPARE (pg,
"get_wire_target_by_legitimization_id",
"SELECT "
diff --git a/src/exchangedb/pg_kyc_provider_account_lookup.h b/src/exchangedb/pg_kyc_provider_account_lookup.h
index 41bcb86ae..74f90d88d 100644
--- a/src/exchangedb/pg_kyc_provider_account_lookup.h
+++ b/src/exchangedb/pg_kyc_provider_account_lookup.h
@@ -44,4 +44,5 @@ TEH_PG_kyc_provider_account_lookup (
const char *provider_legitimization_id,
struct TALER_PaytoHashP *h_payto,
uint64_t *process_row);
+
#endif
diff --git a/src/exchangedb/pg_lookup_auditor_status.c b/src/exchangedb/pg_lookup_auditor_status.c
index 5e62bfa9e..91afe6eaa 100644
--- a/src/exchangedb/pg_lookup_auditor_status.c
+++ b/src/exchangedb/pg_lookup_auditor_status.c
@@ -46,7 +46,7 @@ TEH_PG_lookup_auditor_status (
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_lookup_auditor_status() */
+ /* Used in #postgres_lookup_auditor_status() */
PREPARE (pg,
"lookup_auditor_status",
"SELECT"
diff --git a/src/exchangedb/pg_lookup_denomination_key.c b/src/exchangedb/pg_lookup_denomination_key.c
index 36ada96e4..759af1b5c 100644
--- a/src/exchangedb/pg_lookup_denomination_key.c
+++ b/src/exchangedb/pg_lookup_denomination_key.c
@@ -60,7 +60,7 @@ TEH_PG_lookup_denomination_key (
GNUNET_PQ_result_spec_end
};
- /* used in #postgres_lookup_denomination_key() */
+ /* used in #postgres_lookup_denomination_key() */
PREPARE (pg,
"lookup_denomination_key",
"SELECT"
diff --git a/src/exchangedb/pg_lookup_global_fee_by_time.h b/src/exchangedb/pg_lookup_global_fee_by_time.h
index 9ac7d7dcd..c5ff95fc6 100644
--- a/src/exchangedb/pg_lookup_global_fee_by_time.h
+++ b/src/exchangedb/pg_lookup_global_fee_by_time.h
@@ -48,4 +48,5 @@ TEH_PG_lookup_global_fee_by_time (
struct GNUNET_TIME_Relative *purse_timeout,
struct GNUNET_TIME_Relative *history_expiration,
uint32_t *purse_account_limit);
+
#endif
diff --git a/src/exchangedb/pg_lookup_kyc_process_by_account.h b/src/exchangedb/pg_lookup_kyc_process_by_account.h
index 40af6a7f6..0300b498c 100644
--- a/src/exchangedb/pg_lookup_kyc_process_by_account.h
+++ b/src/exchangedb/pg_lookup_kyc_process_by_account.h
@@ -47,4 +47,5 @@ TEH_PG_lookup_kyc_process_by_account (
struct GNUNET_TIME_Absolute *expiration,
char **provider_account_id,
char **provider_legitimization_id);
+
#endif
diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.c b/src/exchangedb/pg_lookup_kyc_requirement_by_row.c
index 6542aa28f..6f9d76786 100644
--- a/src/exchangedb/pg_lookup_kyc_requirement_by_row.c
+++ b/src/exchangedb/pg_lookup_kyc_requirement_by_row.c
@@ -30,9 +30,11 @@ TEH_PG_lookup_kyc_requirement_by_row (
void *cls,
uint64_t requirement_row,
char **requirements,
+ enum TALER_AmlDecisionState *aml_status,
struct TALER_PaytoHashP *h_payto)
{
struct PostgresClosure *pg = cls;
+ uint32_t status = TALER_AML_NORMAL;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&requirement_row),
GNUNET_PQ_query_param_end
@@ -42,19 +44,28 @@ TEH_PG_lookup_kyc_requirement_by_row (
requirements),
GNUNET_PQ_result_spec_auto_from_type ("h_payto",
h_payto),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_uint32 ("status",
+ &status),
+ NULL),
GNUNET_PQ_result_spec_end
};
-/* Used in #postgres_lookup_kyc_requirement_by_row() */
+ enum GNUNET_DB_QueryStatus qs;
+
PREPARE (pg,
"lookup_legitimization_requirement_by_row",
"SELECT "
- " required_checks"
- ",h_payto"
- " FROM legitimization_requirements"
+ " lr.required_checks"
+ ",lr.h_payto"
+ ",aml.status"
+ " FROM legitimization_requirements lr"
+ " LEFT JOIN aml_status aml USING (h_payto)"
" WHERE legitimization_requirement_serial_id=$1;");
- return GNUNET_PQ_eval_prepared_singleton_select (
+ qs = GNUNET_PQ_eval_prepared_singleton_select (
pg->conn,
"lookup_legitimization_requirement_by_row",
params,
rs);
+ *aml_status = (enum TALER_AmlDecisionState) status;
+ return qs;
}
diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.h b/src/exchangedb/pg_lookup_kyc_requirement_by_row.h
index 12d726187..3d223c985 100644
--- a/src/exchangedb/pg_lookup_kyc_requirement_by_row.h
+++ b/src/exchangedb/pg_lookup_kyc_requirement_by_row.h
@@ -32,6 +32,7 @@
* @param cls closure
* @param requirement_row identifies requirement to look up
* @param[out] requirements provider that must be checked
+ * @param[out] aml_status set to the AML status of the account
* @param[out] h_payto account that must be KYC'ed
* @return database transaction status
*/
@@ -40,5 +41,7 @@ TEH_PG_lookup_kyc_requirement_by_row (
void *cls,
uint64_t requirement_row,
char **requirements,
+ enum TALER_AmlDecisionState *aml_status,
struct TALER_PaytoHashP *h_payto);
+
#endif
diff --git a/src/exchangedb/pg_lookup_records_by_table.c b/src/exchangedb/pg_lookup_records_by_table.c
index 806896e78..2e157360f 100644
--- a/src/exchangedb/pg_lookup_records_by_table.c
+++ b/src/exchangedb/pg_lookup_records_by_table.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet
- Copyright (C) 2020, 2021, 2022 Taler Systems SA
+ Copyright (C) 2020-2023 Taler Systems SA
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -21,6 +21,7 @@
* @file exchangedb/pg_lookup_records_by_table.c
* @brief implementation of lookup_records_by_table
* @author Christian Grothoff
+ * @author Özgür Kesim
*/
#include "platform.h"
#include "taler_error_codes.h"
@@ -231,6 +232,109 @@ lrbt_cb_table_wire_targets (void *cls,
}
+/**
+ * Function called with legitimization_processes table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_legitimization_processes (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
+/**
+ * Function called with legitimization_requirements table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_legitimization_requirements (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_LEGITIMIZATION_REQUIREMENTS
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
/**
* Function called with reserves table entries.
*
@@ -400,6 +504,123 @@ lrbt_cb_table_reserves_close (void *cls,
}
+/**
+ * Function called with reserves_open_requests table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_reserves_open_requests (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct PostgresClosure *pg = ctx->pg;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
+/**
+ * Function called with reserves_open_deposits table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_reserves_open_deposits (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct PostgresClosure *pg = ctx->pg;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
/**
* Function called with reserves_out table entries.
*
@@ -2295,6 +2516,379 @@ lrbt_cb_table_profit_drains (void *cls,
}
+/**
+ * Function called with aml_staff table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_aml_staff (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_AML_STAFF
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
+/**
+ * Function called with aml_history table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_aml_history (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct PostgresClosure *pg = ctx->pg;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_AML_HISTORY
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ td.details.aml_history.new_status
+ = (enum TALER_AmlDecisionState) status32;
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
+/**
+ * Function called with kyc_attributes table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_kyc_attributes (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
+/**
+ * Function called with purse_deletion table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_purse_deletion (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_PURSE_DELETION
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
+/**
+ * Function called with withdraw_age_commitments table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_withdraw_age_commitments (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct PostgresClosure *pg = ctx->pg;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
+/**
+ * Function called with withdraw_age_revealed_coins table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_withdraw_age_revealed_coins (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct LookupRecordsByTableContext *ctx = cls;
+ struct TALER_EXCHANGEDB_TableData td = {
+ .table = TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS
+ };
+
+ for (unsigned int i = 0; ierror = true;
+ return;
+ }
+ ctx->cb (ctx->cb_cls,
+ &td);
+ GNUNET_PQ_cleanup_result (rs);
+ }
+}
+
+
/**
* Assign statement to @a n and PREPARE
* @a sql under name @a n.
@@ -2321,8 +2915,8 @@ TEH_PG_lookup_records_by_table (void *cls,
.cb = cb,
.cb_cls = cb_cls
};
- GNUNET_PQ_PostgresResultHandler rh;
- const char *statement;
+ GNUNET_PQ_PostgresResultHandler rh = NULL;
+ const char *statement = NULL;
enum GNUNET_DB_QueryStatus qs;
switch (table)
@@ -2375,6 +2969,31 @@ TEH_PG_lookup_records_by_table (void *cls,
" ORDER BY wire_target_serial_id ASC;");
rh = &lrbt_cb_table_wire_targets;
break;
+ case TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES:
+ XPREPARE ("select_above_serial_by_table_legitimization_processes",
+ "SELECT"
+ " legitimization_process_serial_id AS serial"
+ ",h_payto"
+ ",expiration_time"
+ ",provider_section"
+ ",provider_user_id"
+ ",provider_legitimization_id"
+ " FROM legitimization_processes"
+ " WHERE legitimization_process_serial_id > $1"
+ " ORDER BY legitimization_process_serial_id ASC;");
+ rh = &lrbt_cb_table_legitimization_processes;
+ break;
+ case TALER_EXCHANGEDB_RT_LEGITIMIZATION_REQUIREMENTS:
+ XPREPARE ("select_above_serial_by_table_legitimization_requirements",
+ "SELECT"
+ " legitimization_requirement_serial_id AS serial"
+ ",h_payto"
+ ",required_checks"
+ " FROM legitimization_requirements"
+ " WHERE legitimization_requirement_serial_id > $1"
+ " ORDER BY legitimization_requirement_serial_id ASC;");
+ rh = &lrbt_cb_table_legitimization_requirements;
+ break;
case TALER_EXCHANGEDB_RT_RESERVES:
XPREPARE ("select_above_serial_by_table_reserves",
"SELECT"
@@ -2420,6 +3039,37 @@ TEH_PG_lookup_records_by_table (void *cls,
" ORDER BY close_uuid ASC;");
rh = &lrbt_cb_table_reserves_close;
break;
+ case TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS:
+ XPREPARE ("select_above_serial_by_table_reserves_open_requests",
+ "SELECT"
+ " open_request_uuid AS serial"
+ ",reserve_pub"
+ ",request_timestamp"
+ ",expiration_date"
+ ",reserve_sig"
+ ",reserve_payment_val"
+ ",reserve_payment_frac"
+ ",requested_purse_limit"
+ " FROM reserves_open_requests"
+ " WHERE open_request_uuid > $1"
+ " ORDER BY open_request_uuid ASC;");
+ rh = &lrbt_cb_table_reserves_open_requests;
+ break;
+ case TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS:
+ XPREPARE ("select_above_serial_by_table_reserves_open_deposits",
+ "SELECT"
+ " reserves_open_deposit_uuid AS serial"
+ ",reserve_sig"
+ ",reserve_pub"
+ ",coin_pub"
+ ",coin_sig"
+ ",contribution_val"
+ ",contribution_frac"
+ " FROM reserves_open_deposits"
+ " WHERE reserves_open_deposit_uuid > $1"
+ " ORDER BY reserves_open_deposit_uuid ASC;");
+ rh = &lrbt_cb_table_reserves_open_deposits;
+ break;
case TALER_EXCHANGEDB_RT_RESERVES_OUT:
XPREPARE ("select_above_serial_by_table_reserves_out",
"SELECT"
@@ -2885,7 +3535,103 @@ TEH_PG_lookup_records_by_table (void *cls,
" ORDER BY profit_drain_serial_id ASC;");
rh = &lrbt_cb_table_profit_drains;
break;
- default:
+
+ case TALER_EXCHANGEDB_RT_AML_STAFF:
+ XPREPARE ("select_above_serial_by_table_aml_staff",
+ "SELECT"
+ " aml_staff_uuid"
+ ",decider_pub"
+ ",master_sig"
+ ",decider_name"
+ ",is_active"
+ ",read_only"
+ ",last_change"
+ " FROM aml_staff"
+ " WHERE aml_staff_uuid > $1"
+ " ORDER BY aml_staff_uuid ASC;");
+ rh = &lrbt_cb_table_aml_staff;
+ break;
+ case TALER_EXCHANGEDB_RT_AML_HISTORY:
+ XPREPARE ("select_above_serial_by_table_aml_history",
+ "SELECT"
+ " aml_history_serial_id"
+ ",h_payto"
+ ",new_threshold_val"
+ ",new_threshold_frac"
+ ",new_status"
+ ",decision_time"
+ ",justification"
+ ",kyc_requirements"
+ ",kyc_req_row"
+ ",decider_pub"
+ ",decider_sig"
+ " FROM aml_history"
+ " WHERE aml_history_serial_id > $1"
+ " ORDER BY aml_history_serial_id ASC;");
+ rh = &lrbt_cb_table_aml_history;
+ break;
+ case TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES:
+ XPREPARE ("select_above_serial_by_table_kyc_attributes",
+ "SELECT"
+ " kyc_attributes_serial_id"
+ ",h_payto"
+ ",kyc_prox"
+ ",provider"
+ ",birthdate"
+ ",collection_time"
+ ",expiration_time"
+ ",encrypted_attributes"
+ " FROM kyc_attributes"
+ " WHERE kyc_attributes_serial_id > $1"
+ " ORDER BY kyc_attributes_serial_id ASC;");
+ rh = &lrbt_cb_table_kyc_attributes;
+ break;
+ case TALER_EXCHANGEDB_RT_PURSE_DELETION:
+ XPREPARE ("select_above_serial_by_table_purse_deletion",
+ "SELECT"
+ " purse_deletion_serial_id"
+ ",purse_pub"
+ ",purse_sig"
+ " FROM purse_deletion"
+ " WHERE purse_deletion_serial_id > $1"
+ " ORDER BY purse_deletion_serial_id ASC;");
+ rh = &lrbt_cb_table_purse_deletion;
+ break;
+ case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS:
+ XPREPARE ("select_above_serial_by_table_withdraw_age_commitments",
+ "SELECT"
+ " withdraw_age_commitment_id"
+ ",h_commitment"
+ ",amount_with_fee_val"
+ ",amount_with_fee_frac"
+ ",max_age"
+ ",reserve_pub"
+ ",reserve_sig"
+ ",noreveal_index"
+ " FROM withdraw_age_commitments"
+ " WHERE withdraw_age_commitment_id > $1"
+ " ORDER BY withdraw_age_commitment_id ASC;");
+ rh = &lrbt_cb_table_withdraw_age_commitments;
+ break;
+ case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS:
+ XPREPARE ("select_above_serial_by_table_withdraw_age_revealed_coins",
+ "SELECT"
+ " withdraw_age_revealed_coins_serial_id"
+ ",h_commitment"
+ ",freshcoin_index"
+ ",denominations_serial"
+ ",coin_ev"
+ ",h_coin_ev"
+ ",ev_sig"
+ ",ewv"
+ " FROM withdraw_age_revealed_coins"
+ " WHERE withdraw_age_revealed_coins_serial_id > $1"
+ " ORDER BY withdraw_age_revealed_coins_serial_id ASC;");
+ rh = &lrbt_cb_table_withdraw_age_revealed_coins;
+ break;
+ }
+ if (NULL == rh)
+ {
GNUNET_break (0);
return GNUNET_DB_STATUS_HARD_ERROR;
}
diff --git a/src/exchangedb/pg_lookup_serial_by_table.c b/src/exchangedb/pg_lookup_serial_by_table.c
index 7e150cd28..c98b4539e 100644
--- a/src/exchangedb/pg_lookup_serial_by_table.c
+++ b/src/exchangedb/pg_lookup_serial_by_table.c
@@ -390,6 +390,60 @@ TEH_PG_lookup_serial_by_table (void *cls,
" LIMIT 1;");
statement = "select_serial_by_table_profit_drains";
break;
+ case TALER_EXCHANGEDB_RT_AML_STAFF:
+ XPREPARE ("select_serial_by_table_aml_staff",
+ "SELECT"
+ " aml_staff_uuid AS serial"
+ " FROM aml_staff"
+ " ORDER BY aml_staff_uuid DESC"
+ " LIMIT 1;");
+ statement = "select_serial_by_table_aml_staff";
+ break;
+ case TALER_EXCHANGEDB_RT_AML_HISTORY:
+ XPREPARE ("select_serial_by_table_aml_history",
+ "SELECT"
+ " aml_history_serial_id AS serial"
+ " FROM aml_history"
+ " ORDER BY aml_history_serial_id DESC"
+ " LIMIT 1;");
+ statement = "select_serial_by_table_aml_history";
+ break;
+ case TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES:
+ XPREPARE ("select_serial_by_table_kyc_attributes",
+ "SELECT"
+ " kyc_attributes_serial_id AS serial"
+ " FROM kyc_attributes"
+ " ORDER BY kyc_attributes_serial_id DESC"
+ " LIMIT 1;");
+ statement = "select_serial_by_table_kyc_attributes";
+ break;
+ case TALER_EXCHANGEDB_RT_PURSE_DELETION:
+ XPREPARE ("select_serial_by_table_purse_deletion",
+ "SELECT"
+ " purse_deletion_serial_id AS serial"
+ " FROM purse_deletion"
+ " ORDER BY purse_deletion_serial_id DESC"
+ " LIMIT 1;");
+ statement = "select_serial_by_table_purse_deletion";
+ break;
+ case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS:
+ XPREPARE ("select_serial_by_table_withdraw_age_commitments",
+ "SELECT"
+ " withdraw_age_commitment_id AS serial"
+ " FROM withdraw_age_commitments"
+ " ORDER BY withdraw_age_commitment_id DESC"
+ " LIMIT 1;");
+ statement = "select_serial_by_table_withdraw_age_commitments";
+ break;
+ case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS:
+ XPREPARE ("select_serial_by_table_withdraw_age_revealed_coins",
+ "SELECT"
+ " withdraw_age_revealed_coins_id AS serial"
+ " FROM withdraw_age_revealed_coins"
+ " ORDER BY withdraw_age_revealed_coins_id DESC"
+ " LIMIT 1;");
+ statement = "select_serial_by_table_withdraw_age_revealed_coins";
+ break;
}
if (NULL == statement)
{
diff --git a/src/exchangedb/pg_lookup_signing_key.c b/src/exchangedb/pg_lookup_signing_key.c
index 3f31a6f49..3803d114f 100644
--- a/src/exchangedb/pg_lookup_signing_key.c
+++ b/src/exchangedb/pg_lookup_signing_key.c
@@ -62,4 +62,3 @@ TEH_PG_lookup_signing_key (
params,
rs);
}
-
diff --git a/src/exchangedb/pg_lookup_wire_timestamp.c b/src/exchangedb/pg_lookup_wire_timestamp.c
index 19e915d48..17dffc706 100644
--- a/src/exchangedb/pg_lookup_wire_timestamp.c
+++ b/src/exchangedb/pg_lookup_wire_timestamp.c
@@ -28,8 +28,8 @@
enum GNUNET_DB_QueryStatus
TEH_PG_lookup_wire_timestamp (void *cls,
- const char *payto_uri,
- struct GNUNET_TIME_Timestamp *last_date)
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp *last_date)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
diff --git a/src/exchangedb/pg_lookup_wire_timestamp.h b/src/exchangedb/pg_lookup_wire_timestamp.h
index 069dd940c..f2ee117de 100644
--- a/src/exchangedb/pg_lookup_wire_timestamp.h
+++ b/src/exchangedb/pg_lookup_wire_timestamp.h
@@ -34,7 +34,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_lookup_wire_timestamp (void *cls,
- const char *payto_uri,
+ const char *payto_uri,
struct GNUNET_TIME_Timestamp *last_date);
#endif
diff --git a/src/exchangedb/pg_profit_drains_get_pending.c b/src/exchangedb/pg_profit_drains_get_pending.c
index a7044ebb8..f4a5d4517 100644
--- a/src/exchangedb/pg_profit_drains_get_pending.c
+++ b/src/exchangedb/pg_profit_drains_get_pending.c
@@ -57,7 +57,7 @@ TEH_PG_profit_drains_get_pending (
master_sig),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_profit_drains_get_pending() */
+ /* Used in #postgres_profit_drains_get_pending() */
PREPARE (pg,
"get_ready_profit_drain",
"SELECT"
diff --git a/src/exchangedb/pg_profit_drains_set_finished.c b/src/exchangedb/pg_profit_drains_set_finished.c
index b70af31fe..f0de27945 100644
--- a/src/exchangedb/pg_profit_drains_set_finished.c
+++ b/src/exchangedb/pg_profit_drains_set_finished.c
@@ -38,18 +38,12 @@ TEH_PG_profit_drains_set_finished (
};
PREPARE (pg,
- "drain_profit_set_finished",
- "UPDATE profit_drains"
- " SET"
- " executed=TRUE"
- " WHERE profit_drain_serial_id=$1;");
+ "drain_profit_set_finished",
+ "UPDATE profit_drains"
+ " SET"
+ " executed=TRUE"
+ " WHERE profit_drain_serial_id=$1;");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"drain_profit_set_finished",
params);
}
-
-
-
-
-
-
diff --git a/src/exchangedb/pg_release_revolving_shard.c b/src/exchangedb/pg_release_revolving_shard.c
index f176972b6..43e45c4bc 100644
--- a/src/exchangedb/pg_release_revolving_shard.c
+++ b/src/exchangedb/pg_release_revolving_shard.c
@@ -27,9 +27,9 @@
enum GNUNET_DB_QueryStatus
TEH_PG_release_revolving_shard (void *cls,
- const char *job_name,
- uint32_t start_row,
- uint32_t end_row)
+ const char *job_name,
+ uint32_t start_row,
+ uint32_t end_row)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
diff --git a/src/exchangedb/pg_release_revolving_shard.h b/src/exchangedb/pg_release_revolving_shard.h
index f1712f538..ea65ab605 100644
--- a/src/exchangedb/pg_release_revolving_shard.h
+++ b/src/exchangedb/pg_release_revolving_shard.h
@@ -37,8 +37,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_release_revolving_shard (void *cls,
- const char *job_name,
- uint32_t start_row,
+ const char *job_name,
+ uint32_t start_row,
uint32_t end_row);
#endif
diff --git a/src/exchangedb/pg_reserves_get.c b/src/exchangedb/pg_reserves_get.c
index bea0022dd..d081ca00f 100644
--- a/src/exchangedb/pg_reserves_get.c
+++ b/src/exchangedb/pg_reserves_get.c
@@ -27,7 +27,7 @@
enum GNUNET_DB_QueryStatus
TEH_PG_reserves_get (void *cls,
- struct TALER_EXCHANGEDB_Reserve *reserve)
+ struct TALER_EXCHANGEDB_Reserve *reserve)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -43,7 +43,7 @@ TEH_PG_reserves_get (void *cls,
&reserve->gc),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_reserves_get() */
+ /* Used in #postgres_reserves_get() */
PREPARE (pg,
"reserves_get",
"SELECT"
diff --git a/src/exchangedb/pg_reserves_get_origin.c b/src/exchangedb/pg_reserves_get_origin.c
index fd6c56586..55d3179d1 100644
--- a/src/exchangedb/pg_reserves_get_origin.c
+++ b/src/exchangedb/pg_reserves_get_origin.c
@@ -50,7 +50,7 @@ TEH_PG_reserves_get_origin (
" wire_source_h_payto"
" FROM reserves_in"
" WHERE reserve_pub=$1");
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_h_wire_source_of_reserve",
params,
rs);
diff --git a/src/exchangedb/pg_reserves_in_insert.c b/src/exchangedb/pg_reserves_in_insert.c
index 1c578478b..691c57d38 100644
--- a/src/exchangedb/pg_reserves_in_insert.c
+++ b/src/exchangedb/pg_reserves_in_insert.c
@@ -55,55 +55,106 @@ compute_notify_on_reserve (const struct TALER_ReservePublicKeyP *reserve_pub)
}
+/**
+ * Record we keep per reserve to process.
+ */
+struct ReserveRecord
+{
+ /**
+ * Details about reserve to insert (input).
+ */
+ const struct TALER_EXCHANGEDB_ReserveInInfo *reserve;
+
+ /**
+ * Hash of the payto URI in @e reserve.
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ /**
+ * Notification to trigger on the reserve (input).
+ */
+ char *notify_s;
+
+ /**
+ * Set to UUID of the reserve (output);
+ */
+ uint64_t reserve_uuid;
+
+ /**
+ * Set to true if the transaction was an exact duplicate (output).
+ */
+ bool transaction_duplicate;
+
+ /**
+ * Set to true if the transaction conflicted with an existing reserve (output)
+ * and needs to be re-done with an UPDATE.
+ */
+ bool conflicts;
+};
+
+
+/**
+ * Generate the SQL parameters to insert the record @a rr at
+ * index @a index
+ */
+#define RR_QUERY_PARAM(rr,index) \
+ GNUNET_PQ_query_param_auto_from_type (rr[index].reserve->reserve_pub), \
+ GNUNET_PQ_query_param_uint64 (&rr[index].reserve->wire_reference), \
+ TALER_PQ_query_param_amount (rr[index].reserve->balance), \
+ GNUNET_PQ_query_param_string (rr[index].reserve->exchange_account_name), \
+ GNUNET_PQ_query_param_timestamp (&rr[index].reserve->execution_time), \
+ GNUNET_PQ_query_param_auto_from_type (&rr[index].h_payto), \
+ GNUNET_PQ_query_param_string (rr[index].reserve->sender_account_details), \
+ GNUNET_PQ_query_param_string (rr[index].notify_s)
+
+
+/**
+ * Generate the SQL parameters to obtain results for record @a rr at
+ * index @a index
+ */
+#define RR_RESULT_PARAM(rr,index) \
+ GNUNET_PQ_result_spec_bool ("transaction_duplicate" TALER_S (index), \
+ &rr[index].transaction_duplicate), \
+ GNUNET_PQ_result_spec_allow_null ( \
+ GNUNET_PQ_result_spec_uint64 ("reserve_uuid" TALER_S (index), \
+ &rr[index].reserve_uuid), \
+ &rr[index].conflicts)
+
+
+/**
+ * Insert 1 reserve record @a rr into the database.
+ *
+ * @param pg database context
+ * @param gc gc timestamp to use
+ * @param reserve_expiration expiration time to use
+ * @param[in,out] rr array of reserve details to use and update
+ * @return database transaction status
+ */
static enum GNUNET_DB_QueryStatus
insert1 (struct PostgresClosure *pg,
- const struct TALER_EXCHANGEDB_ReserveInInfo reserves[1],
- struct GNUNET_TIME_Timestamp expiry,
struct GNUNET_TIME_Timestamp gc,
- struct TALER_PaytoHashP h_payto,
- char *const *notify_s,
struct GNUNET_TIME_Timestamp reserve_expiration,
- bool *transaction_duplicate,
- bool *conflict,
- uint64_t *reserve_uuid,
- enum GNUNET_DB_QueryStatus results[1])
+ struct ReserveRecord *rr)
{
enum GNUNET_DB_QueryStatus qs;
- PREPARE (pg,
- "batch1_reserve_create",
- "SELECT "
- " out_reserve_found AS conflicted"
- ",transaction_duplicate"
- ",ruuid AS reserve_uuid"
- " FROM exchange_do_batch_reserves_in_insert"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12);");
-
struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserves[0].reserve_pub),
- GNUNET_PQ_query_param_timestamp (&expiry),
GNUNET_PQ_query_param_timestamp (&gc),
- GNUNET_PQ_query_param_uint64 (&reserves[0].wire_reference),
- TALER_PQ_query_param_amount (reserves[0].balance),
- GNUNET_PQ_query_param_string (reserves[0].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[0].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[0].sender_account_details),
GNUNET_PQ_query_param_timestamp (&reserve_expiration),
- GNUNET_PQ_query_param_string (notify_s[0]),
+ RR_QUERY_PARAM (rr, 0),
GNUNET_PQ_query_param_end
};
struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("conflicted",
- &conflict[0]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate",
- &transaction_duplicate[0]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
- &reserve_uuid[0]),
+ RR_RESULT_PARAM (rr, 0),
GNUNET_PQ_result_spec_end
};
- TALER_payto_hash (reserves[0].sender_account_details,
- &h_payto);
+ PREPARE (pg,
+ "batch1_reserve_create",
+ "SELECT "
+ " transaction_duplicate0 AS transaction_duplicate0"
+ ",ruuid0 AS reserve_uuid0"
+ " FROM exchange_do_batch_reserves_in_insert"
+ " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"batch1_reserve_create",
params,
@@ -113,537 +164,256 @@ insert1 (struct PostgresClosure *pg,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to create reserves 1(%d)\n",
qs);
- results[0] = qs;
return qs;
}
GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
- if ((! conflict[0]) && transaction_duplicate[0])
+ if ((! rr[0].conflicts) && rr[0].transaction_duplicate)
{
GNUNET_break (0);
TEH_PG_rollback (pg);
- results[0] = GNUNET_DB_STATUS_HARD_ERROR;
return GNUNET_DB_STATUS_HARD_ERROR;
}
- results[0] = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
return qs;
}
+/**
+ * Insert 2 reserve records @a rr into the database.
+ *
+ * @param pg database context
+ * @param gc gc timestamp to use
+ * @param reserve_expiration expiration time to use
+ * @param[in,out] rr array of reserve details to use and update
+ * @return database transaction status
+ */
static enum GNUNET_DB_QueryStatus
insert2 (struct PostgresClosure *pg,
- const struct TALER_EXCHANGEDB_ReserveInInfo reserves[2],
- struct GNUNET_TIME_Timestamp expiry,
struct GNUNET_TIME_Timestamp gc,
- struct TALER_PaytoHashP h_payto,
- char *const*notify_s,
struct GNUNET_TIME_Timestamp reserve_expiration,
- bool *transaction_duplicate,
- bool *conflict,
- uint64_t *reserve_uuid,
- enum GNUNET_DB_QueryStatus results[1])
+ struct ReserveRecord *rr)
{
- enum GNUNET_DB_QueryStatus qs1;
- PREPARE (pg,
- "batch2_reserve_create",
- "SELECT "
- "out_reserve_found AS conflicted"
- ",out_reserve_found2 AS conflicted2"
- ",transaction_duplicate"
- ",transaction_duplicate2"
- ",ruuid AS reserve_uuid"
- ",ruuid2 AS reserve_uuid2"
- " FROM exchange_do_batch2_reserves_insert"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22);");
-
+ enum GNUNET_DB_QueryStatus qs;
struct GNUNET_PQ_QueryParam params[] = {
-
- GNUNET_PQ_query_param_auto_from_type (reserves[0].reserve_pub),
- GNUNET_PQ_query_param_timestamp (&expiry),
GNUNET_PQ_query_param_timestamp (&gc),
- GNUNET_PQ_query_param_uint64 (&reserves[0].wire_reference),
- TALER_PQ_query_param_amount (reserves[0].balance),
- GNUNET_PQ_query_param_string (reserves[0].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[0].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[0].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
- GNUNET_PQ_query_param_string (notify_s[0]),
- GNUNET_PQ_query_param_string (notify_s[1]),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[1].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[1].wire_reference),
- TALER_PQ_query_param_amount (reserves[1].balance),
- GNUNET_PQ_query_param_string (reserves[1].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[1].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[1].sender_account_details),
GNUNET_PQ_query_param_timestamp (&reserve_expiration),
+ RR_QUERY_PARAM (rr, 0),
+ RR_QUERY_PARAM (rr, 1),
GNUNET_PQ_query_param_end
};
struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("conflicted",
- &conflict[0]),
- GNUNET_PQ_result_spec_bool ("conflicted2",
- &conflict[1]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate",
- &transaction_duplicate[0]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate2",
- &transaction_duplicate[1]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
- &reserve_uuid[0]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid2",
- &reserve_uuid[1]),
+ RR_RESULT_PARAM (rr, 0),
+ RR_RESULT_PARAM (rr, 1),
GNUNET_PQ_result_spec_end
};
- TALER_payto_hash (reserves[0].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[1].sender_account_details,
- &h_payto);
-
-
- qs1 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "batch2_reserve_create",
- params,
- rs);
- if (qs1 < 0)
+ PREPARE (pg,
+ "batch2_reserve_create",
+ "SELECT"
+ " transaction_duplicate0"
+ ",transaction_duplicate1"
+ ",ruuid0 AS reserve_uuid0"
+ ",ruuid1 AS reserve_uuid1"
+ " FROM exchange_do_batch2_reserves_insert"
+ " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "batch2_reserve_create",
+ params,
+ rs);
+ if (qs < 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to create reserves 2(%d)\n",
- qs1);
- results[0] = qs1;
- return qs1;
+ qs);
+ return qs;
}
-
- GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs1);
- /* results[i] = (transaction_duplicate)
- ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
- : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;*/
-
- if (
- ((! conflict[0]) && (transaction_duplicate[0]))
- || ((! conflict[1]) && (transaction_duplicate[1]))
- )
+ GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
+ for (unsigned int i = 0; i<2; i++)
{
- GNUNET_break (0);
- TEH_PG_rollback (pg); // ROLLBACK
- results[0] = GNUNET_DB_STATUS_HARD_ERROR;
- return GNUNET_DB_STATUS_HARD_ERROR;
+ if ((! rr[i].conflicts) && (rr[i].transaction_duplicate))
+ {
+ GNUNET_break (0);
+ TEH_PG_rollback (pg);
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
}
- results[0] = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- return qs1;
+ return qs;
}
+/**
+ * Insert 4 reserve records @a rr into the database.
+ *
+ * @param pg database context
+ * @param gc gc timestamp to use
+ * @param reserve_expiration expiration time to use
+ * @param[in,out] rr array of reserve details to use and update
+ * @return database transaction status
+ */
static enum GNUNET_DB_QueryStatus
insert4 (struct PostgresClosure *pg,
- const struct TALER_EXCHANGEDB_ReserveInInfo reserves[4],
- struct GNUNET_TIME_Timestamp expiry,
struct GNUNET_TIME_Timestamp gc,
- struct TALER_PaytoHashP h_payto,
- char *const*notify_s,
struct GNUNET_TIME_Timestamp reserve_expiration,
- bool *transaction_duplicate,
- bool *conflict,
- uint64_t *reserve_uuid,
- enum GNUNET_DB_QueryStatus results[1])
+ struct ReserveRecord *rr)
{
- enum GNUNET_DB_QueryStatus qs3;
- PREPARE (pg,
- "batch4_reserve_create",
- "SELECT "
- "out_reserve_found AS conflicted"
- ",out_reserve_found2 AS conflicted2"
- ",out_reserve_found3 AS conflicted3"
- ",out_reserve_found4 AS conflicted4"
- ",transaction_duplicate"
- ",transaction_duplicate2"
- ",transaction_duplicate3"
- ",transaction_duplicate4"
- ",ruuid AS reserve_uuid"
- ",ruuid2 AS reserve_uuid2"
- ",ruuid3 AS reserve_uuid3"
- ",ruuid4 AS reserve_uuid4"
- " FROM exchange_do_batch4_reserves_insert"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39, $40, $41,$42);");
-
+ enum GNUNET_DB_QueryStatus qs;
struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserves[0].reserve_pub),
- GNUNET_PQ_query_param_timestamp (&expiry),
GNUNET_PQ_query_param_timestamp (&gc),
- GNUNET_PQ_query_param_uint64 (&reserves[0].wire_reference),
- TALER_PQ_query_param_amount (reserves[0].balance),
- GNUNET_PQ_query_param_string (reserves[0].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[0].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[0].sender_account_details),
GNUNET_PQ_query_param_timestamp (&reserve_expiration),
- GNUNET_PQ_query_param_string (notify_s[0]),
- GNUNET_PQ_query_param_string (notify_s[1]),
- GNUNET_PQ_query_param_string (notify_s[2]),
- GNUNET_PQ_query_param_string (notify_s[3]),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[1].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[1].wire_reference),
- TALER_PQ_query_param_amount (reserves[1].balance),
- GNUNET_PQ_query_param_string (reserves[1].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[1].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[1].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[2].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[2].wire_reference),
- TALER_PQ_query_param_amount (reserves[2].balance),
- GNUNET_PQ_query_param_string (reserves[2].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[2].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[2].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[3].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[3].wire_reference),
- TALER_PQ_query_param_amount (reserves[3].balance),
- GNUNET_PQ_query_param_string (reserves[3].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[3].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[3].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
+ RR_QUERY_PARAM (rr, 0),
+ RR_QUERY_PARAM (rr, 1),
+ RR_QUERY_PARAM (rr, 2),
+ RR_QUERY_PARAM (rr, 3),
GNUNET_PQ_query_param_end
};
-
struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("conflicted",
- &conflict[0]),
- GNUNET_PQ_result_spec_bool ("conflicted2",
- &conflict[1]),
- GNUNET_PQ_result_spec_bool ("conflicted3",
- &conflict[2]),
- GNUNET_PQ_result_spec_bool ("conflicted4",
- &conflict[3]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate",
- &transaction_duplicate[0]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate2",
- &transaction_duplicate[1]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate3",
- &transaction_duplicate[2]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate4",
- &transaction_duplicate[3]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
- &reserve_uuid[0]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid2",
- &reserve_uuid[1]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid3",
- &reserve_uuid[2]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid4",
- &reserve_uuid[3]),
+ RR_RESULT_PARAM (rr, 0),
+ RR_RESULT_PARAM (rr, 1),
+ RR_RESULT_PARAM (rr, 2),
+ RR_RESULT_PARAM (rr, 3),
GNUNET_PQ_result_spec_end
};
- TALER_payto_hash (reserves[0].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[1].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[2].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[3].sender_account_details,
- &h_payto);
-
- qs3 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "batch4_reserve_create",
- params,
- rs);
- if (qs3 < 0)
+ PREPARE (pg,
+ "batch4_reserve_create",
+ "SELECT"
+ " transaction_duplicate0"
+ ",transaction_duplicate1"
+ ",transaction_duplicate2"
+ ",transaction_duplicate3"
+ ",ruuid0 AS reserve_uuid0"
+ ",ruuid1 AS reserve_uuid1"
+ ",ruuid2 AS reserve_uuid2"
+ ",ruuid3 AS reserve_uuid3"
+ " FROM exchange_do_batch4_reserves_insert"
+ " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "batch4_reserve_create",
+ params,
+ rs);
+ if (qs < 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to create reserves4 (%d)\n",
- qs3);
- results[0] = qs3;
- return qs3;
+ qs);
+ return qs;
}
- GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs3);
-
- if (
- ((! conflict[0]) && (transaction_duplicate[0]))
- || ((! conflict[1]) && (transaction_duplicate[1]))
- || ((! conflict[2]) && (transaction_duplicate[2]))
- || ((! conflict[3]) && (transaction_duplicate[3]))
- )
+ GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
+ for (unsigned int i = 0; i<4; i++)
{
- GNUNET_break (0);
- TEH_PG_rollback (pg);
- results[0] = GNUNET_DB_STATUS_HARD_ERROR;
- return GNUNET_DB_STATUS_HARD_ERROR;
+ if ((! rr[i].conflicts) && (rr[i].transaction_duplicate))
+ {
+ GNUNET_break (0);
+ TEH_PG_rollback (pg);
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
}
- results[0] = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- return qs3;
+ return qs;
}
+/**
+ * Insert 8 reserve records @a rr into the database.
+ *
+ * @param pg database context
+ * @param gc gc timestamp to use
+ * @param reserve_expiration expiration time to use
+ * @param[in,out] rr array of reserve details to use and update
+ * @return database transaction status
+ */
static enum GNUNET_DB_QueryStatus
insert8 (struct PostgresClosure *pg,
- const struct TALER_EXCHANGEDB_ReserveInInfo reserves[8],
- struct GNUNET_TIME_Timestamp expiry,
struct GNUNET_TIME_Timestamp gc,
- struct TALER_PaytoHashP h_payto,
- char *const*notify_s,
struct GNUNET_TIME_Timestamp reserve_expiration,
- bool *transaction_duplicate,
- bool *conflict,
- uint64_t *reserve_uuid,
- enum GNUNET_DB_QueryStatus results[1])
+ struct ReserveRecord *rr)
{
- enum GNUNET_DB_QueryStatus qs3;
+ enum GNUNET_DB_QueryStatus qs;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_timestamp (&gc),
+ GNUNET_PQ_query_param_timestamp (&reserve_expiration),
+ RR_QUERY_PARAM (rr, 0),
+ RR_QUERY_PARAM (rr, 1),
+ RR_QUERY_PARAM (rr, 2),
+ RR_QUERY_PARAM (rr, 3),
+ RR_QUERY_PARAM (rr, 4),
+ RR_QUERY_PARAM (rr, 5),
+ RR_QUERY_PARAM (rr, 6),
+ RR_QUERY_PARAM (rr, 7),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ RR_RESULT_PARAM (rr, 0),
+ RR_RESULT_PARAM (rr, 1),
+ RR_RESULT_PARAM (rr, 2),
+ RR_RESULT_PARAM (rr, 3),
+ RR_RESULT_PARAM (rr, 4),
+ RR_RESULT_PARAM (rr, 5),
+ RR_RESULT_PARAM (rr, 6),
+ RR_RESULT_PARAM (rr, 7),
+ GNUNET_PQ_result_spec_end
+ };
+
PREPARE (pg,
"batch8_reserve_create",
- "SELECT "
- "out_reserve_found AS conflicted"
- ",out_reserve_found2 AS conflicted2"
- ",out_reserve_found3 AS conflicted3"
- ",out_reserve_found4 AS conflicted4"
- ",out_reserve_found5 AS conflicted5"
- ",out_reserve_found6 AS conflicted6"
- ",out_reserve_found7 AS conflicted7"
- ",out_reserve_found8 AS conflicted8"
- ",transaction_duplicate"
+ "SELECT"
+ " transaction_duplicate0"
+ ",transaction_duplicate1"
",transaction_duplicate2"
",transaction_duplicate3"
",transaction_duplicate4"
",transaction_duplicate5"
",transaction_duplicate6"
",transaction_duplicate7"
- ",transaction_duplicate8"
- ",ruuid AS reserve_uuid"
+ ",ruuid0 AS reserve_uuid0"
+ ",ruuid1 AS reserve_uuid1"
",ruuid2 AS reserve_uuid2"
",ruuid3 AS reserve_uuid3"
",ruuid4 AS reserve_uuid4"
",ruuid5 AS reserve_uuid5"
",ruuid6 AS reserve_uuid6"
",ruuid7 AS reserve_uuid7"
- ",ruuid8 AS reserve_uuid8"
" FROM exchange_do_batch8_reserves_insert"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39, $40, $41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$80,$81,$82);");
+ " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39, $40, $41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$70,$71,$72,$73,$74);");
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserves[0].reserve_pub),
- GNUNET_PQ_query_param_timestamp (&expiry),
- GNUNET_PQ_query_param_timestamp (&gc),
- GNUNET_PQ_query_param_uint64 (&reserves[0].wire_reference),
- TALER_PQ_query_param_amount (reserves[0].balance),
- GNUNET_PQ_query_param_string (reserves[0].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[0].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[0].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
- GNUNET_PQ_query_param_string (notify_s[0]),
- GNUNET_PQ_query_param_string (notify_s[1]),
- GNUNET_PQ_query_param_string (notify_s[2]),
- GNUNET_PQ_query_param_string (notify_s[3]),
- GNUNET_PQ_query_param_string (notify_s[4]),
- GNUNET_PQ_query_param_string (notify_s[5]),
- GNUNET_PQ_query_param_string (notify_s[6]),
- GNUNET_PQ_query_param_string (notify_s[7]),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[1].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[1].wire_reference),
- TALER_PQ_query_param_amount (reserves[1].balance),
- GNUNET_PQ_query_param_string (reserves[1].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[1].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[1].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[2].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[2].wire_reference),
- TALER_PQ_query_param_amount (reserves[2].balance),
- GNUNET_PQ_query_param_string (reserves[2].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[2].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[2].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[3].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[3].wire_reference),
- TALER_PQ_query_param_amount (reserves[3].balance),
- GNUNET_PQ_query_param_string (reserves[3].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[3].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[3].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[4].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[4].wire_reference),
- TALER_PQ_query_param_amount (reserves[4].balance),
- GNUNET_PQ_query_param_string (reserves[4].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[4].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[4].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[5].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[5].wire_reference),
- TALER_PQ_query_param_amount (reserves[5].balance),
- GNUNET_PQ_query_param_string (reserves[5].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[5].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[5].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[6].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[6].wire_reference),
- TALER_PQ_query_param_amount (reserves[6].balance),
- GNUNET_PQ_query_param_string (reserves[6].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[6].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[6].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_auto_from_type (reserves[7].reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserves[7].wire_reference),
- TALER_PQ_query_param_amount (reserves[7].balance),
- GNUNET_PQ_query_param_string (reserves[7].exchange_account_name),
- GNUNET_PQ_query_param_timestamp (&reserves[7].execution_time),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_string (reserves[7].sender_account_details),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
- GNUNET_PQ_query_param_end
- };
-
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("conflicted",
- &conflict[0]),
- GNUNET_PQ_result_spec_bool ("conflicted2",
- &conflict[1]),
- GNUNET_PQ_result_spec_bool ("conflicted3",
- &conflict[2]),
- GNUNET_PQ_result_spec_bool ("conflicted4",
- &conflict[3]),
- GNUNET_PQ_result_spec_bool ("conflicted5",
- &conflict[4]),
- GNUNET_PQ_result_spec_bool ("conflicted6",
- &conflict[5]),
- GNUNET_PQ_result_spec_bool ("conflicted7",
- &conflict[6]),
- GNUNET_PQ_result_spec_bool ("conflicted8",
- &conflict[7]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate",
- &transaction_duplicate[0]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate2",
- &transaction_duplicate[1]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate3",
- &transaction_duplicate[2]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate4",
- &transaction_duplicate[3]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate5",
- &transaction_duplicate[4]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate6",
- &transaction_duplicate[5]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate7",
- &transaction_duplicate[6]),
- GNUNET_PQ_result_spec_bool ("transaction_duplicate8",
- &transaction_duplicate[7]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
- &reserve_uuid[0]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid2",
- &reserve_uuid[1]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid3",
- &reserve_uuid[2]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid4",
- &reserve_uuid[3]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid5",
- &reserve_uuid[4]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid6",
- &reserve_uuid[5]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid7",
- &reserve_uuid[6]),
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid8",
- &reserve_uuid[7]),
- GNUNET_PQ_result_spec_end
- };
-
- TALER_payto_hash (reserves[0].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[1].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[2].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[3].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[4].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[5].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[6].sender_account_details,
- &h_payto);
- TALER_payto_hash (reserves[7].sender_account_details,
- &h_payto);
-
- qs3 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "batch8_reserve_create",
- params,
- rs);
- if (qs3 < 0)
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "batch8_reserve_create",
+ params,
+ rs);
+ if (qs < 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to create reserves8 (%d)\n",
- qs3);
- results[0] = qs3;
- return qs3;
+ qs);
+ return qs;
}
- GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs3);
- /* results[i] = (transaction_duplicate)
- ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
- : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;*/
-
- if (
- ((! conflict[0]) && (transaction_duplicate[0]))
- || ((! conflict[1]) && (transaction_duplicate[1]))
- || ((! conflict[2]) && (transaction_duplicate[2]))
- || ((! conflict[3]) && (transaction_duplicate[3]))
- || ((! conflict[4]) && (transaction_duplicate[4]))
- || ((! conflict[5]) && (transaction_duplicate[5]))
- || ((! conflict[6]) && (transaction_duplicate[6]))
- || ((! conflict[7]) && (transaction_duplicate[7]))
- )
+ GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
+ for (unsigned int i = 0; i<8; i++)
{
- GNUNET_break (0);
- TEH_PG_rollback (pg);
- results[0] = GNUNET_DB_STATUS_HARD_ERROR;
- return GNUNET_DB_STATUS_HARD_ERROR;
+ if ((! rr[i].conflicts) && (rr[i].transaction_duplicate))
+ {
+ GNUNET_break (0);
+ TEH_PG_rollback (pg);
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
}
- results[0] = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- return qs3;
+ return qs;
}
-enum GNUNET_DB_QueryStatus
-TEH_PG_reserves_in_insert (void *cls,
- const struct
- TALER_EXCHANGEDB_ReserveInInfo *reserves,
- unsigned int reserves_length,
- unsigned int batch_size,
- enum GNUNET_DB_QueryStatus *results)
+static enum GNUNET_DB_QueryStatus
+transact (
+ struct PostgresClosure *pg,
+ struct ReserveRecord *rr,
+ unsigned int reserves_length,
+ unsigned int batch_size,
+ enum GNUNET_DB_QueryStatus *results)
{
- struct PostgresClosure *pg = cls;
- enum GNUNET_DB_QueryStatus qs1;
- enum GNUNET_DB_QueryStatus qs2;
- enum GNUNET_DB_QueryStatus qs4;
- enum GNUNET_DB_QueryStatus qs5;
- struct GNUNET_TIME_Timestamp expiry;
- struct GNUNET_TIME_Timestamp gc;
- struct TALER_PaytoHashP h_payto;
- uint64_t reserve_uuid[reserves_length];
- bool transaction_duplicate[reserves_length];
- bool need_update = false;
- bool t_duplicate = false;
struct GNUNET_TIME_Timestamp reserve_expiration
= GNUNET_TIME_relative_to_timestamp (pg->idle_reserve_expiration_time);
- bool conflicts[reserves_length];
- char *notify_s[reserves_length];
+ struct GNUNET_TIME_Timestamp gc
+ = GNUNET_TIME_relative_to_timestamp (pg->legal_reserve_expiration_time);
+ bool need_update = false;
if (GNUNET_OK !=
TEH_PG_preflight (pg))
@@ -652,19 +422,6 @@ TEH_PG_reserves_in_insert (void *cls,
return GNUNET_DB_STATUS_HARD_ERROR;
}
- expiry = GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_absolute_add (reserves->execution_time.abs_time,
- pg->idle_reserve_expiration_time));
- gc = GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
- pg->legal_reserve_expiration_time));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Creating reserve %s with expiration in %s\n",
- TALER_B2S (&(reserves->reserve_pub)),
- GNUNET_STRINGS_relative_time_to_string (
- pg->idle_reserve_expiration_time,
- GNUNET_NO));
-
if (GNUNET_OK !=
TEH_PG_start_read_committed (pg,
"READ_COMMITED"))
@@ -673,156 +430,74 @@ TEH_PG_reserves_in_insert (void *cls,
return GNUNET_DB_STATUS_HARD_ERROR;
}
- /* Optimistically assume this is a new reserve, create balance for the first
- time; we do this before adding the actual transaction to "reserves_in",
- as for a new reserve it can't be a duplicate 'add' operation, and as
- the 'add' operation needs the reserve entry as a foreign key. */
- for (unsigned int i = 0; ireserve_pub);
- }
-
- unsigned int i = 0;
-
- while (i < reserves_length)
- {
- unsigned int bs = GNUNET_MIN (batch_size,
- reserves_length - i);
- if (bs >= 8)
+ while (i < reserves_length)
{
- qs1 = insert8 (pg,
- &reserves[i],
- expiry,
- gc,
- h_payto,
- ¬ify_s[i],
- reserve_expiration,
- &transaction_duplicate[i],
- &conflicts[i],
- &reserve_uuid[i],
- &results[i]);
+ enum GNUNET_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus
+ (*fun)(struct PostgresClosure *pg,
+ struct GNUNET_TIME_Timestamp gc,
+ struct GNUNET_TIME_Timestamp reserve_expiration,
+ struct ReserveRecord *rr);
+ unsigned int lim;
+ unsigned int bs;
- if (qs1<0)
+ bs = GNUNET_MIN (batch_size,
+ reserves_length - i);
+ switch (bs)
+ {
+ case 7:
+ case 6:
+ case 5:
+ case 4:
+ fun = &insert4;
+ lim = 4;
+ break;
+ case 3:
+ case 2:
+ fun = &insert2;
+ lim = 2;
+ break;
+ case 1:
+ fun = &insert1;
+ lim = 1;
+ break;
+ case 0:
+ GNUNET_assert (0);
+ break;
+ default:
+ fun = insert8;
+ lim = 8;
+ break;
+ }
+
+ qs = fun (pg,
+ gc,
+ reserve_expiration,
+ &rr[i]);
+ if (qs < 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to create reserve batch_8 (%d)\n",
- qs1);
- return qs1;
+ "Failed to create reserve batch_%u (%d)\n",
+ lim,
+ qs);
+ results[i] = qs;
+ return qs;
}
- need_update |= conflicts[i];
- need_update |= conflicts[i + 1];
- need_update |= conflicts[i + 2];
- need_update |= conflicts[i + 3];
- need_update |= conflicts[i + 4];
- need_update |= conflicts[i + 5];
- need_update |= conflicts[i + 6];
- need_update |= conflicts[i + 7];
- t_duplicate |= transaction_duplicate[i];
- t_duplicate |= transaction_duplicate[i + 1];
- t_duplicate |= transaction_duplicate[i + 2];
- t_duplicate |= transaction_duplicate[i + 3];
- t_duplicate |= transaction_duplicate[i + 4];
- t_duplicate |= transaction_duplicate[i + 5];
- t_duplicate |= transaction_duplicate[i + 6];
- t_duplicate |= transaction_duplicate[i + 7];
- i += 8;
+ for (unsigned int j = 0; jreserve_pub),
+ GNUNET_PQ_query_param_timestamp (&reserve_expiration),
+ GNUNET_PQ_query_param_uint64 (&rr[i].reserve->wire_reference),
+ TALER_PQ_query_param_amount (rr[i].reserve->balance),
+ GNUNET_PQ_query_param_string (rr[i].reserve->exchange_account_name),
+ GNUNET_PQ_query_param_auto_from_type (&rr[i].h_payto),
+ GNUNET_PQ_query_param_string (rr[i].notify_s),
GNUNET_PQ_query_param_end
};
struct GNUNET_PQ_ResultSpec rs[] = {
@@ -877,17 +548,19 @@ TEH_PG_reserves_in_insert (void *cls,
&duplicate),
GNUNET_PQ_result_spec_end
};
- qs3 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "reserves_update",
- params,
- rs);
- if (qs3<0)
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "reserves_update",
+ params,
+ rs);
+ if (qs < 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to update reserves (%d)\n",
- qs3);
- results[i] = qs3;
- return qs3;
+ qs);
+ results[i] = qs;
+ return qs;
}
results[i] = duplicate
? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
@@ -896,16 +569,49 @@ TEH_PG_reserves_in_insert (void *cls,
}
{
- enum GNUNET_DB_QueryStatus cs;
+ enum GNUNET_DB_QueryStatus cs = TEH_PG_commit (pg);
- cs = TEH_PG_commit (pg);
- if (cs < 0)
+ if (0 > cs)
return cs;
}
-
-exit:
- for (unsigned int i = 0; ireserve = reserve;
+ TALER_payto_hash (reserves->sender_account_details,
+ &rr->h_payto);
+ rr->notify_s = compute_notify_on_reserve (reserve->reserve_pub);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating reserve %s with expiration in %s\n",
+ TALER_B2S (&reserve->reserve_pub),
+ GNUNET_STRINGS_relative_time_to_string (
+ pg->idle_reserve_expiration_time,
+ false));
+ }
+ qs = transact (pg,
+ rrs,
+ reserves_length,
+ batch_size,
+ results);
+ for (unsigned int i = 0; iconn,
"select_contract",
params,
diff --git a/src/exchangedb/pg_select_contract.h b/src/exchangedb/pg_select_contract.h
index a503c8da9..747a82753 100644
--- a/src/exchangedb/pg_select_contract.h
+++ b/src/exchangedb/pg_select_contract.h
@@ -38,10 +38,10 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_select_contract (void *cls,
- const struct TALER_ContractDiffiePublicP *pub_ckey,
- struct TALER_PurseContractPublicKeyP *purse_pub,
- struct TALER_PurseContractSignatureP *econtract_sig,
- size_t *econtract_size,
+ const struct TALER_ContractDiffiePublicP *pub_ckey,
+ struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct TALER_PurseContractSignatureP *econtract_sig,
+ size_t *econtract_size,
void **econtract);
#endif
diff --git a/src/exchangedb/pg_select_contract_by_purse.c b/src/exchangedb/pg_select_contract_by_purse.c
index aeeb56d48..8d29b3954 100644
--- a/src/exchangedb/pg_select_contract_by_purse.c
+++ b/src/exchangedb/pg_select_contract_by_purse.c
@@ -46,7 +46,7 @@ TEH_PG_select_contract_by_purse (
&econtract->econtract_size),
GNUNET_PQ_result_spec_end
};
- /* Used in #postgres_select_contract_by_purse */
+ /* Used in #postgres_select_contract_by_purse */
PREPARE (pg,
"select_contract_by_purse",
"SELECT "
diff --git a/src/exchangedb/pg_select_deposits_missing_wire.c b/src/exchangedb/pg_select_deposits_missing_wire.c
index 2a260a369..e638c88e9 100644
--- a/src/exchangedb/pg_select_deposits_missing_wire.c
+++ b/src/exchangedb/pg_select_deposits_missing_wire.c
@@ -114,10 +114,10 @@ missing_wire_cb (void *cls,
enum GNUNET_DB_QueryStatus
TEH_PG_select_deposits_missing_wire (void *cls,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- TALER_EXCHANGEDB_WireMissingCallback cb,
- void *cb_cls)
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ TALER_EXCHANGEDB_WireMissingCallback cb,
+ void *cb_cls)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -133,11 +133,11 @@ TEH_PG_select_deposits_missing_wire (void *cls,
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_select_deposits_missing_wire */
- // FIXME: used by the auditor; can probably be done
- // smarter by checking if 'done' or 'blocked'
- // are set correctly when going over deposits, instead
- // of JOINing with refunds.
+ /* Used in #postgres_select_deposits_missing_wire */
+ // FIXME: used by the auditor; can probably be done
+ // smarter by checking if 'done' or 'blocked'
+ // are set correctly when going over deposits, instead
+ // of JOINing with refunds.
PREPARE (pg,
"deposits_get_overdue",
"SELECT"
@@ -164,7 +164,6 @@ TEH_PG_select_deposits_missing_wire (void *cls,
" ORDER BY wire_deadline ASC");
-
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
"deposits_get_overdue",
params,
diff --git a/src/exchangedb/pg_select_deposits_missing_wire.h b/src/exchangedb/pg_select_deposits_missing_wire.h
index f702c2417..40c592cee 100644
--- a/src/exchangedb/pg_select_deposits_missing_wire.h
+++ b/src/exchangedb/pg_select_deposits_missing_wire.h
@@ -38,9 +38,9 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_select_deposits_missing_wire (void *cls,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- TALER_EXCHANGEDB_WireMissingCallback cb,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ TALER_EXCHANGEDB_WireMissingCallback cb,
void *cb_cls);
#endif
diff --git a/src/exchangedb/pg_select_history_requests_above_serial_id.c b/src/exchangedb/pg_select_history_requests_above_serial_id.c
index 81e038114..36902e0ab 100644
--- a/src/exchangedb/pg_select_history_requests_above_serial_id.c
+++ b/src/exchangedb/pg_select_history_requests_above_serial_id.c
@@ -113,8 +113,6 @@ history_request_serial_helper_cb (void *cls,
}
-
-
enum GNUNET_DB_QueryStatus
TEH_PG_select_history_requests_above_serial_id (
void *cls,
diff --git a/src/exchangedb/pg_select_merge_amounts_for_kyc_check.c b/src/exchangedb/pg_select_merge_amounts_for_kyc_check.c
index 5cb665fa8..b1bdd1450 100644
--- a/src/exchangedb/pg_select_merge_amounts_for_kyc_check.c
+++ b/src/exchangedb/pg_select_merge_amounts_for_kyc_check.c
@@ -26,7 +26,6 @@
#include "pg_helper.h"
-
/**
* Closure for #get_kyc_amounts_cb().
*/
@@ -132,7 +131,7 @@ TEH_PG_select_merge_amounts_for_kyc_check (
};
enum GNUNET_DB_QueryStatus qs;
-
+
PREPARE (pg,
"select_kyc_relevant_merge_events",
"SELECT"
@@ -157,4 +156,3 @@ TEH_PG_select_merge_amounts_for_kyc_check (
return GNUNET_DB_STATUS_HARD_ERROR;
return qs;
}
-
diff --git a/src/exchangedb/pg_select_purse_decisions_above_serial_id.c b/src/exchangedb/pg_select_purse_decisions_above_serial_id.c
index 2368f2d3e..02e67197b 100644
--- a/src/exchangedb/pg_select_purse_decisions_above_serial_id.c
+++ b/src/exchangedb/pg_select_purse_decisions_above_serial_id.c
@@ -112,7 +112,6 @@ purse_decision_serial_helper_cb (void *cls,
}
-
enum GNUNET_DB_QueryStatus
TEH_PG_select_purse_decisions_above_serial_id (
void *cls,
diff --git a/src/exchangedb/pg_select_purse_decisions_above_serial_id.h b/src/exchangedb/pg_select_purse_decisions_above_serial_id.h
index 53ab31c80..83168d546 100644
--- a/src/exchangedb/pg_select_purse_decisions_above_serial_id.h
+++ b/src/exchangedb/pg_select_purse_decisions_above_serial_id.h
@@ -43,4 +43,5 @@ TEH_PG_select_purse_decisions_above_serial_id (
bool refunded,
TALER_EXCHANGEDB_PurseDecisionCallback cb,
void *cb_cls);
+
#endif
diff --git a/src/exchangedb/pg_select_purse_merge.c b/src/exchangedb/pg_select_purse_merge.c
index d1f6a5396..ce9f03618 100644
--- a/src/exchangedb/pg_select_purse_merge.c
+++ b/src/exchangedb/pg_select_purse_merge.c
@@ -56,7 +56,7 @@ TEH_PG_select_purse_merge (
};
*partner_url = NULL;
- /* Used in #postgres_select_purse_merge */
+ /* Used in #postgres_select_purse_merge */
PREPARE (pg,
"select_purse_merge",
"SELECT "
diff --git a/src/exchangedb/pg_select_recoup_above_serial_id.c b/src/exchangedb/pg_select_recoup_above_serial_id.c
index 9047a86f8..b2933fae3 100644
--- a/src/exchangedb/pg_select_recoup_above_serial_id.c
+++ b/src/exchangedb/pg_select_recoup_above_serial_id.c
@@ -26,7 +26,6 @@
#include "pg_helper.h"
-
/**
* Closure for #recoup_serial_helper_cb().
*/
@@ -137,6 +136,7 @@ recoup_serial_helper_cb (void *cls,
}
}
+
enum GNUNET_DB_QueryStatus
TEH_PG_select_recoup_above_serial_id (
void *cls,
@@ -157,7 +157,7 @@ TEH_PG_select_recoup_above_serial_id (
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_select_recoup_above_serial_id() to obtain recoup transactions */
+ /* Used in #postgres_select_recoup_above_serial_id() to obtain recoup transactions */
PREPARE (pg,
"recoup_get_incr",
"SELECT"
diff --git a/src/exchangedb/pg_select_recoup_refresh_above_serial_id.c b/src/exchangedb/pg_select_recoup_refresh_above_serial_id.c
index a3f6bc93d..c6fb62cc7 100644
--- a/src/exchangedb/pg_select_recoup_refresh_above_serial_id.c
+++ b/src/exchangedb/pg_select_recoup_refresh_above_serial_id.c
@@ -141,7 +141,6 @@ recoup_refresh_serial_helper_cb (void *cls,
}
-
enum GNUNET_DB_QueryStatus
TEH_PG_select_recoup_refresh_above_serial_id (
void *cls,
@@ -162,8 +161,8 @@ TEH_PG_select_recoup_refresh_above_serial_id (
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_select_recoup_refresh_above_serial_id() to obtain
- recoup-refresh transactions */
+ /* Used in #postgres_select_recoup_refresh_above_serial_id() to obtain
+ recoup-refresh transactions */
PREPARE (pg,
"recoup_refresh_get_incr",
"SELECT"
diff --git a/src/exchangedb/pg_select_refreshes_above_serial_id.c b/src/exchangedb/pg_select_refreshes_above_serial_id.c
index d2b4a7fa6..401e6dcef 100644
--- a/src/exchangedb/pg_select_refreshes_above_serial_id.c
+++ b/src/exchangedb/pg_select_refreshes_above_serial_id.c
@@ -130,10 +130,6 @@ refreshs_serial_helper_cb (void *cls,
}
-
-
-
-
enum GNUNET_DB_QueryStatus
TEH_PG_select_refreshes_above_serial_id (
void *cls,
@@ -153,8 +149,8 @@ TEH_PG_select_refreshes_above_serial_id (
.status = GNUNET_OK
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_select_refreshes_above_serial_id() to fetch
- refresh session with id '\geq' the given parameter */
+ /* Used in #postgres_select_refreshes_above_serial_id() to fetch
+ refresh session with id '\geq' the given parameter */
PREPARE (pg,
"audit_get_refresh_commitments_incr",
"SELECT"
diff --git a/src/exchangedb/pg_select_refunds_by_coin.h b/src/exchangedb/pg_select_refunds_by_coin.h
index e1838b235..72df13fda 100644
--- a/src/exchangedb/pg_select_refunds_by_coin.h
+++ b/src/exchangedb/pg_select_refunds_by_coin.h
@@ -44,4 +44,5 @@ TEH_PG_select_refunds_by_coin (
const struct TALER_PrivateContractHashP *h_contract,
TALER_EXCHANGEDB_RefundCoinCallback cb,
void *cb_cls);
+
#endif
diff --git a/src/exchangedb/pg_select_reserves_in_above_serial_id.c b/src/exchangedb/pg_select_reserves_in_above_serial_id.c
index 1a6efc66b..8dd4a9aba 100644
--- a/src/exchangedb/pg_select_reserves_in_above_serial_id.c
+++ b/src/exchangedb/pg_select_reserves_in_above_serial_id.c
@@ -137,8 +137,8 @@ TEH_PG_select_reserves_in_above_serial_id (
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
- transactions for reserves with serial id '\geq' the given parameter */
+ /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
+ transactions for reserves with serial id '\geq' the given parameter */
PREPARE (pg,
"audit_reserves_in_get_transactions_incr",
"SELECT"
diff --git a/src/exchangedb/pg_select_reserves_in_above_serial_id_by_account.c b/src/exchangedb/pg_select_reserves_in_above_serial_id_by_account.c
index ba73994f0..809df191b 100644
--- a/src/exchangedb/pg_select_reserves_in_above_serial_id_by_account.c
+++ b/src/exchangedb/pg_select_reserves_in_above_serial_id_by_account.c
@@ -138,8 +138,8 @@ TEH_PG_select_reserves_in_above_serial_id_by_account (
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
- transactions for reserves with serial id '\geq' the given parameter */
+ /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
+ transactions for reserves with serial id '\geq' the given parameter */
PREPARE (pg,
"audit_reserves_in_get_transactions_incr_by_account",
"SELECT"
diff --git a/src/exchangedb/pg_select_wire_out_above_serial_id.c b/src/exchangedb/pg_select_wire_out_above_serial_id.c
index e219f5d4b..a9615ac8e 100644
--- a/src/exchangedb/pg_select_wire_out_above_serial_id.c
+++ b/src/exchangedb/pg_select_wire_out_above_serial_id.c
@@ -113,7 +113,6 @@ wire_out_serial_helper_cb (void *cls,
}
-
enum GNUNET_DB_QueryStatus
TEH_PG_select_wire_out_above_serial_id (
void *cls,
@@ -133,7 +132,7 @@ TEH_PG_select_wire_out_above_serial_id (
.status = GNUNET_OK
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_select_wire_out_above_serial_id() */
+ /* Used in #postgres_select_wire_out_above_serial_id() */
PREPARE (pg,
"audit_get_wire_incr",
"SELECT"
diff --git a/src/exchangedb/pg_select_wire_out_above_serial_id_by_account.c b/src/exchangedb/pg_select_wire_out_above_serial_id_by_account.c
index 08883c9a4..a6c3f0730 100644
--- a/src/exchangedb/pg_select_wire_out_above_serial_id_by_account.c
+++ b/src/exchangedb/pg_select_wire_out_above_serial_id_by_account.c
@@ -112,6 +112,7 @@ wire_out_serial_helper_cb (void *cls,
}
}
+
enum GNUNET_DB_QueryStatus
TEH_PG_select_wire_out_above_serial_id_by_account (
void *cls,
@@ -134,7 +135,7 @@ TEH_PG_select_wire_out_above_serial_id_by_account (
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_select_wire_out_above_serial_id_by_account() */
+ /* Used in #postgres_select_wire_out_above_serial_id_by_account() */
PREPARE (pg,
"audit_get_wire_incr_by_account",
"SELECT"
diff --git a/src/exchangedb/pg_select_wire_out_above_serial_id_by_account.h b/src/exchangedb/pg_select_wire_out_above_serial_id_by_account.h
index 98315cace..04c6a62b2 100644
--- a/src/exchangedb/pg_select_wire_out_above_serial_id_by_account.h
+++ b/src/exchangedb/pg_select_wire_out_above_serial_id_by_account.h
@@ -43,4 +43,5 @@ TEH_PG_select_wire_out_above_serial_id_by_account (
uint64_t serial_id,
TALER_EXCHANGEDB_WireTransferOutCallback cb,
void *cb_cls);
+
#endif
diff --git a/src/exchangedb/pg_select_withdraw_amounts_for_kyc_check.c b/src/exchangedb/pg_select_withdraw_amounts_for_kyc_check.c
index e200da8de..339fa3e23 100644
--- a/src/exchangedb/pg_select_withdraw_amounts_for_kyc_check.c
+++ b/src/exchangedb/pg_select_withdraw_amounts_for_kyc_check.c
@@ -131,21 +131,21 @@ TEH_PG_select_withdraw_amounts_for_kyc_check (
.status = GNUNET_OK
};
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_select_withdraw_amounts_for_kyc_check (
-() */
+ /* Used in #postgres_select_withdraw_amounts_for_kyc_check (
+ () */
PREPARE (pg,
- "select_kyc_relevant_withdraw_events",
- "SELECT"
- " ro.amount_with_fee_val AS amount_val"
- ",ro.amount_with_fee_frac AS amount_frac"
- ",ro.execution_date AS date"
- " FROM reserves_out ro"
- " JOIN reserves_out_by_reserve USING (h_blind_ev)"
- " JOIN reserves res ON (ro.reserve_uuid = res.reserve_uuid)"
- " JOIN reserves_in ri ON (res.reserve_pub = ri.reserve_pub)"
- " WHERE wire_source_h_payto=$1"
- " AND ro.execution_date >= $2"
- " ORDER BY ro.execution_date DESC");
+ "select_kyc_relevant_withdraw_events",
+ "SELECT"
+ " ro.amount_with_fee_val AS amount_val"
+ ",ro.amount_with_fee_frac AS amount_frac"
+ ",ro.execution_date AS date"
+ " FROM reserves_out ro"
+ " JOIN reserves_out_by_reserve USING (h_blind_ev)"
+ " JOIN reserves res ON (ro.reserve_uuid = res.reserve_uuid)"
+ " JOIN reserves_in ri ON (res.reserve_pub = ri.reserve_pub)"
+ " WHERE wire_source_h_payto=$1"
+ " AND ro.execution_date >= $2"
+ " ORDER BY ro.execution_date DESC");
qs = GNUNET_PQ_eval_prepared_multi_select (
pg->conn,
"select_kyc_relevant_withdraw_events",
diff --git a/src/exchangedb/pg_select_withdraw_amounts_for_kyc_check.h b/src/exchangedb/pg_select_withdraw_amounts_for_kyc_check.h
index 4c1283744..9a780adbe 100644
--- a/src/exchangedb/pg_select_withdraw_amounts_for_kyc_check.h
+++ b/src/exchangedb/pg_select_withdraw_amounts_for_kyc_check.h
@@ -44,4 +44,5 @@ TEH_PG_select_withdraw_amounts_for_kyc_check (
struct GNUNET_TIME_Absolute time_limit,
TALER_EXCHANGEDB_KycAmountCallback kac,
void *kac_cls);
+
#endif
diff --git a/src/exchangedb/pg_select_withdrawals_above_serial_id.c b/src/exchangedb/pg_select_withdrawals_above_serial_id.c
index 4718a62ae..b842b11aa 100644
--- a/src/exchangedb/pg_select_withdrawals_above_serial_id.c
+++ b/src/exchangedb/pg_select_withdrawals_above_serial_id.c
@@ -121,7 +121,6 @@ reserves_out_serial_helper_cb (void *cls,
}
-
enum GNUNET_DB_QueryStatus
TEH_PG_select_withdrawals_above_serial_id (
void *cls,
@@ -142,7 +141,7 @@ TEH_PG_select_withdrawals_above_serial_id (
};
enum GNUNET_DB_QueryStatus qs;
- /* Fetch deposits with rowid '\geq' the given parameter */
+ /* Fetch deposits with rowid '\geq' the given parameter */
PREPARE (pg,
"audit_get_reserves_out_incr",
diff --git a/src/exchangedb/pg_select_withdrawals_above_serial_id.h b/src/exchangedb/pg_select_withdrawals_above_serial_id.h
index adc23fb30..2b741a3b4 100644
--- a/src/exchangedb/pg_select_withdrawals_above_serial_id.h
+++ b/src/exchangedb/pg_select_withdrawals_above_serial_id.h
@@ -41,4 +41,5 @@ TEH_PG_select_withdrawals_above_serial_id (
uint64_t serial_id,
TALER_EXCHANGEDB_WithdrawCallback cb,
void *cb_cls);
+
#endif
diff --git a/src/exchangedb/pg_set_extension_manifest.c b/src/exchangedb/pg_set_extension_manifest.c
index 86e9d3f08..c7db04312 100644
--- a/src/exchangedb/pg_set_extension_manifest.c
+++ b/src/exchangedb/pg_set_extension_manifest.c
@@ -28,8 +28,8 @@
enum GNUNET_DB_QueryStatus
TEH_PG_set_extension_manifest (void *cls,
- const char *extension_name,
- const char *manifest)
+ const char *extension_name,
+ const char *manifest)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam pcfg =
diff --git a/src/exchangedb/pg_set_extension_manifest.h b/src/exchangedb/pg_set_extension_manifest.h
index ead3abd28..0befeedd8 100644
--- a/src/exchangedb/pg_set_extension_manifest.h
+++ b/src/exchangedb/pg_set_extension_manifest.h
@@ -37,7 +37,7 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_set_extension_manifest (void *cls,
- const char *extension_name,
+ const char *extension_name,
const char *manifest);
#endif
diff --git a/src/exchangedb/pg_set_purse_balance.c b/src/exchangedb/pg_set_purse_balance.c
index a996104bc..e955cb1cb 100644
--- a/src/exchangedb/pg_set_purse_balance.c
+++ b/src/exchangedb/pg_set_purse_balance.c
@@ -50,6 +50,3 @@ TEH_PG_set_purse_balance (
"set_purse_balance",
params);
}
-
-
-
diff --git a/src/exchangedb/pg_setup_wire_target.c b/src/exchangedb/pg_setup_wire_target.c
index a2d890c50..ed6fbe338 100644
--- a/src/exchangedb/pg_setup_wire_target.c
+++ b/src/exchangedb/pg_setup_wire_target.c
@@ -26,7 +26,7 @@
enum GNUNET_DB_QueryStatus
-TEH_PG_setup_wire_target(
+TEH_PG_setup_wire_target (
struct PostgresClosure *pg,
const char *payto_uri,
struct TALER_PaytoHashP *h_payto)
diff --git a/src/exchangedb/pg_setup_wire_target.h b/src/exchangedb/pg_setup_wire_target.h
index 12c0e59b0..77512a600 100644
--- a/src/exchangedb/pg_setup_wire_target.h
+++ b/src/exchangedb/pg_setup_wire_target.h
@@ -35,7 +35,7 @@
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
-TEH_PG_setup_wire_target(
+TEH_PG_setup_wire_target (
struct PostgresClosure *pg,
const char *payto_uri,
struct TALER_PaytoHashP *h_payto);
diff --git a/src/exchangedb/pg_store_wire_transfer_out.c b/src/exchangedb/pg_store_wire_transfer_out.c
index 8bc0147dd..b8b0bb692 100644
--- a/src/exchangedb/pg_store_wire_transfer_out.c
+++ b/src/exchangedb/pg_store_wire_transfer_out.c
@@ -44,7 +44,7 @@ TEH_PG_store_wire_transfer_out (
GNUNET_PQ_query_param_end
};
- /* Used in #postgres_store_wire_transfer_out */
+ /* Used in #postgres_store_wire_transfer_out */
PREPARE (pg,
"insert_wire_out",
"INSERT INTO wire_out "
diff --git a/src/exchangedb/pg_update_aggregation_transient.c b/src/exchangedb/pg_update_aggregation_transient.c
index 1d91301c3..c44cd67ec 100644
--- a/src/exchangedb/pg_update_aggregation_transient.c
+++ b/src/exchangedb/pg_update_aggregation_transient.c
@@ -26,7 +26,6 @@
#include "pg_helper.h"
-
enum GNUNET_DB_QueryStatus
TEH_PG_update_aggregation_transient (
void *cls,
@@ -45,7 +44,7 @@ TEH_PG_update_aggregation_transient (
};
- /* Used in #postgres_update_aggregation_transient() */
+ /* Used in #postgres_update_aggregation_transient() */
PREPARE (pg,
"update_aggregation_transient",
"UPDATE aggregation_transient"
diff --git a/src/exchangedb/pg_update_auditor.c b/src/exchangedb/pg_update_auditor.c
index 9d82f25db..167a270b9 100644
--- a/src/exchangedb/pg_update_auditor.c
+++ b/src/exchangedb/pg_update_auditor.c
@@ -28,11 +28,11 @@
enum GNUNET_DB_QueryStatus
TEH_PG_update_auditor (void *cls,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const char *auditor_url,
- const char *auditor_name,
- struct GNUNET_TIME_Timestamp change_date,
- bool enabled)
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ const char *auditor_name,
+ struct GNUNET_TIME_Timestamp change_date,
+ bool enabled)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -43,16 +43,16 @@ TEH_PG_update_auditor (void *cls,
GNUNET_PQ_query_param_timestamp (&change_date),
GNUNET_PQ_query_param_end
};
- /* used in #postgres_update_auditor() */
- PREPARE(pg,
- "update_auditor",
- "UPDATE auditors"
- " SET"
- " auditor_url=$2"
- " ,auditor_name=$3"
- " ,is_active=$4"
- " ,last_change=$5"
- " WHERE auditor_pub=$1");
+ /* used in #postgres_update_auditor() */
+ PREPARE (pg,
+ "update_auditor",
+ "UPDATE auditors"
+ " SET"
+ " auditor_url=$2"
+ " ,auditor_name=$3"
+ " ,is_active=$4"
+ " ,last_change=$5"
+ " WHERE auditor_pub=$1");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"update_auditor",
params);
diff --git a/src/exchangedb/pg_update_auditor.h b/src/exchangedb/pg_update_auditor.h
index af8d06062..ee869f8b7 100644
--- a/src/exchangedb/pg_update_auditor.h
+++ b/src/exchangedb/pg_update_auditor.h
@@ -38,10 +38,10 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_update_auditor (void *cls,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const char *auditor_url,
- const char *auditor_name,
- struct GNUNET_TIME_Timestamp change_date,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ const char *auditor_name,
+ struct GNUNET_TIME_Timestamp change_date,
bool enabled);
#endif
diff --git a/src/exchangedb/pg_update_wire.c b/src/exchangedb/pg_update_wire.c
index f5f5672cb..4059348c9 100644
--- a/src/exchangedb/pg_update_wire.c
+++ b/src/exchangedb/pg_update_wire.c
@@ -28,9 +28,9 @@
enum GNUNET_DB_QueryStatus
TEH_PG_update_wire (void *cls,
- const char *payto_uri,
- struct GNUNET_TIME_Timestamp change_date,
- bool enabled)
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp change_date,
+ bool enabled)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -40,7 +40,7 @@ TEH_PG_update_wire (void *cls,
GNUNET_PQ_query_param_end
};
- /* used in #postgres_update_wire() */
+ /* used in #postgres_update_wire() */
PREPARE (pg,
"update_wire",
"UPDATE wire_accounts"
diff --git a/src/exchangedb/pg_update_wire.h b/src/exchangedb/pg_update_wire.h
index c01d68a46..67038b580 100644
--- a/src/exchangedb/pg_update_wire.h
+++ b/src/exchangedb/pg_update_wire.h
@@ -36,8 +36,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_update_wire (void *cls,
- const char *payto_uri,
- struct GNUNET_TIME_Timestamp change_date,
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp change_date,
bool enabled);
#endif
diff --git a/src/exchangedb/pg_wire_prepare_data_get.c b/src/exchangedb/pg_wire_prepare_data_get.c
index d45413010..21d1b947a 100644
--- a/src/exchangedb/pg_wire_prepare_data_get.c
+++ b/src/exchangedb/pg_wire_prepare_data_get.c
@@ -99,10 +99,10 @@ prewire_cb (void *cls,
enum GNUNET_DB_QueryStatus
TEH_PG_wire_prepare_data_get (void *cls,
- uint64_t start_row,
- uint64_t limit,
- TALER_EXCHANGEDB_WirePreparationIterator cb,
- void *cb_cls)
+ uint64_t start_row,
+ uint64_t limit,
+ TALER_EXCHANGEDB_WirePreparationIterator cb,
+ void *cb_cls)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -118,7 +118,7 @@ TEH_PG_wire_prepare_data_get (void *cls,
enum GNUNET_DB_QueryStatus qs;
- /* Used in #postgres_wire_prepare_data_get() */
+ /* Used in #postgres_wire_prepare_data_get() */
PREPARE (pg,
"wire_prepare_data_get",
"SELECT"
diff --git a/src/exchangedb/pg_wire_prepare_data_get.h b/src/exchangedb/pg_wire_prepare_data_get.h
index 91e21d27e..815c14bdf 100644
--- a/src/exchangedb/pg_wire_prepare_data_get.h
+++ b/src/exchangedb/pg_wire_prepare_data_get.h
@@ -38,8 +38,9 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_wire_prepare_data_get (void *cls,
- uint64_t start_row,
- uint64_t limit,
- TALER_EXCHANGEDB_WirePreparationIterator cb,
+ uint64_t start_row,
+ uint64_t limit,
+ TALER_EXCHANGEDB_WirePreparationIterator cb,
void *cb_cls);
+
#endif
diff --git a/src/exchangedb/pg_wire_prepare_data_insert.c b/src/exchangedb/pg_wire_prepare_data_insert.c
index 903f22a5b..919fccdaf 100644
--- a/src/exchangedb/pg_wire_prepare_data_insert.c
+++ b/src/exchangedb/pg_wire_prepare_data_insert.c
@@ -27,9 +27,9 @@
enum GNUNET_DB_QueryStatus
TEH_PG_wire_prepare_data_insert (void *cls,
- const char *type,
- const char *buf,
- size_t buf_size)
+ const char *type,
+ const char *buf,
+ size_t buf_size)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -39,15 +39,15 @@ TEH_PG_wire_prepare_data_insert (void *cls,
};
- /* Used in #postgres_wire_prepare_data_insert() to store
- wire transfer information before actually committing it with the bank */
+ /* Used in #postgres_wire_prepare_data_insert() to store
+ wire transfer information before actually committing it with the bank */
PREPARE (pg,
- "wire_prepare_data_insert",
- "INSERT INTO prewire "
- "(wire_method"
- ",buf"
- ") VALUES "
- "($1, $2);");
+ "wire_prepare_data_insert",
+ "INSERT INTO prewire "
+ "(wire_method"
+ ",buf"
+ ") VALUES "
+ "($1, $2);");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"wire_prepare_data_insert",
params);
diff --git a/src/exchangedb/pg_wire_prepare_data_insert.h b/src/exchangedb/pg_wire_prepare_data_insert.h
index 2b6050d05..e73ee152d 100644
--- a/src/exchangedb/pg_wire_prepare_data_insert.h
+++ b/src/exchangedb/pg_wire_prepare_data_insert.h
@@ -36,7 +36,8 @@
*/
enum GNUNET_DB_QueryStatus
TEH_PG_wire_prepare_data_insert (void *cls,
- const char *type,
- const char *buf,
+ const char *type,
+ const char *buf,
size_t buf_size);
+
#endif
diff --git a/src/exchangedb/pg_wire_prepare_data_mark_failed.c b/src/exchangedb/pg_wire_prepare_data_mark_failed.c
index fe2236b82..4e4d729a3 100644
--- a/src/exchangedb/pg_wire_prepare_data_mark_failed.c
+++ b/src/exchangedb/pg_wire_prepare_data_mark_failed.c
@@ -37,7 +37,7 @@ TEH_PG_wire_prepare_data_mark_failed (
GNUNET_PQ_query_param_end
};
- /* Used in #postgres_wire_prepare_data_mark_failed() */
+ /* Used in #postgres_wire_prepare_data_mark_failed() */
PREPARE (pg,
"wire_prepare_data_mark_failed",
diff --git a/src/exchangedb/pg_wire_prepare_data_mark_failed.h b/src/exchangedb/pg_wire_prepare_data_mark_failed.h
index cae1523d1..98846b284 100644
--- a/src/exchangedb/pg_wire_prepare_data_mark_failed.h
+++ b/src/exchangedb/pg_wire_prepare_data_mark_failed.h
@@ -36,4 +36,5 @@ enum GNUNET_DB_QueryStatus
TEH_PG_wire_prepare_data_mark_failed (
void *cls,
uint64_t rowid);
+
#endif
diff --git a/src/exchangedb/pg_wire_prepare_data_mark_finished.c b/src/exchangedb/pg_wire_prepare_data_mark_finished.c
index de8738e40..af4a0fbbb 100644
--- a/src/exchangedb/pg_wire_prepare_data_mark_finished.c
+++ b/src/exchangedb/pg_wire_prepare_data_mark_finished.c
@@ -36,12 +36,12 @@ TEH_PG_wire_prepare_data_mark_finished (
GNUNET_PQ_query_param_end
};
- /* Used in #postgres_wire_prepare_data_mark_finished() */
+ /* Used in #postgres_wire_prepare_data_mark_finished() */
PREPARE (pg,
- "wire_prepare_data_mark_done",
- "UPDATE prewire"
- " SET finished=TRUE"
- " WHERE prewire_uuid=$1;");
+ "wire_prepare_data_mark_done",
+ "UPDATE prewire"
+ " SET finished=TRUE"
+ " WHERE prewire_uuid=$1;");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"wire_prepare_data_mark_done",
diff --git a/src/exchangedb/pg_wire_prepare_data_mark_finished.h b/src/exchangedb/pg_wire_prepare_data_mark_finished.h
index 19db2ca99..ba2e384cd 100644
--- a/src/exchangedb/pg_wire_prepare_data_mark_finished.h
+++ b/src/exchangedb/pg_wire_prepare_data_mark_finished.h
@@ -36,4 +36,5 @@ enum GNUNET_DB_QueryStatus
TEH_PG_wire_prepare_data_mark_finished (
void *cls,
uint64_t rowid);
+
#endif
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 2ef250775..b3ebc7547 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -21,6 +21,7 @@
* @author Christian Grothoff
* @author Sree Harsha Totakura
* @author Marcello Stanisci
+ * @author Özgür Kesim
*/
#include "platform.h"
#include
@@ -216,7 +217,7 @@
#include "pg_select_aml_process.h"
#include "pg_select_aml_history.h"
#include "pg_insert_aml_decision.h"
-
+#include "pg_batch_ensure_coin_known.h"
/**
* Set to 1 to enable Postgres auto_explain module. This will
@@ -773,6 +774,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &TEH_PG_select_aml_history;
plugin->insert_aml_decision
= &TEH_PG_insert_aml_decision;
+
+ plugin->batch_ensure_coin_known
+ = &TEH_PG_batch_ensure_coin_known;
+
return plugin;
}
diff --git a/src/exchangedb/procedures.sql.in b/src/exchangedb/procedures.sql.in
index a53396c36..12ec3656f 100644
--- a/src/exchangedb/procedures.sql.in
+++ b/src/exchangedb/procedures.sql.in
@@ -39,13 +39,11 @@ SET search_path TO exchange;
#include "exchange_do_insert_or_update_policy_details.sql"
#include "exchange_do_insert_aml_decision.sql"
#include "exchange_do_insert_aml_officer.sql"
-#include "exchange_do_batch_reserves_in_insert.sql"
+#include "exchange_do_reserves_in_insert.sql"
#include "exchange_do_batch_reserves_update.sql"
-#include "exchange_do_batch2_reserves_in_insert.sql"
-#include "exchange_do_batch4_reserves_in_insert.sql"
-#include "exchange_do_batch8_reserves_in_insert.sql"
#include "exchange_do_refund_by_coin.sql"
#include "exchange_do_get_ready_deposit.sql"
#include "exchange_do_get_link_data.sql"
+#include "exchange_do_batch_coin_known.sql"
COMMIT;
diff --git a/src/exchangedb/spi/Makefile b/src/exchangedb/spi/Makefile
new file mode 100644
index 000000000..d654d91e9
--- /dev/null
+++ b/src/exchangedb/spi/Makefile
@@ -0,0 +1,9 @@
+EXTENSION = own_test
+MODULES = own_test
+DATA = own_test.sql
+PG_CPPFLAGS = -I /usr/include/postgresql
+
+# postgresql build stuff
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
diff --git a/src/exchangedb/spi/README.md b/src/exchangedb/spi/README.md
new file mode 100644
index 000000000..47eb37b94
--- /dev/null
+++ b/src/exchangedb/spi/README.md
@@ -0,0 +1,37 @@
+ Server Programming Interface (SPI)
+
+
+Overview
+========
+
+This folder contains results from an experiment by Joseph Xu
+to use the Postgres SPI. They are not currently used at all
+by the GNU Taler exchange.
+
+
+Dependencies
+============
+
+These are the direct dependencies for compiling the code:
+
+# apt-get install libpq-dev postgresql-server-dev-13
+# apt-get install libkrb5-dev
+# apt-get install libssl-dev
+
+
+Compilation
+===========
+
+$ make
+
+Loading functions
+=================
+
+# make install
+$ psql "$DB_NAME" < own_test.sql
+
+
+Calling functions
+==================
+
+$ psql -c "SELECT $FUNCTION_NAME($ARGS);" "$DB_NAME"
diff --git a/src/exchangedb/spi/own_test.c b/src/exchangedb/spi/own_test.c
new file mode 100644
index 000000000..ac72fad7b
--- /dev/null
+++ b/src/exchangedb/spi/own_test.c
@@ -0,0 +1,873 @@
+#include "postgres.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef PG_MODULE_MAGIC
+PG_MODULE_MAGIC;
+#endif
+
+typedef struct
+{
+ Datum col1;
+ Datum col2;
+} valuest;
+
+void _PG_init (void);
+
+void _PG_fini (void);
+
+void
+_PG_init (void)
+{
+}
+
+
+PG_FUNCTION_INFO_V1 (pg_spi_insert_int);
+PG_FUNCTION_INFO_V1 (pg_spi_select_from_x);
+PG_FUNCTION_INFO_V1 (pg_spi_select_pair_from_y);
+// PG_FUNCTION_INFO_V1(pg_spi_select_with_cond);
+PG_FUNCTION_INFO_V1 (pg_spi_update_y);
+PG_FUNCTION_INFO_V1 (pg_spi_prepare_example);
+PG_FUNCTION_INFO_V1 (pg_spi_prepare_example_without_saveplan);
+PG_FUNCTION_INFO_V1 (pg_spi_prepare_insert);
+PG_FUNCTION_INFO_V1 (pg_spi_prepare_insert_without_saveplan);
+// PG_FUNCTION_INFO_V1(pg_spi_prepare_select_with_cond);
+PG_FUNCTION_INFO_V1 (pg_spi_prepare_select_with_cond_without_saveplan);
+PG_FUNCTION_INFO_V1 (pg_spi_prepare_update);
+PG_FUNCTION_INFO_V1 (pg_spi_get_dep_ref_fees);
+// SIMPLE SELECT
+Datum
+pg_spi_prepare_example (PG_FUNCTION_ARGS)
+{
+ static SPIPlanPtr prepared_plan;
+ int ret;
+ int64 result;
+ char *value;
+ SPIPlanPtr new_plan;
+
+ ret = SPI_connect ();
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "DB connection failed ! \n");
+ }
+ {
+ if (prepared_plan == NULL)
+ {
+ new_plan = SPI_prepare ("SELECT 1 FROM X", 0, NULL);
+ prepared_plan = SPI_saveplan (new_plan);
+
+ if (prepared_plan == NULL)
+ {
+ elog (ERROR, "FAIL TO SAVE !\n");
+ }
+ }
+
+ ret = SPI_execute_plan (prepared_plan, NULL, 0,false, 0);
+ if (ret != SPI_OK_SELECT)
+ {
+ elog (ERROR, "SELECT FAILED %d !\n", ret);
+ }
+
+ if (SPI_tuptable != NULL && SPI_tuptable->vals != NULL &&
+ SPI_tuptable->tupdesc != NULL)
+ {
+ value = SPI_getvalue (SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
+ result = atoi (value);
+ }
+ else
+ {
+ elog (ERROR, "EMPTY TABLE !\n");
+ }
+ }
+ SPI_finish ();
+ PG_RETURN_INT64 (result);
+}
+
+
+Datum
+pg_spi_prepare_example_without_saveplan (PG_FUNCTION_ARGS)
+{
+ int ret;
+ int64 result;
+ char *value;
+ SPIPlanPtr new_plan;
+
+ ret = SPI_connect ();
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "DB connection failed ! \n");
+ }
+
+ {
+ new_plan = SPI_prepare ("SELECT 1 FROM X", 0, NULL);
+ ret = SPI_execute_plan (new_plan, NULL, 0,false, 0);
+ if (ret != SPI_OK_SELECT)
+ {
+ elog (ERROR, "SELECT FAILED %d !\n", ret);
+ }
+
+ if (SPI_tuptable != NULL
+ && SPI_tuptable->vals != NULL
+ && SPI_tuptable->tupdesc != NULL)
+ {
+ value = SPI_getvalue (SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
+ result = atoi (value);
+ }
+ else
+ {
+ elog (ERROR, "EMPTY TABLE !\n");
+ }
+ }
+ SPI_finish ();
+ PG_RETURN_INT64 (result);// PG_RETURN_INT64(result);
+}
+
+
+// SELECT 1 FROM X
+// V1
+Datum
+pg_spi_select_from_x (PG_FUNCTION_ARGS)
+{
+ int ret;
+ char *query = "SELECT 1 FROM X";
+ uint64 proc;
+ ret = SPI_connect ();
+
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "SPI_connect failed");
+ }
+
+ ret = SPI_exec (query, 10);
+ proc = SPI_processed;
+ if (ret != SPI_OK_SELECT)
+ {
+ elog (ERROR, "SPI_exec failed");
+ }
+
+ SPI_finish ();
+
+ PG_RETURN_INT64 (proc);
+}
+
+
+// INSERT INTO X VALUES (1)
+Datum
+pg_spi_insert_int (PG_FUNCTION_ARGS)
+{
+ int ret;
+ int nargs;
+ Oid argtypes[1];
+ Datum values[1];
+ char *query = "INSERT INTO X (a) VALUES ($1)";
+
+ ret = SPI_connect ();
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "SPI_connect failed");
+ }
+
+ nargs = 1;
+ argtypes[0] = INT4OID;
+ values[0] = Int32GetDatum (3);
+
+ ret = SPI_execute_with_args (query, nargs, argtypes, values, NULL, false, 0);
+ if (ret != SPI_OK_INSERT)
+ {
+ elog (ERROR, "SPI_execute_with_args failed");
+ }
+
+ SPI_finish ();
+
+ PG_RETURN_VOID ();
+}
+
+
+Datum
+pg_spi_prepare_insert (PG_FUNCTION_ARGS)
+{
+ static SPIPlanPtr prepared_plan = NULL;
+ int ret;
+ int nargs;
+ Oid argtypes[1];
+ Datum values[1];
+ const char *query = "INSERT INTO X (a) VALUES ($1)";
+ SPIPlanPtr new_plan;
+ ret = SPI_connect ();
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "SPI_connect failed ! \n");
+ }
+ if (prepared_plan == NULL)
+ {
+
+ argtypes[0] = INT4OID;
+ nargs = 1;
+ values[0] = Int32GetDatum (3);
+ new_plan = SPI_prepare (query, nargs, argtypes);
+ if (new_plan== NULL)
+ {
+ elog (ERROR, "SPI_prepare failed ! \n");
+ }
+ prepared_plan = SPI_saveplan (new_plan);
+ if (prepared_plan == NULL)
+ {
+ elog (ERROR, "SPI_saveplan failed ! \n");
+ }
+ }
+
+ ret = SPI_execute_plan (prepared_plan, values, NULL, false, 0);
+ if (ret != SPI_OK_INSERT)
+ {
+ elog (ERROR, "SPI_execute_plan failed ! \n");
+ }
+
+ SPI_finish ();
+
+ PG_RETURN_VOID ();
+}
+
+
+/*
+Datum
+pg_spi_prepare_insert_bytea(PG_FUNCTION_ARGS)
+{
+ static SPIPlanPtr prepared_plan = NULL;
+ int ret;
+ int nargs;
+ Oid argtypes[1];
+ Datum values[1];
+ Oid argtypes2[1];
+ Datum val[1];
+ char *query = "INSERT INTO X (a) VALUES ($1)";
+ SPIPlanPtr new_plan;
+ ret = SPI_connect();
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog(ERROR, "SPI_connect failed ! \n");
+ }
+ if (prepared_plan == NULL) {
+ argtypes2[0] = BOOLOID;
+ val[0] = BoolGetDatum();
+ argtypes[0] = BYTEAOID;
+ nargs = 1;
+ values[0] = Int32GetDatum(3);
+ new_plan = SPI_prepare(query, nargs, argtypes);
+ if (new_plan== NULL)
+ {
+ elog(ERROR, "SPI_prepare failed ! \n");
+ }
+ prepared_plan = SPI_saveplan(new_plan);
+ if (prepared_plan == NULL)
+ {
+ elog(ERROR, "SPI_saveplan failed ! \n");
+ }
+ }
+
+ ret = SPI_execute_plan(prepared_plan, values, NULL, false, 0);
+ if (ret != SPI_OK_INSERT)
+ {
+ elog(ERROR, "SPI_execute_plan failed ! \n");
+ }
+
+ SPI_finish();
+
+ PG_RETURN_VOID();
+}
+*/
+
+Datum
+pg_spi_prepare_insert_without_saveplan (PG_FUNCTION_ARGS)
+{
+ int ret;
+ int nargs;
+ Oid argtypes[1];
+ Datum values[1];
+ const char *query = "INSERT INTO X (a) VALUES ($1)";
+ SPIPlanPtr new_plan;
+ ret = SPI_connect ();
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "SPI_connect failed");
+ }
+ {
+ argtypes[0] = INT4OID;
+ nargs = 1;
+ values[0] = Int32GetDatum (3);
+ new_plan = SPI_prepare (query, nargs, argtypes);
+ if (new_plan== NULL)
+ {
+ elog (ERROR, "SPI_prepare failed");
+ }
+ }
+
+ ret = SPI_execute_plan (new_plan, values, NULL, false, 0);
+ if (ret != SPI_OK_INSERT)
+ {
+ elog (ERROR, "SPI_execute_plan failed");
+ }
+
+ SPI_finish ();
+
+ PG_RETURN_VOID ();
+}
+
+
+/*
+Datum
+pg_spi_select_pair_from_y(PG_FUNCTION_ARGS)
+{
+ int ret;
+ valuest result;
+ bool isnull;
+ char *query = "SELECT 1,1 FROM Y";
+ result.col1 = 0;
+ result.col2 = 0;
+
+ if ((ret = SPI_connect()) < 0) {
+ fprintf(stderr, "SPI_connect returned %d\n", ret);
+ exit(1);
+ }
+ ret = SPI_exec(query, 0);
+ if (ret == SPI_OK_SELECT && SPI_processed > 0) {
+ int i;
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable->tupdesc;
+ for (i = 0; i < SPI_processed; i++) {
+ HeapTuple tuple = tuptable->vals[i];
+ result.col1 = SPI_getbinval(tuple, tupdesc, 1, &isnull);
+ result.col2 = SPI_getbinval(tuple, tupdesc, 2, &isnull);
+ }
+ }
+ SPI_finish();
+ PG_RETURN_TEXT_P(result);
+}
+*/
+
+// SELECT X FROM Y WHERE Z=$1
+/*
+Datum
+pg_spi_select_with_cond(PG_FUNCTION_ARGS)
+{
+ int ret;
+ char *query;
+ int nargs;
+ Oid argtypes[1];
+ Datum values[1];
+ uint64 proc;
+ query = "SELECT col1 FROM Y WHERE col2 = $1";
+
+ ret = SPI_connect();
+ if (ret != SPI_OK_CONNECT) {
+ elog(ERROR, "SPI_connect failed: %d", ret);
+ }
+ nargs = 1;
+ argtypes[0] = INT4OID;
+ values[0] = Int32GetDatum(2);
+
+ ret = SPI_execute_with_args(query, nargs, argtypes, values, NULL, false, 0);
+ proc = SPI_processed;
+ if (ret != SPI_OK_SELECT)
+ {
+ elog(ERROR, "SPI_execute_with_args failed");
+ }
+
+ SPI_finish();
+
+
+ PG_RETURN_INT64(proc);
+ }*/
+
+////////SELECT WITH COND
+/*
+Datum pg_spi_prepare_select_with_cond(PG_FUNCTION_ARGS) {
+ static SPIPlanPtr prepared_plan = NULL;
+ SPIPlanPtr new_plan;
+ int ret;
+ Datum values[1];
+ uint64 proc;
+ int nargs;
+ Oid argtypes[1];
+ char *query = "SELECT col1 FROM Y WHERE col1 = $1";
+ int result = 0;
+
+ ret = SPI_connect();
+ if (ret != SPI_OK_CONNECT)
+ elog(ERROR, "SPI_connect failed ! \n");
+
+ if (prepared_plan == NULL) {
+
+ argtypes[0] = INT4OID;
+ nargs = 1;
+ values[0] = DatumGetByteaP(SPI_getbinval(tuptable->vals[0], tupdesc, 1, &isnull)); //Value col2
+
+ new_plan = SPI_prepare(query, nargs, argtypes);
+ if (new_plan == NULL)
+ elog(ERROR, "SPI_prepare failed ! \n");
+
+ prepared_plan = SPI_saveplan(new_plan);
+ if (prepared_plan == NULL)
+ elog(ERROR, "SPI_saveplan failed ! \n");
+ }
+
+
+ ret = SPI_execute_plan(prepared_plan, values, NULL, false, 0);
+
+ if (ret != SPI_OK_SELECT) {
+ elog(ERROR, "SPI_execute_plan failed: %d \n", ret);
+ }
+
+ proc = SPI_processed;
+
+ if (proc > 0) {
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable->tupdesc;
+ HeapTuple tuple;
+ int i;
+
+ for (i = 0; i < proc; i++) {
+ tuple = tuptable->vals[i];
+ for (int j = 1; j <= tupdesc->natts; j++) {
+ char * value = SPI_getvalue(tuple, tupdesc, j);
+ result += atoi(value);
+ }
+ }
+ }
+ SPI_finish();
+ PG_RETURN_INT64(result);
+}
+*/
+
+Datum
+pg_spi_prepare_select_with_cond_without_saveplan (PG_FUNCTION_ARGS)
+{
+
+ SPIPlanPtr new_plan;
+ int ret;
+ Datum values[1];
+ uint64 proc;
+ int nargs;
+ Oid argtypes[1];
+ char *query = "SELECT col1 FROM Y WHERE col2 = $1";
+ int result = 0;
+
+ ret = SPI_connect ();
+ if (ret != SPI_OK_CONNECT)
+ elog (ERROR, "SPI_connect failed ! \n");
+
+ {
+
+ argtypes[0] = INT4OID;
+ nargs = 1;
+ values[0] = Int32GetDatum (2); // Value col2
+
+ new_plan = SPI_prepare (query, nargs, argtypes);
+ if (new_plan == NULL)
+ elog (ERROR, "SPI_prepare failed ! \n");
+
+ }
+
+
+ ret = SPI_execute_plan (new_plan, values, NULL, false, 0);
+
+ if (ret != SPI_OK_SELECT)
+ {
+ elog (ERROR, "SPI_execute_plan failed: %d \n", ret);
+ }
+
+ proc = SPI_processed;
+
+ if (proc > 0)
+ {
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable->tupdesc;
+ HeapTuple tuple;
+ int i;
+
+ for (i = 0; i < proc; i++)
+ {
+ tuple = tuptable->vals[i];
+ for (int j = 1; j <= tupdesc->natts; j++)
+ {
+ char *value = SPI_getvalue (tuple, tupdesc, j);
+ result += atoi (value);
+ }
+ }
+ }
+ SPI_finish ();
+ PG_RETURN_INT64 (result);
+}
+
+
+Datum
+pg_spi_update_y (PG_FUNCTION_ARGS)
+{
+ int ret;
+ int nargs;
+ Oid argtypes[1];
+ Datum values[1];
+ const char *query = "UPDATE Y SET col1 = 4 WHERE (col2 = $1)";
+
+ ret = SPI_connect ();
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "SPI_connect failed ! \n");
+ }
+
+ nargs = 1;
+ argtypes[0] = INT4OID;
+ values[0] = Int32GetDatum (0);
+
+ ret = SPI_execute_with_args (query, nargs, argtypes, values, NULL, false, 0);
+ if (ret != SPI_OK_UPDATE)
+ {
+ elog (ERROR, "SPI_execute_with_args failed ! \n");
+ }
+
+ SPI_finish ();
+
+ PG_RETURN_VOID ();
+}
+
+
+Datum
+pg_spi_prepare_update (PG_FUNCTION_ARGS)
+{
+ static SPIPlanPtr prepared_plan = NULL;
+ SPIPlanPtr new_plan;
+ int ret;
+ int nargs;
+ Oid argtypes[1];
+ Datum values[1];
+ const char *query = "UPDATE Y SET col1 = 4 WHERE (col2 = $1)";
+
+ ret = SPI_connect ();
+ if (ret != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "SPI_connect failed ! \n");
+ }
+
+ if (prepared_plan == NULL)
+ {
+ argtypes[0] = INT4OID;
+ nargs = 1;
+ values[0] = Int32GetDatum (3);
+ // PREPARE
+ new_plan = SPI_prepare (query, nargs, argtypes);
+ if (new_plan == NULL)
+ elog (ERROR, "SPI_prepare failed ! \n");
+ // SAVEPLAN
+ prepared_plan = SPI_saveplan (new_plan);
+ if (prepared_plan == NULL)
+ elog (ERROR, "SPI_saveplan failed ! \n");
+ }
+ ret = SPI_execute_plan (prepared_plan, values, NULL, false, 0);
+ if (ret != SPI_OK_UPDATE)
+ elog (ERROR, "SPI_execute_plan failed ! \n");
+
+ SPI_finish ();
+ PG_RETURN_VOID ();
+}
+
+
+/*
+Datum
+pg_spi_prepare_update_without_saveplan(PG_FUNCTION_ARGS)
+{}*/
+void
+_PG_fini (void)
+{
+}
+
+
+/*
+
+*/
+
+
+Datum
+pg_spi_get_dep_ref_fees (PG_FUNCTION_ARGS)
+{
+ /* Define plan to save */
+ static SPIPlanPtr deposit_plan;
+ static SPIPlanPtr ref_plan;
+ static SPIPlanPtr fees_plan;
+ static SPIPlanPtr dummy_plan;
+ /* Define variables to update */
+ Timestamp refund_deadline = PG_GETARG_TIMESTAMP (0);
+ bytea *merchant_pub = PG_GETARG_BYTEA_P (1);
+ bytea *wire_target_h_payto = PG_GETARG_BYTEA_P (2);
+ bytea *wtid_raw = PG_GETARG_BYTEA_P (3);
+ bool is_null;
+ /* Define variables to store the results of each SPI query */
+ uint64_t sum_deposit_val = 0;
+ uint32_t sum_deposit_frac = 0;
+ uint64_t s_refund_val = 0;
+ uint32_t s_refund_frac = 0;
+ uint64_t sum_dep_fee_val = 0;
+ uint32_t sum_dep_fee_frac = 0;
+ uint64_t norm_refund_val = 0;
+ uint32_t norm_refund_frac = 0;
+ uint64_t sum_refund_val = 0;
+ uint32_t sum_refund_frac = 0;
+ /* Define variables to store the Tuptable */
+ SPITupleTable *dep_res;
+ SPITupleTable *ref_res;
+ SPITupleTable *ref_by_coin_res;
+ SPITupleTable *norm_ref_by_coin_res;
+ SPITupleTable *fully_refunded_coins_res;
+ SPITupleTable *fees_res;
+ SPITupleTable *dummys_res;
+ /* Define variable to update */
+ Datum values_refund[2];
+ Datum values_deposit[3];
+ Datum values_fees[2];
+ Datum values_dummys[2];
+ TupleDesc tupdesc;
+ /* Define variables to replace some tables */
+ bytea *ref_by_coin_coin_pub;
+ int64 ref_by_coin_deposit_serial_id = 0;
+ bytea *norm_ref_by_coin_coin_pub;
+ int64_t norm_ref_by_coin_deposit_serial_id = 0;
+ bytea *new_dep_coin_pub = NULL;
+ int res = SPI_connect ();
+
+ /* Connect to SPI */
+ if (res < 0)
+ {
+ elog (ERROR, "Could not connect to SPI manager");
+ }
+ if (deposit_plan == NULL)
+ {
+ const char *dep_sql;
+ SPIPlanPtr new_plan;
+
+ // Execute first query and store results in variables
+ dep_sql =
+ "UPDATE deposits SET done=TRUE "
+ "WHERE NOT (done OR policy_blocked) "
+ "AND refund_deadline=$1 "
+ "AND merchant_pub=$2 "
+ "AND wire_target_h_payto=$3 "
+ "RETURNING "
+ "deposit_serial_id,"
+ "coin_pub,"
+ "amount_with_fee_val,"
+ "amount_with_fee_frac;";
+ fprintf (stderr, "dep sql %d\n", 1);
+ new_plan =
+ SPI_prepare (dep_sql, 4,(Oid[]){INT8OID, BYTEAOID, BYTEAOID});
+ fprintf (stderr, "dep sql %d\n", 2);
+ if (new_plan == NULL)
+ elog (ERROR, "SPI_prepare failed for dep \n");
+ deposit_plan = SPI_saveplan (new_plan);
+ if (deposit_plan == NULL)
+ elog (ERROR, "SPI_saveplan failed for dep \n");
+ }
+ fprintf (stdout, "dep sql %d\n", 3);
+
+ values_deposit[0] = Int64GetDatum (refund_deadline);
+ values_deposit[1] = PointerGetDatum (merchant_pub);
+ values_deposit[2] = PointerGetDatum (wire_target_h_payto);
+
+ res = SPI_execute_plan (deposit_plan,
+ values_deposit,
+ NULL,
+ true,
+ 0);
+ fprintf (stdout, "dep sql %d\n", 4);
+ if (res != SPI_OK_UPDATE)
+ {
+ elog (ERROR, "Failed to execute subquery 1 \n");
+ }
+ // STORE TUPTABLE deposit
+ dep_res = SPI_tuptable;
+
+ for (unsigned int i = 0; i < SPI_processed; i++)
+ {
+ int64 dep_deposit_serial_ids = DatumGetInt64 (SPI_getbinval (
+ SPI_tuptable->vals[i],
+ SPI_tuptable->tupdesc, 1,
+ &is_null));
+ bytea *dep_coin_pub = DatumGetByteaP (SPI_getbinval (SPI_tuptable->vals[i],
+ SPI_tuptable->tupdesc,
+ 2, &is_null));
+ int64 dep_amount_val = DatumGetInt64 (SPI_getbinval (SPI_tuptable->vals[i],
+ SPI_tuptable->tupdesc,
+ 3, &is_null));
+ int32 dep_amount_frac = DatumGetInt32 (SPI_getbinval (SPI_tuptable->vals[i],
+ SPI_tuptable->tupdesc,
+ 4, &is_null));
+
+ if (is_null)
+ elog (ERROR, "Failed to retrieve data from deposit \n");
+ if (ref_plan == NULL)
+ {
+ // Execute second query with parameters from first query and store results in variables
+ const char *ref_sql =
+ "SELECT amount_with_fee_val, amount_with_fee_frac, coin_pub, deposit_serial_id "
+ "FROM refunds "
+ "WHERE coin_pub=$1 "
+ "AND deposit_serial_id=$2;";
+ SPIPlanPtr new_plan = SPI_prepare (ref_sql, 3, (Oid[]){BYTEAOID,
+ INT8OID});
+ if (new_plan == NULL)
+ elog (ERROR, "SPI_prepare failed for refund\n");
+ ref_plan = SPI_saveplan (new_plan);
+ if (ref_plan == NULL)
+ elog (ERROR, "SPI_saveplan failed for refund\n");
+ }
+ values_refund[0] = PointerGetDatum (dep_coin_pub);
+ values_refund[1] = Int64GetDatum (dep_deposit_serial_ids);
+ res = SPI_execute_plan (ref_plan,
+ values_refund,
+ NULL,
+ false,
+ 0);
+ if (res != SPI_OK_SELECT)
+ elog (ERROR, "Failed to execute subquery 2\n");
+ // STORE TUPTABLE refund
+ ref_res = SPI_tuptable;
+ for (unsigned int j = 0; j < SPI_processed; j++)
+ {
+ int64 ref_refund_val = DatumGetInt64 (SPI_getbinval (
+ SPI_tuptable->vals[j],
+ SPI_tuptable->tupdesc, 1,
+ &is_null));
+ int32 ref_refund_frac = DatumGetInt32 (SPI_getbinval (
+ SPI_tuptable->vals[j],
+ SPI_tuptable->tupdesc, 2,
+ &is_null));
+ bytea *ref_coin_pub = DatumGetByteaP (SPI_getbinval (
+ SPI_tuptable->vals[j],
+ SPI_tuptable->tupdesc, 3,
+ &is_null));
+ int64 ref_deposit_serial_id = DatumGetInt64 (SPI_getbinval (
+ SPI_tuptable->vals[j],
+ SPI_tuptable->tupdesc, 4,
+ &is_null));
+ // Execute third query with parameters from second query and store results in variables
+ ref_by_coin_coin_pub = ref_coin_pub;
+ ref_by_coin_deposit_serial_id = ref_deposit_serial_id;
+ // LOOP TO GET THE SUM FROM REFUND BY COIN
+ for (unsigned int i = 0; ivals[i],
+ SPI_tuptable->tupdesc, 1,
+ &is_null)))
+ &&
+ (ref_by_coin_deposit_serial_id ==
+ DatumGetUInt64 (SPI_getbinval (SPI_tuptable->vals[i],
+ SPI_tuptable->tupdesc, 2,
+ &is_null)))
+ )
+ {
+ sum_refund_val += ref_refund_val;
+ sum_refund_frac += ref_refund_frac;
+ norm_ref_by_coin_coin_pub = ref_by_coin_coin_pub;
+ norm_ref_by_coin_deposit_serial_id = ref_by_coin_deposit_serial_id;
+ }
+ }// END SUM CALCULATION
+ // NORMALIZE REFUND VAL FRAC
+ norm_refund_val =
+ (sum_refund_val + sum_refund_frac) / 100000000;
+ norm_refund_frac =
+ sum_refund_frac % 100000000;
+ // Get refund values
+ s_refund_val += sum_refund_val;
+ s_refund_frac = sum_refund_frac;
+ }// END REFUND
+ if (norm_ref_by_coin_coin_pub == dep_coin_pub
+ && ref_by_coin_deposit_serial_id == dep_deposit_serial_ids
+ && norm_refund_val == dep_amount_val
+ && norm_refund_frac == dep_amount_frac)
+ {
+ new_dep_coin_pub = dep_coin_pub;
+ }
+ // Ensure we get the fee for each coin and not only once per denomination
+ if (fees_plan == NULL)
+ {
+ const char *fees_sql =
+ "SELECT "
+ " denom.fee_deposit_val AS fee_val, "
+ " denom.fee_deposit_frac AS fee_frac, "
+ "FROM known_coins kc"
+ "JOIN denominations denom USING (denominations_serial) "
+ "WHERE kc.coin_pub = $1 AND kc.coin_pub != $2;";
+ SPIPlanPtr new_plan = SPI_prepare (fees_sql, 3, (Oid[]){BYTEAOID,
+ BYTEAOID});
+ if (new_plan == NULL)
+ {
+ elog (ERROR, "SPI_prepare for fees failed ! \n");
+ }
+ fees_plan = SPI_saveplan (new_plan);
+ if (fees_plan == NULL)
+ {
+ elog (ERROR, "SPI_saveplan for fees failed ! \n");
+ }
+ }
+ values_fees[0] = PointerGetDatum (dep_coin_pub);
+ values_fees[1] = PointerGetDatum (new_dep_coin_pub);
+ res = SPI_execute_plan (fees_plan, values_fees, NULL, false, 0);
+ if (res != SPI_OK_SELECT)
+ elog (ERROR, "SPI_execute_plan failed for fees \n");
+ fees_res = SPI_tuptable;
+ tupdesc = fees_res->tupdesc;
+ for (unsigned int i = 0; ivals[i];
+ bool is_null;
+ uint64_t fee_val = DatumGetUInt64 (SPI_getbinval (tuple, tupdesc, 1,
+ &is_null));
+ uint32_t fee_frac = DatumGetUInt32 (SPI_getbinval (tuple, tupdesc, 2,
+ &is_null));
+ uint64_t fees_deposit_serial_id = DatumGetUInt64 (SPI_getbinval (tuple,
+ tupdesc,
+ 3,
+ &is_null));
+ if (dummy_plan == NULL)
+ {
+ const char *insert_dummy_sql =
+ "INSERT INTO "
+ "aggregation_tracking(deposit_serial_id, wtid_raw)"
+ " VALUES ($1, $2)";
+
+ SPIPlanPtr new_plan = SPI_prepare (insert_dummy_sql, 2, (Oid[]){INT8OID,
+ BYTEAOID});
+ if (new_plan == NULL)
+ elog (ERROR, "FAILED to prepare aggregation tracking \n");
+ dummy_plan = SPI_saveplan (new_plan);
+ if (dummy_plan == NULL)
+ elog (ERROR, "FAILED to saveplan aggregation tracking\n");
+ }
+ values_dummys[0] = Int64GetDatum (dep_deposit_serial_ids);
+ values_dummys[1] = PointerGetDatum (wtid_raw);
+ res = SPI_execute_plan (dummy_plan, values_dummys, NULL, false, 0);
+ if (res != SPI_OK_INSERT)
+ elog (ERROR, "Failed to insert dummy\n");
+ dummys_res = SPI_tuptable;
+ // Calculation of deposit fees for not fully refunded deposits
+ sum_dep_fee_val += fee_val;
+ sum_dep_fee_frac += fee_frac;
+ }
+ // Get deposit values
+ sum_deposit_val += dep_amount_val;
+ sum_deposit_frac += dep_amount_frac;
+ }// END DEPOSIT
+ SPI_finish ();
+ PG_RETURN_VOID ();
+}
diff --git a/src/exchangedb/spi/own_test.control b/src/exchangedb/spi/own_test.control
new file mode 100644
index 000000000..4e73e207f
--- /dev/null
+++ b/src/exchangedb/spi/own_test.control
@@ -0,0 +1,4 @@
+comment = 'Example extension for testing purposes'
+default_version = '1.0'
+module_pathname = '$libdir/own_test'
+relocatable = true
diff --git a/src/exchangedb/spi/own_test.sql b/src/exchangedb/spi/own_test.sql
new file mode 100644
index 000000000..12729d068
--- /dev/null
+++ b/src/exchangedb/spi/own_test.sql
@@ -0,0 +1,201 @@
+DROP TABLE IF EXISTS X;
+CREATE TABLE X (
+ a integer
+);
+
+INSERT INTO X (a)
+ VALUES (1), (2), (3), (4), (5), (6), (7);
+
+DROP TABLE IF EXISTS Y;
+CREATE TABLE Y (col1 INT, col2 INT);
+INSERT INTO Y (col1,col2)
+ VALUES (1,2), (2,0), (0,4), (4,0), (0,6), (6,7), (7,8);
+
+DROP TABLE IF EXISTS Z;
+CREATE TABLE Z (col1 BYTEA);
+
+DROP TABLE IF EXISTS deposits;
+CREATE TABLE deposits(
+ deposit_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY
+ ,shard INT8 NOT NULL
+ ,coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)
+ ,known_coin_id INT8 NOT NULL
+ ,amount_with_fee_val INT8 NOT NULL
+ ,amount_with_fee_frac INT4 NOT NULL
+ ,wallet_timestamp INT8 NOT NULL
+ ,exchange_timestamp INT8 NOT NULL
+ ,refund_deadline INT8 NOT NULL
+ ,wire_deadline INT8 NOT NULL
+ ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)
+ ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)
+ ,coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)
+ ,wire_salt BYTEA NOT NULL CHECK (LENGTH(wire_salt)=16)
+ ,wire_target_h_payto BYTEA CHECK (LENGTH(wire_target_h_payto)=32)
+ ,done BOOLEAN NOT NULL DEFAULT FALSE
+ ,policy_blocked BOOLEAN NOT NULL DEFAULT FALSE
+ ,policy_details_serial_id INT8);
+
+
+DROP FUNCTION IF EXISTS pg_spi_insert_int;
+CREATE FUNCTION pg_spi_insert_int()
+ RETURNS VOID
+ LANGUAGE c VOLATILE COST 100
+AS '$libdir/own_test', 'pg_spi_insert_int';
+
+DROP FUNCTION IF EXISTS pg_spi_select_from_x;
+CREATE FUNCTION pg_spi_select_from_x()
+ RETURNS INT8
+ LANGUAGE c COST 100
+AS '$libdir/own_test', 'pg_spi_select_from_x';
+
+/*
+CREATE FUNCTION pg_spi_select_pair_from_y()
+ RETURNS valuest
+ LANGUAGE c COST 100
+AS '$libdir/own_test', 'pg_spi_select_pair_from_y';
+*/
+/*CREATE FUNCTION pg_spi_select_with_cond()
+ RETURNS INT8
+ LANGUAGE c COST 100
+AS '$libdir/own_test', 'pg_spi_select_with_cond';
+*/
+
+DROP FUNCTION IF EXISTS pg_spi_update_y;
+CREATE FUNCTION pg_spi_update_y()
+ RETURNS VOID
+ LANGUAGE c VOLATILE COST 100
+AS '$libdir/own_test', 'pg_spi_update_y';
+
+DROP FUNCTION IF EXISTS pg_spi_prepare_example;
+CREATE FUNCTION pg_spi_prepare_example()
+ RETURNS INT8
+ LANGUAGE c COST 100
+AS '$libdir/own_test', 'pg_spi_prepare_example';
+
+DROP FUNCTION IF EXISTS pg_spi_prepare_example_without_saveplan;
+CREATE FUNCTION pg_spi_prepare_example_without_saveplan()
+ RETURNS INT8
+ LANGUAGE c COST 100
+AS '$libdir/own_test', 'pg_spi_prepare_example_without_saveplan';
+
+DROP FUNCTION IF EXISTS pg_spi_prepare_insert;
+CREATE FUNCTION pg_spi_prepare_insert()
+ RETURNS VOID
+ LANGUAGE c VOLATILE COST 100
+AS '$libdir/own_test', 'pg_spi_prepare_insert';
+
+DROP FUNCTION IF EXISTS pg_spi_prepare_insert_without_saveplan;
+CREATE FUNCTION pg_spi_prepare_insert_without_saveplan()
+ RETURNS VOID
+ LANGUAGE c VOLATILE COST 100
+AS '$libdir/own_test', 'pg_spi_prepare_insert_without_saveplan';
+
+/*
+CREATE FUNCTION pg_spi_prepare_select_with_cond()
+ RETURNS INT8
+ LANGUAGE c COST 100
+AS '$libdir/own_test', 'pg_spi_prepare_select_with_cond';
+*/
+
+DROP FUNCTION IF EXISTS pg_spi_prepare_select_with_cond_without_saveplan;
+CREATE FUNCTION pg_spi_prepare_select_with_cond_without_saveplan()
+ RETURNS INT8
+ LANGUAGE c COST 100
+AS '$libdir/own_test', 'pg_spi_prepare_select_with_cond_without_saveplan';
+
+DROP FUNCTION IF EXISTS pg_spi_prepare_update;
+CREATE FUNCTION pg_spi_prepare_update()
+ RETURNS VOID
+ LANGUAGE c VOLATILE COST 100
+AS '$libdir/own_test', 'pg_spi_prepare_update';
+
+DROP FUNCTION IF EXISTS pg_spi_get_dep_ref_fees;
+CREATE FUNCTION pg_spi_get_dep_ref_fees(
+ IN in_timestamp INT8
+ ,IN merchant_pub BYTEA
+ ,IN wire_target_h_payto BYTEA
+ ,IN wtid BYTEA
+)
+ RETURNS VOID
+ LANGUAGE c VOLATILE COST 100
+AS '$libdir/own_test', 'pg_spi_get_dep_ref_fees';
+
+DROP FUNCTION IF EXISTS update_pg_spi_get_dep_ref_fees;
+CREATE FUNCTION update_pg_spi_get_dep_ref_fees(
+ IN in_refund_deadline INT8,
+ IN in_merchant_pub BYTEA,
+ IN in_wire_target_h_payto BYTEA
+)
+RETURNS SETOF record
+LANGUAGE plpgsql VOLATILE
+AS $$
+DECLARE
+
+BEGIN
+RETURN QUERY
+ UPDATE deposits
+ SET done = TRUE
+ WHERE NOT (done OR policy_blocked)
+ AND refund_deadline < in_refund_deadline
+ AND merchant_pub = in_merchant_pub
+ AND wire_target_h_payto = in_wire_target_h_payto
+ RETURNING
+ deposit_serial_id,
+ coin_pub,
+ amount_with_fee_val,
+ amount_with_fee_frac;
+END $$;
+
+DROP FUNCTION IF EXISTS stored_procedure_update;
+CREATE FUNCTION stored_procedure_update(
+IN in_number INT8
+)
+RETURNS VOID
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ UPDATE Y
+ SET col1 = 4
+ WHERE col2 = in_number;
+END $$;
+
+DROP FUNCTION IF EXISTS stored_procedure_select;
+CREATE FUNCTION stored_procedure_select(OUT out_value INT8)
+RETURNS INT8
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ SELECT 1
+ INTO out_value
+ FROM X;
+ RETURN;
+END $$;
+
+
+DROP FUNCTION IF EXISTS stored_procedure_insert;
+CREATE FUNCTION stored_procedure_insert(
+IN in_number INT8,
+OUT out_number INT8)
+RETURNS INT8
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ INSERT INTO X (a)
+ VALUES (in_number)
+ RETURNING a INTO out_number;
+END $$;
+
+DROP FUNCTION IF EXISTS stored_procedure_select_with_cond;
+CREATE FUNCTION stored_procedure_select_with_cond(
+IN in_number INT8,
+OUT out_number INT8
+)
+RETURNS INT8
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ SELECT col1 INTO out_number
+ FROM Y
+ WHERE col2 = in_number;
+ RETURN;
+END $$;
diff --git a/src/exchangedb/spi/perf_own_test.c b/src/exchangedb/spi/perf_own_test.c
new file mode 100644
index 000000000..92be2235e
--- /dev/null
+++ b/src/exchangedb/spi/perf_own_test.c
@@ -0,0 +1,25 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2023 Taler Systems SA
+
+ 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, see
+*/
+/**
+ * @file exchangedb/spi/perf_own_test.c
+ * @brief benchmark for 'own_test'
+ * @author Joseph Xu
+ */
+#include "exchangedb/platform.h"
+#include "exchangedb/taler_exchangedb_lib.h"
+#include "exchangedb/taler_json_lib.h"
+#include "exchangedb/taler_exchangedb_plugin.h"
+#include "own_test.sql"
diff --git a/src/exchangedb/spi/pg_aggregate.c b/src/exchangedb/spi/pg_aggregate.c
new file mode 100644
index 000000000..721f247c7
--- /dev/null
+++ b/src/exchangedb/spi/pg_aggregate.c
@@ -0,0 +1,411 @@
+#include "postgres.h"
+#include "fmgr.h"
+#include "utils/numeric.h"
+#include "utils/builtins.h"
+#include "executor/spi.h"
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1 (get_deposit_summary);
+
+Datum
+get_deposit_summary (PG_FUNCTION_ARGS)
+{
+
+ static SPIPlanPtr deposit_plan;
+ static SPIPlanPtr refund_plan;
+ static SPIPlanPtr refund_by_coin_plan;
+ static SPIPlanPtr norm_refund_by_coin_plan;
+ static SPIPlanPtr fully_refunded_by_coins_plan;
+ static SPIPlanPtr fees_plan;
+
+ int shard = PG_GETARG_INT32 (0);
+ char *sql;
+ char *merchant_pub = text_to_cstring (PG_GETARG_TEXT_P (1));
+ char *wire_target_h_payto = text_to_cstring (PG_GETARG_TEXT_P (2));
+ char *wtid_raw = text_to_cstring (PG_GETARG_TEXT_P (3));
+ int refund_deadline = PG_GETARG_INT32 (4);
+ int conn = SPI_connect ();
+ if (conn != SPI_OK_CONNECT)
+ {
+ elog (ERROR, "DB connection failed ! \n");
+ }
+
+ if (deposit_plan == NULL
+ || refund_plan == NULL
+ || refund_by_coin_plan == NULL
+ || norm_refund_by_coin_plan = NULL
+ || fully_refunded_coins_plan = NULL
+ || fees_plan
+ == NULL)
+ {
+ if (deposit_plan == NULL)
+ {
+ int nargs = 3;
+ Oid argtypes[3];
+ argtypes[0] = INT8OID;
+ argtypes[1] = BYTEAOID;
+ argtypes[2] = BYTEAOID;
+ const char *dep_sql =
+ " UPDATE deposits"
+ " SET done=TRUE"
+ " WHERE NOT (done OR policy_blocked)"
+ " AND refund_deadline < $1"
+ " AND merchant_pub = $2"
+ " AND wire_target_h_payto = $3"
+ " RETURNING"
+ " deposit_serial_id"
+ " ,coin_pub"
+ " ,amount_with_fee_val AS amount_val"
+ " ,amount_with_fee_frac AS amount_frac";
+ SPIPlanPtr new_plan =
+ SPI_prepare (dep_sql, 4, argtypes);
+ if (new_plan == NULL)
+ {
+ elog (ERROR, "SPI_prepare for deposit failed ! \n");
+ }
+ deposit_plan = SPI_saveplan (new_plan);
+ if (deposit_plan == NULL)
+ {
+ elog (ERROR, "SPI_saveplan for deposit failed ! \n");
+ }
+ }
+
+ Datum values[4];
+ values[0] = Int64GetDatum (refund_deadline);
+ values[1] = CStringGetDatum (merchant_pub);
+ values[2] = CStringGetDatum (wire_target_h_payto);
+ int ret = SPI_execute_plan (deposit_plan,
+ values,
+ NULL,
+ true,
+ 0);
+ if (ret != SPI_OK_UPDATE)
+ {
+ elog (ERROR, "Failed to execute subquery 1\n");
+ }
+ uint64_t *dep_deposit_serial_ids = palloc (sizeof(uint64_t)
+ * SPI_processed);
+ BYTEA **dep_coin_pubs = palloc (sizeof(BYTEA *) * SPI_processed);
+ uint64_t *dep_amount_vals = palloc (sizeof(uint64_t) * SPI_processed);
+ uint32_t *dep_amount_fracs = palloc (sizeof(uint32_t) * SPI_processed);
+ for (unsigned int i = 0; i < SPI_processed; i++)
+ {
+ HeapTuple tuple = SPI_tuptable->vals[i];
+ dep_deposit_serial_ids[i] =
+ DatumGetInt64 (SPI_getbinval (tuple, SPI_tuptable->tupdesc, 1, &ret));
+ dep_coin_pubs[i] =
+ DatumGetByteaP (SPI_getbinval (tuple, SPI_tuptable->tupdesc, 2, &ret));
+ dep_amount_vals[i] =
+ DatumGetInt64 (SPI_getbinval (tuple, SPI_tuptable->tupdesc, 3, &ret));
+ dep_amount_fracs[i] =
+ DatumGetInt32 (SPI_getbinval (tuple, SPI_tuptable->tupdesc, 4, &ret));
+ }
+
+
+ if (refund_plan == NULL)
+ {
+ const char *ref_sql =
+ "ref AS ("
+ " SELECT"
+ " amount_with_fee_val AS refund_val"
+ " ,amount_with_fee_frac AS refund_frac"
+ " ,coin_pub"
+ " ,deposit_serial_id"
+ " FROM refunds"
+ " WHERE coin_pub IN (SELECT coin_pub FROM dep)"
+ " AND deposit_serial_id IN (SELECT deposit_serial_id FROM dep)) ";
+ SPIPlanPtr new_plan = SPI_prepare (ref_sql, 0, NULL);
+ if (new_plan == NULL)
+ elog (ERROR, "SPI_prepare for refund failed ! \n");
+ refund_plan = SPI_saveplan (new_plan);
+ if (refund_plan == NULL)
+ {
+ elog (ERROR, "SPI_saveplan for refund failed ! \n");
+ }
+ }
+
+ int64t_t *ref_deposit_serial_ids = palloc (sizeof(int64_t) * SPI_processed);
+
+ int res = SPI_execute_plan (refund_plan, NULL, NULL, false, 0);
+ if (res != SPI_OK_SELECT)
+ {
+ elog (ERROR, "Failed to execute subquery 2\n");
+ }
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable->tupdesc;
+ for (unsigned int i = 0; i < SPI_processed; i++)
+ {
+ HeapTuple tuple = tuptable->vals[i];
+ Datum refund_val = SPI_getbinval (tuple, tupdesc, 1, &refund_val_isnull);
+ Datum refund_frac = SPI_getbinval (tuple, tupdesc, 2,
+ &refund_frac_isnull);
+ Datum coin_pub = SPI_getbinval (tuple, tupdesc, 3, &coin_pub_isnull);
+ Datum deposit_serial_id = SPI_getbinval (tuple, tupdesc, 4,
+ &deposit_serial_id_isnull);
+ if (refund_val_isnull
+ || refund_frac_isnull
+ || coin_pub_isnull
+ || deposit_serial_id_isnull)
+ {
+ elog (ERROR, "Failed to retrieve data from subquery 2");
+ }
+ uint64_t refund_val_int = DatumGetUInt64 (refund_val);
+ uint32_t refund_frac_int = DatumGetUInt32 (refund_frac);
+ BYTEA coin_pub = DatumGetByteaP (coin_pub);
+ ref_deposit_serial_ids = DatumGetInt64 (deposit_serial_id);
+
+ refund *new_refund = (refund*) palloc (sizeof(refund));
+ new_refund->coin_pub = coin_pub_str;
+ new_refund->deposit_serial_id = deposit_serial_id_int;
+ new_refund->amount_with_fee_val = refund_val_int;
+ new_refund->amount_with_fee_frac = refund_frac_int;
+ }
+
+
+ if (refund_by_coin_plan == NULL)
+ {
+ const char *ref_by_coin_sql =
+ "ref_by_coin AS ("
+ " SELECT"
+ " SUM(refund_val) AS sum_refund_val"
+ " ,SUM(refund_frac) AS sum_refund_frac"
+ " ,coin_pub"
+ " ,deposit_serial_id"
+ " FROM ref"
+ " GROUP BY coin_pub, deposit_serial_id) ";
+ SPIPlanPtr new_plan = SPI_prepare (ref_by_coin_sql, 0, NULL);
+ if (new_plan == NULL)
+ elog (ERROR, "SPI_prepare for refund by coin failed ! \n");
+ refund_by_coin_plan = SPI_saveplan (new_plan);
+ if (refund_by_coin_plan == NULL)
+ elog (ERROR, "SPI_saveplan for refund failed");
+ }
+
+
+ int res = SPI_execute_plan (refund_by_coin_plan, NULL, NULL, false, 0);
+ if (res != SPI_OK_SELECT)
+ {
+ elog (ERROR, "Failed to execute subquery 2\n");
+ }
+
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable->tupdesc;
+ for (unsigned int i = 0; i < SPI_processed; i++)
+ {
+ HeapTuple tuple = tuptable->vals[i];
+ Datum sum_refund_val = SPI_getbinval (tuple, tupdesc, 1,
+ &refund_val_isnull);
+ Datum sum_refund_frac = SPI_getbinval (tuple, tupdesc, 2,
+ &refund_frac_isnull);
+ Datum coin_pub = SPI_getbinval (tuple, tupdesc, 3, &coin_pub_isnull);
+ Datum deposit_serial_id_int = SPI_getbinval (tuple, tupdesc, 4,
+ &deposit_serial_id_isnull);
+ if (refund_val_isnull
+ || refund_frac_isnull
+ || coin_pub_isnull
+ || deposit_serial_id_isnull)
+ {
+ elog (ERROR, "Failed to retrieve data from subquery 2");
+ }
+ uint64_t s_refund_val_int = DatumGetUInt64 (sum_refund_val);
+ uint32_t s_refund_frac_int = DatumGetUInt32 (sum_refund_frac);
+ BYTEA coin_pub = DatumGetByteaP (coin_pub);
+ uint64_t deposit_serial_id_int = DatumGetInt64 (deposit_serial_id_int);
+ refund *new_refund_by_coin = (refund*) palloc (sizeof(refund));
+ new_refund_by_coin->coin_pub = coin_pub;
+ new_refund_by_coin->deposit_serial_id = deposit_serial_id_int;
+ new_refund_by_coin->refund_amount_with_fee_val = s_refund_val_int;
+ new_refund_by_coin->refund_amount_with_fee_frac = s_refund_frac_int;
+ }
+
+
+ if (norm_refund_by_coin_plan == NULL)
+ {
+ const char *norm_ref_by_coin_sql =
+ "norm_ref_by_coin AS ("
+ " SELECT"
+ " coin_pub"
+ " ,deposit_serial_id"
+ " FROM ref_by_coin) ";
+ SPIPlanPtr new_plan = SPI_prepare (norm_ref_by_coin_sql, 0, NULL);
+ if (new_plan == NULL)
+ elog (ERROR, "SPI_prepare for norm refund by coin failed ! \n");
+ norm_refund_by_coin_plan = SPI_saveplan (new_plan);
+ if (norm_refund_by_coin_plan == NULL)
+ elog (ERROR, "SPI_saveplan for norm refund by coin failed ! \n");
+ }
+
+ double norm_refund_val =
+ ((double) new_refund_by_coin->refund_amount_with_fee_val
+ + (double) new_refund_by_coin->refund_amount_with_fee_frac) / 100000000;
+ double norm_refund_frac =
+ (double) new_refund_by_coin->refund_amount_with_fee_frac % 100000000;
+
+ if (fully_refunded_coins_plan == NULL)
+ {
+ const char *fully_refunded_coins_sql =
+ "fully_refunded_coins AS ("
+ " SELECT"
+ " dep.coin_pub"
+ " FROM norm_ref_by_coin norm"
+ " JOIN dep"
+ " ON (norm.coin_pub = dep.coin_pub"
+ " AND norm.deposit_serial_id = dep.deposit_serial_id"
+ " AND norm.norm_refund_val = dep.amount_val"
+ " AND norm.norm_refund_frac = dep.amount_frac)) ";
+ SPIPlanPtr new_plan =
+ SPI_prepare (fully_refunded_coins_sql, 0, NULL);
+ if (new_plan == NULL)
+ elog (ERROR, "SPI_prepare for fully refunded coins failed ! \n");
+ fully_refunded_coins_plan = SPI_saveplan (new_plan);
+ if (fully_refunded_coins_plan == NULL)
+ elog (ERROR, "SPI_saveplan for fully refunded coins failed ! \n");
+ }
+
+ int res = SPI_execute_plan (fully_refunded_coins_sql);
+ if (res != SPI_OK_SELECT)
+ elog (ERROR, "Failed to execute subquery 4\n");
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable->tupdesc;
+
+ BYTEA coin_pub = SPI_getbinval (tuple, tupdesc, 1, &coin_pub_isnull);
+ if (fees_plan == NULL)
+ {
+ const char *fees_sql =
+ "SELECT "
+ " denom.fee_deposit_val AS fee_val, "
+ " denom.fee_deposit_frac AS fee_frac, "
+ " cs.deposit_serial_id "
+ "FROM dep cs "
+ "JOIN known_coins kc USING (coin_pub) "
+ "JOIN denominations denom USING (denominations_serial) "
+ "WHERE coin_pub NOT IN (SELECT coin_pub FROM fully_refunded_coins)";
+ SPIPlanPtr new_plan =
+ SPI_prepare (fees_sql, 0, NULL);
+ if (new_plan == NULL)
+ {
+ elog (ERROR, "SPI_prepare for fees failed ! \n");
+ }
+ fees_plan = SPI_saveplan (new_plan);
+ if (fees_plan == NULL)
+ {
+ elog (ERROR, "SPI_saveplan for fees failed ! \n");
+ }
+ }
+ }
+ int fees_ntuples;
+ SPI_execute (fees_sql, true, 0);
+ if (SPI_result_code () != SPI_OK_SELECT)
+ {
+ ereport (
+ ERROR,
+ (errcode (ERRCODE_INTERNAL_ERROR),
+ errmsg ("deposit fee query failed: error code %d \n",
+ SPI_result_code ())));
+ }
+ fees_ntuples = SPI_processed;
+
+ if (fees_ntuples > 0)
+ {
+ for (i = 0; i < fees_ntuples; i++)
+ {
+ Datum fee_val_datum =
+ SPI_getbinval (SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1,
+ &fee_null);
+ Datum fee_frac_datum =
+ SPI_getbinval (SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 2,
+ &fee_null);
+ Datum deposit_id_datum =
+ SPI_getbinval (SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 3,
+ &deposit_null);
+ if (! fee_null && ! deposit_null)
+ {
+ int64 fee_val = DatumGetInt64 (fee_val_datum);
+ int32 fee_frac = DatumGetInt32 (fee_frac_datum);
+ int64 deposit_id = DatumGetInt64 (deposit_id_datum);
+ sum_fee_value += fee_val;
+ sum_fee_fraction += fee_frac;
+ char *insert_agg_sql =
+ psprintf (
+ "INSERT INTO "
+ "aggregation_tracking(deposit_serial_id, wtid_raw)"
+ " VALUES (%lld, '%s')",
+ deposit_id, wtid_raw);
+ SPI_execute (insert_agg_sql, false, 0);
+ }
+ }
+ }
+
+ TupleDesc tupdesc;
+ SPITupleTable *tuptable = SPI_tuptable;
+ HeapTuple tuple;
+ Datum result;
+
+ if (tuptable == NULL || SPI_processed != 1)
+ {
+ ereport (
+ ERROR,
+ (errcode (ERRCODE_INTERNAL_ERROR),
+ errmsg ("Unexpected result \n")));
+ }
+ tupdesc = SPI_tuptable->tupdesc;
+ tuple = SPI_tuptable->vals[0];
+ result = HeapTupleGetDatum (tuple);
+
+ TupleDesc result_desc = CreateTemplateTupleDesc (6, false);
+ TupleDescInitEntry (result_desc, (AttrNumber) 1, "sum_deposit_value", INT8OID,
+ -1, 0);
+ TupleDescInitEntry (result_desc, (AttrNumber) 2, "sum_deposit_fraction",
+ INT4OID, -1, 0);
+ TupleDescInitEntry (result_desc, (AttrNumber) 3, "sum_refund_value", INT8OID,
+ -1, 0);
+ TupleDescInitEntry (result_desc, (AttrNumber) 4, "sum_refund_fraction",
+ INT4OID, -1, 0);
+ TupleDescInitEntry (result_desc, (AttrNumber) 5, "sum_fee_value", INT8OID, -1,
+ 0);
+ TupleDescInitEntry (result_desc, (AttrNumber) 6, "sum_fee_fraction", INT4OID,
+ -1, 0);
+
+ int ret = SPI_prepare (sql, 4, argtypes);
+ if (ret != SPI_OK_PREPARE)
+ {
+ elog (ERROR, "Failed to prepare statement: %s \n", sql);
+ }
+
+ ret = SPI_execute_plan (plan, args, nulls, true, 0);
+ if (ret != SPI_OK_SELECT)
+ {
+ elog (ERROR, "Failed to execute statement: %s \n", sql);
+ }
+
+ if (SPI_processed > 0)
+ {
+ HeapTuple tuple;
+ Datum values[6];
+ bool nulls[6] = {false};
+ values[0] =
+ SPI_getbinval (SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1,
+ &nulls[0]);
+ values[1] =
+ SPI_getbinval (SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2,
+ &nulls[1]);
+ values[2] =
+ SPI_getbinval (SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 3,
+ &nulls[2]);
+ values[3] =
+ SPI_getbinval (SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 4,
+ &nulls[3]);
+ values[4] =
+ SPI_getbinval (SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 5,
+ &nulls[4]);
+ values[5] =
+ SPI_getbinval (SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 6,
+ &nulls[5]);
+ tuple = heap_form_tuple (result_desc, values, nulls);
+ PG_RETURN_DATUM (HeapTupleGetDatum (tuple));
+ }
+ SPI_finish ();
+
+ PG_RETURN_NULL ();
+}
diff --git a/src/exchangedb/test_exchangedb_by_j.c b/src/exchangedb/test_exchangedb_by_j.c
index 9769d964b..24b24d5b0 100644
--- a/src/exchangedb/test_exchangedb_by_j.c
+++ b/src/exchangedb/test_exchangedb_by_j.c
@@ -74,8 +74,8 @@ static void
run (void *cls)
{
static const unsigned int batches[] = {1, 2, 3, 4, 8, 16 };
- struct GNUNET_TIME_Relative times[sizeof (batches)/sizeof(*batches)];
- unsigned long long sqrs[sizeof (batches)/sizeof(*batches)];
+ struct GNUNET_TIME_Relative times[sizeof (batches) / sizeof(*batches)];
+ unsigned long long sqrs[sizeof (batches) / sizeof(*batches)];
struct GNUNET_CONFIGURATION_Handle *cfg = cls;
const uint32_t num_partitions = 10;
@@ -101,74 +101,75 @@ run (void *cls)
memset (times, 0, sizeof (times));
memset (sqrs, 0, sizeof (sqrs));
for (unsigned int r = 0; r < ROUNDS; r++)
- {
+ {
for (unsigned int i = 0; i< 6; i++)
+ {
+ const char *sndr = "payto://x-taler-bank/localhost:8080/1";
+ struct TALER_Amount value;
+ unsigned int batch_size = batches[i];
+ unsigned int iterations = 16; // 1024*10;
+ struct TALER_ReservePublicKeyP reserve_pubs[iterations];
+ struct GNUNET_TIME_Absolute now;
+ struct GNUNET_TIME_Timestamp ts;
+ struct GNUNET_TIME_Relative duration;
+ struct TALER_EXCHANGEDB_ReserveInInfo reserves[iterations];
+ enum GNUNET_DB_QueryStatus results[iterations];
+ unsigned long long duration_sq;
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":1.000010",
+ &value));
+ now = GNUNET_TIME_absolute_get ();
+ ts = GNUNET_TIME_timestamp_get ();
+ for (unsigned int r = 0; rbatch2_reserves_in_insert (plugin->cls,
- reserves,
- iterations,
- batch_size,
- results));
- duration = GNUNET_TIME_absolute_get_duration (now);
- times[i] = GNUNET_TIME_relative_add (times[i],
- duration);
- duration_sq = duration.rel_value_us * duration.rel_value_us;
- GNUNET_assert (duration_sq / duration.rel_value_us == duration.rel_value_us);
- GNUNET_assert (sqrs[i] + duration_sq >= sqrs[i]);
- sqrs[i] += duration_sq;
- fprintf (stdout,
- "for a batchsize equal to %d it took %s\n",
- batch_size,
- GNUNET_STRINGS_relative_time_to_string (duration,
- GNUNET_NO) );
-
- system ("./test.sh"); //DELETE AFTER TIMER
+ RND_BLK (&reserve_pubs[r]);
+ reserves[r].reserve_pub = &reserve_pubs[r];
+ reserves[r].balance = &value;
+ reserves[r].execution_time = ts;
+ reserves[r].sender_account_details = sndr;
+ reserves[r].exchange_account_name = "name";
+ reserves[r].wire_reference = r;
}
- }
- for (unsigned int i = 0; i< 6; i++)
- {
- struct GNUNET_TIME_Relative avg;
- double avg_dbl;
- double variance;
+ FAILIF (iterations !=
+ plugin->batch2_reserves_in_insert (plugin->cls,
+ reserves,
+ iterations,
+ batch_size,
+ results));
+ duration = GNUNET_TIME_absolute_get_duration (now);
+ times[i] = GNUNET_TIME_relative_add (times[i],
+ duration);
+ duration_sq = duration.rel_value_us * duration.rel_value_us;
+ GNUNET_assert (duration_sq / duration.rel_value_us ==
+ duration.rel_value_us);
+ GNUNET_assert (sqrs[i] + duration_sq >= sqrs[i]);
+ sqrs[i] += duration_sq;
+ fprintf (stdout,
+ "for a batchsize equal to %d it took %s\n",
+ batch_size,
+ GNUNET_STRINGS_relative_time_to_string (duration,
+ GNUNET_NO) );
- avg = GNUNET_TIME_relative_divide (times[i],
- ROUNDS);
- avg_dbl = avg.rel_value_us;
- variance = sqrs[i] - (avg_dbl * avg_dbl * ROUNDS);
- fprintf(stdout,
- "Batch[%2u]: %8llu ± %6.0f\n",
- batches[i],
- (unsigned long long) avg.rel_value_us,
- sqrt (variance / (ROUNDS-1)));
+ system ("./test.sh"); // DELETE AFTER TIMER
}
+ }
+ for (unsigned int i = 0; i< 6; i++)
+ {
+ struct GNUNET_TIME_Relative avg;
+ double avg_dbl;
+ double variance;
+
+ avg = GNUNET_TIME_relative_divide (times[i],
+ ROUNDS);
+ avg_dbl = avg.rel_value_us;
+ variance = sqrs[i] - (avg_dbl * avg_dbl * ROUNDS);
+ fprintf (stdout,
+ "Batch[%2u]: %8llu ± %6.0f\n",
+ batches[i],
+ (unsigned long long) avg.rel_value_us,
+ sqrt (variance / (ROUNDS - 1)));
+ }
result = 0;
drop:
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 4f52d78fa..61d92483f 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -1947,6 +1947,7 @@ void
TALER_payto_hash (const char *payto,
struct TALER_PaytoHashP *h_payto);
+
/**
* Details about a planchet that the customer wants to obtain
* a withdrawal authorization. This is the information that
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index 2bf71a17e..4099d6bb0 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -3490,8 +3490,16 @@ struct TALER_EXCHANGE_KycStatus
*/
struct TALER_ExchangeSignatureP exchange_sig;
+ /**
+ * AML status for the account.
+ */
+ enum TALER_AmlDecisionState aml_status;
+
} success;
+ /**
+ * KYC is required.
+ */
struct
{
@@ -3502,8 +3510,26 @@ struct TALER_EXCHANGE_KycStatus
*/
const char *kyc_url;
+ /**
+ * AML status for the account.
+ */
+ enum TALER_AmlDecisionState aml_status;
+
} accepted;
+ /**
+ * KYC is OK, but account needs positive AML decision.
+ */
+ struct
+ {
+
+ /**
+ * AML status for the account.
+ */
+ enum TALER_AmlDecisionState aml_status;
+
+ } unavailable_for_legal_reasons;
+
} details;
};
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index cf7659b3b..c3f670579 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2022 Taler Systems SA
+ Copyright (C) 2014-2023 Taler Systems SA
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
@@ -18,6 +18,7 @@
* @brief Low-level (statement-level) database access for the exchange
* @author Florian Dold
* @author Christian Grothoff
+ * @author Özgür Kesim
*/
#ifndef TALER_EXCHANGEDB_PLUGIN_H
#define TALER_EXCHANGEDB_PLUGIN_H
@@ -29,6 +30,47 @@
#include "taler_extensions_policy.h"
+/**
+ * Per-coin information returned when doing a batch insert.
+ */
+struct TALER_EXCHANGEDB_CoinInfo
+{
+ /**
+ * Row of the coin in the known_coins table.
+ */
+ uint64_t known_coin_id;
+
+ /**
+ * Hash of the denomination, relevant on @e denom_conflict.
+ */
+ struct TALER_DenominationHashP denom_hash;
+
+ /**
+ * Hash of the age commitment, relevant on @e age_conflict.
+ */
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * True if the coin was known previously.
+ */
+ bool existed;
+
+ /**
+ * True if the known coin has a different denomination;
+ * application will find denomination of the already
+ * known coin in @e denom_hash.
+ */
+ bool denom_conflict;
+
+ /**
+ * True if the known coin has a different age restriction;
+ * application will find age commitment of the already
+ * known coin in @e h_age_commitment.
+ */
+ bool age_conflict;
+};
+
+
/**
* Information about a denomination key.
*/
@@ -193,6 +235,7 @@ struct TALER_EXCHANGEDB_SignkeyMetaData
*/
enum TALER_EXCHANGEDB_ReplicatedTable
{
+ /* From exchange-0002.sql: */
TALER_EXCHANGEDB_RT_DENOMINATIONS,
TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS,
TALER_EXCHANGEDB_RT_WIRE_TARGETS,
@@ -235,6 +278,13 @@ enum TALER_EXCHANGEDB_ReplicatedTable
TALER_EXCHANGEDB_RT_WADS_IN,
TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES,
TALER_EXCHANGEDB_RT_PROFIT_DRAINS,
+ /* From exchange-0003.sql: */
+ TALER_EXCHANGEDB_RT_AML_STAFF,
+ TALER_EXCHANGEDB_RT_AML_HISTORY,
+ TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES,
+ TALER_EXCHANGEDB_RT_PURSE_DELETION,
+ TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS,
+ TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS,
};
@@ -660,6 +710,70 @@ struct TALER_EXCHANGEDB_TableData
struct TALER_MasterSignatureP master_sig;
} profit_drains;
+ struct
+ {
+ struct TALER_AmlOfficerPublicKeyP decider_pub;
+ struct TALER_MasterSignatureP master_sig;
+ char *decider_name;
+ bool is_active;
+ bool read_only;
+ struct GNUNET_TIME_Timestamp last_change;
+ } aml_staff;
+
+ struct
+ {
+ struct TALER_PaytoHashP h_payto;
+ struct TALER_Amount new_threshold;
+ enum TALER_AmlDecisionState new_status;
+ struct GNUNET_TIME_Timestamp decision_time;
+ char *justification;
+ char *kyc_requirements; /* NULL allowed! */
+ uint64_t kyc_req_row;
+ struct TALER_AmlOfficerPublicKeyP decider_pub;
+ struct TALER_AmlOfficerSignatureP decider_sig;
+ } aml_history;
+
+ struct
+ {
+ struct TALER_PaytoHashP h_payto;
+ struct GNUNET_ShortHashCode kyc_prox;
+ char *provider;
+ char *birthdate; /* NULL allowed! */
+ struct GNUNET_TIME_Timestamp collection_time;
+ struct GNUNET_TIME_Timestamp expiration_time;
+ void *encrypted_attributes;
+ size_t encrypted_attributes_size;
+ } kyc_attributes;
+
+ struct
+ {
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_PurseContractSignatureP purse_sig;
+ } purse_deletion;
+
+ struct
+ {
+ struct TALER_AgeWithdrawCommitmentHashP h_commitment;
+ struct TALER_Amount amount_with_fee;
+ uint16_t max_age;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_ReserveSignatureP reserve_sig;
+ uint32_t noreveal_index;
+ struct GNUNET_TIME_Absolute timestamp;
+ } withdraw_age_commitments;
+
+ struct
+ {
+ struct TALER_AgeWithdrawCommitmentHashP h_commitment;
+ uint32_t freshcoin_index;
+ uint64_t denominations_serial;
+ void *coin_ev;
+ size_t coin_ev_size;
+ struct TALER_ExchangeWithdrawValues ewv;
+ // h_coin_ev omitted, to be recomputed!
+ struct TALER_BlindedDenominationSignature ev_sig;
+ } withdraw_age_revealed_coins;
+
} details;
};
@@ -1066,7 +1180,7 @@ struct TALER_EXCHANGEDB_AgeWithdrawCommitment
/**
* Maximum age that the coins are restricted to.
*/
- uint32_t max_age;
+ uint16_t max_age;
/**
* The hash of the commitment of all n*kappa coins
@@ -1095,11 +1209,6 @@ struct TALER_EXCHANGEDB_AgeWithdrawCommitment
* The exchange's signature of the response.
*/
struct TALER_ExchangeSignatureP sig;
-
- /**
- * Timestamp of the request being made
- */
- struct GNUNET_TIME_Timestamp timestamp;
};
@@ -3683,7 +3792,6 @@ struct TALER_EXCHANGEDB_Plugin
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
* @param commitment corresponding commitment for the age-withdraw
- * @param now current time (rounded)
* @param[out] found set to true if the reserve was found
* @param[out] balance_ok set to true if the balance was sufficient
* @param[out] ruuid set to the reserve's UUID (reserves table row)
@@ -3693,7 +3801,6 @@ struct TALER_EXCHANGEDB_Plugin
(*do_age_withdraw)(
void *cls,
const struct TALER_EXCHANGEDB_AgeWithdrawCommitment *commitment,
- struct GNUNET_TIME_Timestamp now,
bool *found,
bool *balance_ok,
uint64_t *ruuid);
@@ -4059,6 +4166,25 @@ struct TALER_EXCHANGEDB_Plugin
struct TALER_AgeCommitmentHash *age_hash);
+ /**
+ * Make sure the array of given @a coin is known to the database.
+ *
+ * @param cls database connection plugin state
+ * @param coin array of coins that must be made known
+ * @param[out] result array where to store information about each coin
+ * @param coin_length length of the @a coin and @a result arraysf
+ * @param batch_size desired (maximum) batch size
+ * @return database transaction status, non-negative on success
+ */
+ enum GNUNET_DB_QueryStatus
+ (*batch_ensure_coin_known)(
+ void *cls,
+ const struct TALER_CoinPublicInfo *coin,
+ struct TALER_EXCHANGEDB_CoinInfo *result,
+ unsigned int coin_length,
+ unsigned int batch_size);
+
+
/**
* Retrieve information about the given @a coin from the database.
*
@@ -5688,6 +5814,7 @@ struct TALER_EXCHANGEDB_Plugin
* Insert record set into @a table. Used in exchange-auditor database
* replication.
*
+ memset (&awc, 0, sizeof (awc));
* @param cls closure
* @param tb table data to insert
* @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if
@@ -6428,6 +6555,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls closure
* @param legi_row identifies requirement to look up
* @param[out] requirements space-separated list of requirements
+ * @param[out] aml_status set to the AML status of the account
* @param[out] h_payto account that must be KYC'ed
* @return database transaction status
*/
@@ -6436,6 +6564,7 @@ struct TALER_EXCHANGEDB_Plugin
void *cls,
uint64_t requirement_row,
char **requirements,
+ enum TALER_AmlDecisionState *aml_status,
struct TALER_PaytoHashP *h_payto);
diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c
index d4aaf4494..228525e28 100644
--- a/src/kyclogic/plugin_kyclogic_oauth2.c
+++ b/src/kyclogic/plugin_kyclogic_oauth2.c
@@ -514,6 +514,11 @@ initiate_task (void *cls)
pd->client_id,
redirect_uri_encoded);
GNUNET_free (redirect_uri_encoded);
+ /* FIXME-API: why do we *redirect* the client here,
+ instead of making the HTTP request *ourselves*
+ and forwarding the response? This prevents us
+ from using authentication on initiation,
+ (which is desirable for challenger!) */
ih->cb (ih->cb_cls,
TALER_EC_NONE,
url,
diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c
index afbeda75a..55a05d962 100644
--- a/src/lib/auditor_api_deposit_confirmation.c
+++ b/src/lib/auditor_api_deposit_confirmation.c
@@ -362,10 +362,16 @@ TALER_AUDITOR_deposit_confirmation (
dh->ctx.headers,
&handle_deposit_confirmation_finished,
dh);
- /* Disable 100 continue processing */
- GNUNET_CURL_extend_headers (dh->job,
- curl_slist_append (NULL,
- "Expect:"));
+ {
+ /* Disable 100 continue processing */
+ struct curl_slist *x_headers;
+
+ x_headers = curl_slist_append (NULL,
+ "Expect:");
+ GNUNET_CURL_extend_headers (dh->job,
+ x_headers);
+ curl_slist_free_all (x_headers);
+ }
return dh;
}
diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c
index 68a40a962..2f03730a8 100644
--- a/src/lib/exchange_api_kyc_check.c
+++ b/src/lib/exchange_api_kyc_check.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2021 Taler Systems SA
+ Copyright (C) 2021-2023 Taler Systems SA
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
@@ -97,6 +97,7 @@ handle_kyc_check_finished (void *cls,
case MHD_HTTP_OK:
{
json_t *kyc_details;
+ uint32_t status;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
&ks.details.success.exchange_sig),
@@ -106,6 +107,8 @@ handle_kyc_check_finished (void *cls,
&ks.details.success.timestamp),
GNUNET_JSON_spec_json ("kyc_details",
&kyc_details),
+ GNUNET_JSON_spec_uint32 ("aml_status",
+ &status),
GNUNET_JSON_spec_end ()
};
const struct TALER_EXCHANGE_Keys *key_state;
@@ -121,6 +124,8 @@ handle_kyc_check_finished (void *cls,
break;
}
ks.details.success.kyc_details = kyc_details;
+ ks.details.success.aml_status
+ = (enum TALER_AmlDecisionState) status;
key_state = TALER_EXCHANGE_get_keys (kch->exchange);
if (GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (key_state,
@@ -155,9 +160,12 @@ handle_kyc_check_finished (void *cls,
}
case MHD_HTTP_ACCEPTED:
{
+ uint32_t status;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("kyc_url",
&ks.details.accepted.kyc_url),
+ GNUNET_JSON_spec_uint32 ("aml_status",
+ &status),
GNUNET_JSON_spec_end ()
};
@@ -171,6 +179,8 @@ handle_kyc_check_finished (void *cls,
ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
}
+ ks.details.accepted.aml_status
+ = (enum TALER_AmlDecisionState) status;
kch->cb (kch->cb_cls,
&ks);
GNUNET_JSON_parse_free (spec);
@@ -190,6 +200,33 @@ handle_kyc_check_finished (void *cls,
case MHD_HTTP_NOT_FOUND:
ks.ec = TALER_JSON_get_error_code (j);
break;
+ case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
+ {
+ uint32_t status;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_uint32 ("aml_status",
+ &status),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (j,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ ks.http_status = 0;
+ ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ break;
+ }
+ ks.details.unavailable_for_legal_reasons.aml_status
+ = (enum TALER_AmlDecisionState) status;
+ kch->cb (kch->cb_cls,
+ &ks);
+ GNUNET_JSON_parse_free (spec);
+ TALER_EXCHANGE_kyc_check_cancel (kch);
+ return;
+ }
case MHD_HTTP_INTERNAL_SERVER_ERROR:
ks.ec = TALER_JSON_get_error_code (j);
/* Server had an internal issue; we should retry, but this API
diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c
index 995a0933c..c23ea62d8 100644
--- a/src/lib/exchange_api_wire.c
+++ b/src/lib/exchange_api_wire.c
@@ -111,11 +111,13 @@ free_fees (struct FeeMap *fm)
/**
* Parse wire @a fees and return map.
*
+ * @param master_pub master public key to use to check signatures
* @param fees json AggregateTransferFee to parse
* @return NULL on error
*/
static struct FeeMap *
-parse_fees (json_t *fees)
+parse_fees (const struct TALER_MasterPublicKeyP *master_pub,
+ json_t *fees)
{
struct FeeMap *fm = NULL;
const char *key;
@@ -164,6 +166,19 @@ parse_fees (json_t *fees)
free_fees (fm);
return NULL;
}
+ if (GNUNET_OK !=
+ TALER_exchange_offline_wire_fee_verify (
+ key,
+ wa->start_date,
+ wa->end_date,
+ &wa->fees,
+ master_pub,
+ &wa->master_sig))
+ {
+ GNUNET_break_op (0);
+ free_fees (fm);
+ return NULL;
+ }
if (idx + 1 < len)
wa->next = &fe->fee_list[idx + 1];
else
@@ -227,8 +242,10 @@ handle_wire_finished (void *cls,
json_t *fees;
unsigned int num_accounts;
struct FeeMap *fm;
- const struct TALER_EXCHANGE_Keys *key_state;
+ struct TALER_MasterPublicKeyP master_pub;
struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("master_public_key",
+ &master_pub),
GNUNET_JSON_spec_json ("accounts",
&accounts),
GNUNET_JSON_spec_json ("fees",
@@ -249,6 +266,21 @@ handle_wire_finished (void *cls,
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
break;
}
+ {
+ const struct TALER_EXCHANGE_Keys *key_state;
+
+ key_state = TALER_EXCHANGE_get_keys (wh->exchange);
+ if (0 != GNUNET_memcmp (&key_state->master_pub,
+ &master_pub))
+ {
+ /* bogus reply: master public key in /wire differs from that in /keys */
+ GNUNET_break_op (0);
+ hr.http_status = 0;
+ hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+ break;
+ }
+ }
+
if (0 == (num_accounts = json_array_size (accounts)))
{
/* bogus reply */
@@ -258,7 +290,8 @@ handle_wire_finished (void *cls,
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
break;
}
- if (NULL == (fm = parse_fees (fees)))
+ if (NULL == (fm = parse_fees (&master_pub,
+ fees)))
{
/* bogus reply */
GNUNET_break_op (0);
@@ -268,7 +301,6 @@ handle_wire_finished (void *cls,
break;
}
- key_state = TALER_EXCHANGE_get_keys (wh->exchange);
/* parse accounts */
{
struct TALER_EXCHANGE_WireAccount was[num_accounts];
@@ -290,7 +322,7 @@ handle_wire_finished (void *cls,
i);
if (GNUNET_OK !=
TALER_JSON_exchange_wire_signature_check (account,
- &key_state->master_pub))
+ &master_pub))
{
/* bogus reply */
GNUNET_break_op (0);
diff --git a/src/mhd/mhd_legal.c b/src/mhd/mhd_legal.c
index 25435210e..2c4127117 100644
--- a/src/mhd/mhd_legal.c
+++ b/src/mhd/mhd_legal.c
@@ -232,7 +232,7 @@ TALER_MHD_reply_legal (struct MHD_Connection *conn,
MHD_HEADER_KIND,
MHD_HTTP_HEADER_ACCEPT);
if (NULL == mime)
- mime = "text/html";
+ mime = "text/plain";
lang = MHD_lookup_connection_value (conn,
MHD_HEADER_KIND,
MHD_HTTP_HEADER_ACCEPT_LANGUAGE);
@@ -257,7 +257,7 @@ TALER_MHD_reply_legal (struct MHD_Connection *conn,
char *tmp = langs;
GNUNET_asprintf (&langs,
- "%s %s",
+ "%s,%s",
tmp,
p->language);
GNUNET_free (tmp);
@@ -327,7 +327,7 @@ TALER_MHD_reply_legal (struct MHD_Connection *conn,
{
GNUNET_break (MHD_YES ==
MHD_add_response_header (resp,
- "Acceptable-Languages",
+ "Avail-Languages",
langs));
GNUNET_free (langs);
}
@@ -385,9 +385,9 @@ load_terms (struct TALER_MHD_Legal *legal,
const char *mime;
unsigned int priority;
} mm[] = {
+ { .ext = ".txt", .mime = "text/plain", .priority = 150 },
{ .ext = ".html", .mime = "text/html", .priority = 100 },
{ .ext = ".htm", .mime = "text/html", .priority = 99 },
- { .ext = ".txt", .mime = "text/plain", .priority = 50 },
{ .ext = ".md", .mime = "text/markdown", .priority = 50 },
{ .ext = ".pdf", .mime = "application/pdf", .priority = 25 },
{ .ext = ".jpg", .mime = "image/jpeg" },
diff --git a/src/testing/testing_api_cmd_exec_wirewatch.c b/src/testing/testing_api_cmd_exec_wirewatch.c
index 2517bf74d..32d23a170 100644
--- a/src/testing/testing_api_cmd_exec_wirewatch.c
+++ b/src/testing/testing_api_cmd_exec_wirewatch.c
@@ -34,7 +34,6 @@
*/
struct WirewatchState
{
-
/**
* Process for the wirewatcher.
*/
diff --git a/src/testing/testing_api_cmd_take_aml_decision.c b/src/testing/testing_api_cmd_take_aml_decision.c
index 871cdb712..21ba9af6f 100644
--- a/src/testing/testing_api_cmd_take_aml_decision.c
+++ b/src/testing/testing_api_cmd_take_aml_decision.c
@@ -151,9 +151,14 @@ take_aml_decision_run (void *cls,
TALER_TESTING_interpreter_fail (is);
return;
}
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_h_payto (ref,
- &h_payto));
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_h_payto (ref,
+ &h_payto))
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
ref = TALER_TESTING_interpreter_lookup_command (is,
ds->officer_ref_cmd);
if (NULL == ref)
@@ -162,9 +167,14 @@ take_aml_decision_run (void *cls,
TALER_TESTING_interpreter_fail (is);
return;
}
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_officer_priv (ref,
- &officer_priv));
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_officer_priv (ref,
+ &officer_priv))
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
ds->h_payto = *h_payto;
if (NULL != ds->kyc_requirement)
{
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index 986358ed3..1865a1129 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -353,7 +353,7 @@ maint_child_death (void *cls)
while (TALER_TESTING_cmd_is_batch (cmd))
cmd = TALER_TESTING_cmd_batch_get_current (cmd);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Got SIGCHLD for `%s'.\n",
cmd->label);
is->child_death_task = NULL;
diff --git a/src/util/crypto_confirmation.c b/src/util/crypto_confirmation.c
index c5a674501..e52562e3e 100644
--- a/src/util/crypto_confirmation.c
+++ b/src/util/crypto_confirmation.c
@@ -189,7 +189,7 @@ executive_totp (void *h_key,
if (NULL == ret)
{
GNUNET_asprintf (&ret,
- "%llu",
+ "%08llu",
(unsigned long long) code);
}
else
@@ -197,7 +197,7 @@ executive_totp (void *h_key,
char *tmp;
GNUNET_asprintf (&tmp,
- "%s\n%llu",
+ "%s\n%08llu",
ret,
(unsigned long long) code);
GNUNET_free (ret);