diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-07-28 18:29:23 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-07-28 18:29:23 +0200 |
commit | edcc550215759e91eca93279f8be2d596dba60c4 (patch) | |
tree | 8f32670e08b3473eb277f3fbdb50ed0dec951d94 /src/backenddb/plugin_merchantdb_postgres.c | |
parent | 46cdd4322c7133f4f26047f97c5edc2d794cb06a (diff) | |
download | merchant-edcc550215759e91eca93279f8be2d596dba60c4.tar.gz merchant-edcc550215759e91eca93279f8be2d596dba60c4.tar.bz2 merchant-edcc550215759e91eca93279f8be2d596dba60c4.zip |
use amount tuples
Diffstat (limited to 'src/backenddb/plugin_merchantdb_postgres.c')
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 1916 |
1 files changed, 65 insertions, 1851 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index f129b90b..016cb4e2 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -84,6 +84,15 @@ #include "pg_set_transfer_status_to_confirmed.h" #include "pg_insert_exchange_keys.h" #include "pg_select_exchange_keys.h" +#include "pg_insert_deposit_to_transfer.h" +#include "pg_increase_refund.h" +#include "pg_insert_transfer.h" +#include "pg_insert_transfer_details.h" +#include "pg_store_wire_fee_by_exchange.h" +#include "pg_insert_reserve.h" +#include "pg_activate_reserve.h" +#include "pg_authorize_reward.h" +#include "pg_insert_pickup.h" /** @@ -234,126 +243,6 @@ check_connection (struct PostgresClosure *pg) /** - * Start a transaction. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param name unique name identifying the transaction (for debugging), - * must point to a constant - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -postgres_start (void *cls, - const char *name) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_ExecuteStatement es[] = { - GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"), - GNUNET_PQ_EXECUTE_STATEMENT_END - }; - - check_connection (pg); - postgres_preflight (pg); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Starting merchant DB transaction `%s'\n", - name); - if (GNUNET_OK != - GNUNET_PQ_exec_statements (pg->conn, - es)) - { - TALER_LOG_ERROR ("Failed to start transaction\n"); - GNUNET_break (0); - return GNUNET_SYSERR; - } - pg->transaction_name = name; - return GNUNET_OK; -} - - -/** - * Start a transaction in 'read committed' mode. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param name unique name identifying the transaction (for debugging), - * must point to a constant - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -postgres_start_read_committed (void *cls, - const char *name) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_ExecuteStatement es[] = { - GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL READ COMMITTED"), - GNUNET_PQ_EXECUTE_STATEMENT_END - }; - - check_connection (pg); - postgres_preflight (pg); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Starting merchant DB transaction %s (READ COMMITTED)\n", - name); - if (GNUNET_OK != - GNUNET_PQ_exec_statements (pg->conn, - es)) - { - TALER_LOG_ERROR ("Failed to start transaction\n"); - GNUNET_break (0); - return GNUNET_SYSERR; - } - pg->transaction_name = name; - return GNUNET_OK; -} - - -/** - * Roll back the current transaction of a database connection. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - */ -static void -postgres_rollback (void *cls) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_ExecuteStatement es[] = { - GNUNET_PQ_make_execute ("ROLLBACK"), - GNUNET_PQ_EXECUTE_STATEMENT_END - }; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Rolling back merchant DB transaction `%s'\n", - pg->transaction_name); - GNUNET_break (GNUNET_OK == - GNUNET_PQ_exec_statements (pg->conn, - es)); - pg->transaction_name = NULL; -} - - -/** - * Commit the current transaction of a database connection. - * - * @param cls the `struct PostgresClosure` with the plugin-specific state - * @return transaction status code - */ -static enum GNUNET_DB_QueryStatus -postgres_commit (void *cls) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_end - }; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Committing merchant DB transaction %s\n", - pg->transaction_name); - pg->transaction_name = NULL; - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "end_transaction", - params); -} - - -/** * Closure for lookup_deposits_by_order_cb(). */ struct LookupDepositsByOrderContext @@ -616,37 +505,6 @@ postgres_lookup_transfer_details_by_order ( /** - * Insert wire transfer details for a deposit. - * - * @param cls closure - * @param deposit_serial serial number of the deposit - * @param dd deposit transfer data from the exchange to store - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_insert_deposit_to_transfer ( - void *cls, - uint64_t deposit_serial, - const struct TALER_EXCHANGE_DepositData *dd) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&deposit_serial), - TALER_PQ_query_param_amount (&dd->coin_contribution), - GNUNET_PQ_query_param_timestamp (&dd->execution_time), - GNUNET_PQ_query_param_auto_from_type (&dd->exchange_sig), - GNUNET_PQ_query_param_auto_from_type (&dd->exchange_pub), - GNUNET_PQ_query_param_auto_from_type (&dd->wtid), - GNUNET_PQ_query_param_end - }; - - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_deposit_to_transfer", - params); -} - - -/** * Set 'wired' status for an order to 'true'. * * @param cls closure @@ -670,452 +528,6 @@ postgres_mark_order_wired (void *cls, /** - * Closure for #process_refund_cb(). - */ -struct FindRefundContext -{ - - /** - * Plugin context. - */ - struct PostgresClosure *pg; - - /** - * Updated to reflect total amount refunded so far. - */ - struct TALER_Amount refunded_amount; - - /** - * Set to the largest refund transaction ID encountered. - */ - uint64_t max_rtransaction_id; - - /** - * Set to true on hard errors. - */ - bool err; -}; - - -/** - * Function to be called with the results of a SELECT statement - * that has returned @a num_results results. - * - * @param cls closure, our `struct FindRefundContext` - * @param result the postgres result - * @param num_results the number of results in @a result - */ -static void -process_refund_cb (void *cls, - PGresult *result, - unsigned int num_results) -{ - struct FindRefundContext *ictx = cls; - struct PostgresClosure *pg = ictx->pg; - - for (unsigned int i = 0; i<num_results; i++) - { - /* Sum up existing refunds */ - struct TALER_Amount acc; - uint64_t rtransaction_id; - struct GNUNET_PQ_ResultSpec rs[] = { - TALER_PQ_RESULT_SPEC_AMOUNT ("refund_amount", - &acc), - GNUNET_PQ_result_spec_uint64 ("rtransaction_id", - &rtransaction_id), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, - rs, - i)) - { - GNUNET_break (0); - ictx->err = true; - return; - } - if (0 > - TALER_amount_add (&ictx->refunded_amount, - &ictx->refunded_amount, - &acc)) - { - GNUNET_break (0); - ictx->err = true; - return; - } - ictx->max_rtransaction_id = GNUNET_MAX (ictx->max_rtransaction_id, - rtransaction_id); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Found refund of %s\n", - TALER_amount2s (&acc)); - } -} - - -/** - * Closure for #process_deposits_for_refund_cb(). - */ -struct InsertRefundContext -{ - /** - * Used to provide a connection to the db - */ - struct PostgresClosure *pg; - - /** - * Amount to which increase the refund for this contract - */ - const struct TALER_Amount *refund; - - /** - * Human-readable reason behind this refund - */ - const char *reason; - - /** - * Transaction status code. - */ - enum TALER_MERCHANTDB_RefundStatus rs; -}; - - -/** - * Data extracted per coin. - */ -struct RefundCoinData -{ - - /** - * Public key of a coin. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Amount deposited for this coin. - */ - struct TALER_Amount deposited_with_fee; - - /** - * Amount refunded already for this coin. - */ - struct TALER_Amount refund_amount; - - /** - * Order serial (actually not really per-coin). - */ - uint64_t order_serial; - - /** - * Maximum rtransaction_id for this coin so far. - */ - uint64_t max_rtransaction_id; - -}; - - -/** - * Function to be called with the results of a SELECT statement - * that has returned @a num_results results. - * - * @param cls closure, our `struct InsertRefundContext` - * @param result the postgres result - * @param num_results the number of results in @a result - */ -static void -process_deposits_for_refund_cb (void *cls, - PGresult *result, - unsigned int num_results) -{ - struct InsertRefundContext *ctx = cls; - struct PostgresClosure *pg = ctx->pg; - struct TALER_Amount current_refund; - struct RefundCoinData rcd[GNUNET_NZL (num_results)]; - struct GNUNET_TIME_Timestamp now; - - now = GNUNET_TIME_timestamp_get (); - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (ctx->refund->currency, - ¤t_refund)); - memset (rcd, 0, sizeof (rcd)); - /* Pass 1: Collect amount of existing refunds into current_refund. - * Also store existing refunded amount for each deposit in deposit_refund. */ - for (unsigned int i = 0; i<num_results; i++) - { - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("coin_pub", - &rcd[i].coin_pub), - GNUNET_PQ_result_spec_uint64 ("order_serial", - &rcd[i].order_serial), - TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", - &rcd[i].deposited_with_fee), - GNUNET_PQ_result_spec_end - }; - struct FindRefundContext ictx = { - .pg = pg - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, - rs, - i)) - { - GNUNET_break (0); - ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; - return; - } - - { - enum GNUNET_DB_QueryStatus ires; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&rcd[i].coin_pub), - GNUNET_PQ_query_param_uint64 (&rcd[i].order_serial), - GNUNET_PQ_query_param_end - }; - - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (ctx->refund->currency, - &ictx.refunded_amount)); - ires = GNUNET_PQ_eval_prepared_multi_select (ctx->pg->conn, - "find_refunds_by_coin", - params, - &process_refund_cb, - &ictx); - if ( (ictx.err) || - (GNUNET_DB_STATUS_HARD_ERROR == ires) ) - { - GNUNET_break (0); - ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; - return; - } - if (GNUNET_DB_STATUS_SOFT_ERROR == ires) - { - ctx->rs = TALER_MERCHANTDB_RS_SOFT_ERROR; - return; - } - } - if (0 > - TALER_amount_add (¤t_refund, - ¤t_refund, - &ictx.refunded_amount)) - { - GNUNET_break (0); - ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; - return; - } - rcd[i].refund_amount = ictx.refunded_amount; - rcd[i].max_rtransaction_id = ictx.max_rtransaction_id; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Existing refund for coin %s is %s\n", - TALER_B2S (&rcd[i].coin_pub), - TALER_amount2s (&ictx.refunded_amount)); - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Total existing refund is %s\n", - TALER_amount2s (¤t_refund)); - - /* stop immediately if we are 'done' === amount already - * refunded. */ - if (0 >= TALER_amount_cmp (ctx->refund, - ¤t_refund)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Existing refund of %s at or above requested refund. Finished early.\n", - TALER_amount2s (¤t_refund)); - ctx->rs = TALER_MERCHANTDB_RS_SUCCESS; - return; - } - - /* Phase 2: Try to increase current refund until it matches desired refund */ - for (unsigned int i = 0; i<num_results; i++) - { - const struct TALER_Amount *increment; - struct TALER_Amount left; - struct TALER_Amount remaining_refund; - - /* How much of the coin is left after the existing refunds? */ - if (0 > - TALER_amount_subtract (&left, - &rcd[i].deposited_with_fee, - &rcd[i].refund_amount)) - { - GNUNET_break (0); - ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; - return; - } - - if ( (0 == left.value) && - (0 == left.fraction) ) - { - /* coin was fully refunded, move to next coin */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Coin %s fully refunded, moving to next coin\n", - TALER_B2S (&rcd[i].coin_pub)); - continue; - } - - rcd[i].max_rtransaction_id++; - /* How much of the refund is still to be paid back? */ - if (0 > - TALER_amount_subtract (&remaining_refund, - ctx->refund, - ¤t_refund)) - { - GNUNET_break (0); - ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; - return; - } - - /* By how much will we increase the refund for this coin? */ - if (0 >= TALER_amount_cmp (&remaining_refund, - &left)) - { - /* remaining_refund <= left */ - increment = &remaining_refund; - } - else - { - increment = &left; - } - - if (0 > - TALER_amount_add (¤t_refund, - ¤t_refund, - increment)) - { - GNUNET_break (0); - ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; - return; - } - - /* actually run the refund */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Coin %s deposit amount is %s\n", - TALER_B2S (&rcd[i].coin_pub), - TALER_amount2s (&rcd[i].deposited_with_fee)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Coin %s refund will be incremented by %s\n", - TALER_B2S (&rcd[i].coin_pub), - TALER_amount2s (increment)); - { - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&rcd[i].order_serial), - GNUNET_PQ_query_param_uint64 (&rcd[i].max_rtransaction_id), /* already inc'ed */ - GNUNET_PQ_query_param_timestamp (&now), - GNUNET_PQ_query_param_auto_from_type (&rcd[i].coin_pub), - GNUNET_PQ_query_param_string (ctx->reason), - TALER_PQ_query_param_amount (increment), - GNUNET_PQ_query_param_end - }; - - check_connection (pg); - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_refund", - params); - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; - return; - case GNUNET_DB_STATUS_SOFT_ERROR: - ctx->rs = TALER_MERCHANTDB_RS_SOFT_ERROR; - return; - default: - ctx->rs = (enum TALER_MERCHANTDB_RefundStatus) qs; - break; - } - } - - /* stop immediately if we are done */ - if (0 == TALER_amount_cmp (ctx->refund, - ¤t_refund)) - { - ctx->rs = TALER_MERCHANTDB_RS_SUCCESS; - return; - } - } - - /** - * We end up here if not all of the refund has been covered. - * Although this should be checked as the business should never - * issue a refund bigger than the contract's actual price, we cannot - * rely upon the frontend being correct. - */ - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "The refund of %s is bigger than the order's value\n", - TALER_amount2s (ctx->refund)); - ctx->rs = TALER_MERCHANTDB_RS_TOO_HIGH; -} - - -/** - * Function called when some backoffice staff decides to award or - * increase the refund on an existing contract. This function - * MUST be called from within a transaction scope setup by the - * caller as it executes mulrewardle SQL statements. - * - * @param cls closure - * @param instance_id instance identifier - * @param order_id the order to increase the refund for - * @param refund maximum refund to return to the customer for this contract - * @param reason 0-terminated UTF-8 string giving the reason why the customer - * got a refund (free form, business-specific) - * @return transaction status - * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a refund is ABOVE the amount we - * were originally paid and thus the transaction failed; - * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the request is valid, - * regardless of whether it actually increased the refund beyond - * what was already refunded (idempotency!) - */ -static enum TALER_MERCHANTDB_RefundStatus -postgres_increase_refund (void *cls, - const char *instance_id, - const char *order_id, - const struct TALER_Amount *refund, - const char *reason) -{ - struct PostgresClosure *pg = cls; - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_string (order_id), - GNUNET_PQ_query_param_end - }; - struct InsertRefundContext ctx = { - .pg = pg, - .refund = refund, - .reason = reason - }; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Asked to refund %s on order %s\n", - TALER_amount2s (refund), - order_id); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - "find_deposits_for_refund", - params, - &process_deposits_for_refund_cb, - &ctx); - switch (qs) - { - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - /* never paid, means we clearly cannot refund anything */ - return TALER_MERCHANTDB_RS_NO_SUCH_ORDER; - case GNUNET_DB_STATUS_SOFT_ERROR: - return TALER_MERCHANTDB_RS_SOFT_ERROR; - case GNUNET_DB_STATUS_HARD_ERROR: - return TALER_MERCHANTDB_RS_HARD_ERROR; - default: - /* Got one or more deposits */ - return ctx.rs; - } -} - - -/** * Closure for #lookup_refunds_detailed_cb(). */ struct LookupRefundsDetailedContext @@ -1365,47 +777,6 @@ postgres_lookup_order_by_fulfillment (void *cls, /** - * Insert information about a wire transfer the merchant has received. - * - * @param cls closure - * @param instance_id the instance that received the transfer - * @param exchange_url which exchange made the transfer - * @param wtid identifier of the wire transfer - * @param credit_amount how much did we receive - * @param payto_uri what is the merchant's bank account that received the transfer - * @param confirmed whether the transfer was confirmed by the merchant or - * was merely claimed by the exchange at this point - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_insert_transfer ( - void *cls, - const char *instance_id, - const char *exchange_url, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_Amount *credit_amount, - const char *payto_uri, - bool confirmed) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (exchange_url), - GNUNET_PQ_query_param_auto_from_type (wtid), - TALER_PQ_query_param_amount (credit_amount), - GNUNET_PQ_query_param_string (payto_uri), - GNUNET_PQ_query_param_bool (confirmed), - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_end - }; - - check_connection (pg); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_transfer", - params); -} - - -/** * Delete information about a transfer. Note that transfers * confirmed by the exchange cannot be deleted anymore. * @@ -1503,204 +874,6 @@ postgres_lookup_account (void *cls, /** - * Insert information about a wire transfer the merchant has received. - * - * @param cls closure - * @param instance_id instance to provide transfer details for - * @param exchange_url which exchange made the transfer - * @param payto_uri what is the merchant's bank account that received the transfer - * @param wtid identifier of the wire transfer - * @param td transfer details to store - * @return transaction status, - * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the @a wtid and @a exchange_uri are not known for this @a instance_id - * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT on success - */ -static enum GNUNET_DB_QueryStatus -postgres_insert_transfer_details ( - void *cls, - const char *instance_id, - const char *exchange_url, - const char *payto_uri, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_EXCHANGE_TransferData *td) -{ - struct PostgresClosure *pg = cls; - enum GNUNET_DB_QueryStatus qs; - uint64_t credit_serial; - unsigned int retries; - - retries = 0; - check_connection (pg); -RETRY: - if (MAX_RETRIES < ++retries) - return GNUNET_DB_STATUS_SOFT_ERROR; - if (GNUNET_OK != - postgres_start_read_committed (pg, - "insert transfer details")) - { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - /* lookup credit serial */ - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (exchange_url), - GNUNET_PQ_query_param_string (payto_uri), - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (wtid), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("credit_serial", - &credit_serial), - GNUNET_PQ_result_spec_end - }; - - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "lookup_credit_serial", - params, - rs); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - postgres_rollback (pg); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "'lookup_credit_serial' for account %s and amount %s failed with status %d\n", - payto_uri, - TALER_amount2s (&td->total_amount), - qs); - return qs; - } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - postgres_rollback (pg); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "'lookup_credit_serial' for account %s failed with transfer unknown\n", - payto_uri); - return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; - } - } - - /* update merchant_transfer_signatures table */ - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&credit_serial), - TALER_PQ_query_param_amount (&td->total_amount), - TALER_PQ_query_param_amount (&td->wire_fee), - GNUNET_PQ_query_param_timestamp (&td->execution_time), - GNUNET_PQ_query_param_auto_from_type (&td->exchange_sig), - GNUNET_PQ_query_param_auto_from_type (&td->exchange_pub), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_transfer_signature", - params); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - postgres_rollback (pg); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "'insert_transfer_signature' failed with status %d\n", - qs); - return qs; - } - if (0 == qs) - { - postgres_rollback (pg); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "'insert_transfer_signature' failed with status %d\n", - qs); - return GNUNET_DB_STATUS_HARD_ERROR; - } - } - - /* Update transfer-coin association table */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Updating transfer-coin association table\n"); - for (unsigned int i = 0; i<td->details_length; i++) - { - const struct TALER_TrackTransferDetails *d = &td->details[i]; - uint64_t i64 = (uint64_t) i; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&credit_serial), - GNUNET_PQ_query_param_uint64 (&i64), - TALER_PQ_query_param_amount (&d->coin_value), - TALER_PQ_query_param_amount (&d->coin_fee), /* deposit fee */ - GNUNET_PQ_query_param_auto_from_type (&d->coin_pub), - GNUNET_PQ_query_param_auto_from_type (&d->h_contract_terms), - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_transfer_to_coin_mapping", - params); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - postgres_rollback (pg); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "'insert_transfer_to_coin_mapping' failed with status %d\n", - qs); - return qs; - } - if (0 == qs) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "'insert_transfer_to_coin_mapping' failed at %u: deposit unknown\n", - i); - } - } - /* Update merchant_contract_terms 'wired' status: for all coins - that were wired, set the respective order's "wired" status to - true, *if* all other deposited coins associated with that order - have also been wired (this time or earlier) */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Updating contract terms 'wired' status\n"); - for (unsigned int i = 0; i<td->details_length; i++) - { - const struct TALER_TrackTransferDetails *d = &td->details[i]; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (&d->coin_pub), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_wired_by_coin_pub", - params); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - postgres_rollback (pg); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "'update_wired_by_coin_pub' failed with status %d\n", - qs); - return qs; - } - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Committing transaction...\n"); - qs = postgres_commit (pg); - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - return qs; -} - - -/** * Obtain information about wire fees charged by an exchange, * including signature (so we have proof). * @@ -2249,187 +1422,6 @@ postgres_lookup_transfer_details ( /** - * Store information about wire fees charged by an exchange, - * including signature (so we have proof). - * - * @param cls closure - * @param master_pub public key of the exchange - * @param h_wire_method hash of wire method - * @param fees the fee charged - * @param start_date start of fee being used - * @param end_date end of fee being used - * @param master_sig signature of exchange over fee structure - * @return transaction status code - */ -static enum GNUNET_DB_QueryStatus -postgres_store_wire_fee_by_exchange ( - void *cls, - const struct TALER_MasterPublicKeyP *master_pub, - const struct GNUNET_HashCode *h_wire_method, - const struct TALER_WireFeeSet *fees, - struct GNUNET_TIME_Timestamp start_date, - struct GNUNET_TIME_Timestamp end_date, - const struct TALER_MasterSignatureP *master_sig) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (master_pub), - GNUNET_PQ_query_param_auto_from_type (h_wire_method), - TALER_PQ_query_param_amount (&fees->wire), - TALER_PQ_query_param_amount (&fees->closing), - GNUNET_PQ_query_param_timestamp (&start_date), - GNUNET_PQ_query_param_timestamp (&end_date), - GNUNET_PQ_query_param_auto_from_type (master_sig), - GNUNET_PQ_query_param_end - }; - - /* no preflight check here, run in its own transaction by the caller */ - check_connection (pg); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Storing wire fee for %s starting at %s of %s\n", - TALER_B2S (master_pub), - GNUNET_TIME_timestamp2s (start_date), - TALER_amount2s (&fees->wire)); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_wire_fee", - params); -} - - -/** - * Add @a credit to a reserve to be used for rewardping. Note that - * this function does not actually perform any wire transfers to - * credit the reserve, it merely tells the merchant backend that - * a reserve now exists. This has to happen before rewards can be - * authorized. - * - * @param cls closure, typically a connection to the db - * @param instance_id which instance is the reserve tied to - * @param reserve_priv which reserve is topped up or created - * @param reserve_pub which reserve is topped up or created - * @param master_pub master public key of the exchange - * @param exchange_url what URL is the exchange reachable at where the reserve is located - * @param initial_balance how much money will be added to the reserve - * @param expiration when does the reserve expire? - * @return transaction status, usually - * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success - */ -static enum TALER_ErrorCode -postgres_insert_reserve (void *cls, - const char *instance_id, - const struct TALER_ReservePrivateKeyP *reserve_priv, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_MasterPublicKeyP *master_pub, - const char *exchange_url, - const struct TALER_Amount *initial_balance, - struct GNUNET_TIME_Timestamp expiration) -{ - struct PostgresClosure *pg = cls; - unsigned int retries; - enum GNUNET_DB_QueryStatus qs; - - retries = 0; - check_connection (pg); -RETRY: - if (MAX_RETRIES < ++retries) - return TALER_EC_GENERIC_DB_SOFT_FAILURE; - if (GNUNET_OK != - postgres_start (pg, - "insert reserve")) - { - GNUNET_break (0); - return TALER_EC_GENERIC_DB_START_FAILED; - } - - /* Setup reserve */ - { - struct GNUNET_TIME_Timestamp now; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (reserve_pub), - GNUNET_PQ_query_param_timestamp (&now), - GNUNET_PQ_query_param_timestamp (&expiration), - TALER_PQ_query_param_amount (initial_balance), - GNUNET_PQ_query_param_end - }; - - now = GNUNET_TIME_timestamp_get (); - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_reserve", - params); - if (0 > qs) - { - postgres_rollback (pg); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - return qs; - } - } - /* Store private key */ - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (reserve_pub), - GNUNET_PQ_query_param_auto_from_type (reserve_priv), - GNUNET_PQ_query_param_string (exchange_url), - GNUNET_PQ_query_param_auto_from_type (master_pub), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_reserve_key", - params); - if (0 > qs) - { - postgres_rollback (pg); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - return qs; - } - } - qs = postgres_commit (pg); - if (0 <= qs) - return TALER_EC_NONE; /* success */ - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - return qs; -} - - -/** - * Confirms @a credit as the amount the exchange claims to have received and - * thus really 'activates' the reserve. This has to happen before rewards can - * be authorized. - * - * @param cls closure, typically a connection to the db - * @param instance_id which instance is the reserve tied to - * @param reserve_pub which reserve is topped up or created - * @param initial_exchange_balance how much money was be added to the reserve - * according to the exchange - * @return transaction status, usually - * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success - */ -static enum GNUNET_DB_QueryStatus -postgres_activate_reserve (void *cls, - const char *instance_id, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_Amount *initial_exchange_balance) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (reserve_pub), - TALER_PQ_query_param_amount (initial_exchange_balance), - GNUNET_PQ_query_param_end - }; - - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "activate_reserve", - params); -} - - -/** * Closure for #lookup_pending_reserves_cb. */ struct LookupPendingReservesContext @@ -2795,366 +1787,6 @@ postgres_purge_reserve (void *cls, /** - * Closure for #lookup_reserve_for_reward_cb(). - */ -struct LookupReserveForRewardContext -{ - /** - * Postgres context. - */ - struct PostgresClosure *pg; - - /** - * Public key of the reserve we found. - */ - struct TALER_ReservePublicKeyP reserve_pub; - - /** - * How much money must be left in the reserve. - */ - struct TALER_Amount required_amount; - - /** - * Set to the expiration time of the reserve we found. - * #GNUNET_TIME_UNIT_FOREVER_ABS if we found none. - */ - struct GNUNET_TIME_Timestamp expiration; - - /** - * Error status. - */ - enum TALER_ErrorCode ec; - - /** - * Did we find a good reserve? - */ - bool ok; -}; - - -/** - * How long must a reserve be at least still valid before we use - * it for a reward? - */ -#define MIN_EXPIRATION GNUNET_TIME_UNIT_HOURS - - -/** - * Function to be called with the results of a SELECT statement - * that has returned @a num_results results about accounts. - * - * @param[in,out] cls of type `struct LookupReserveForRewardContext *` - * @param result the postgres result - * @param num_results the number of results in @a result - */ -static void -lookup_reserve_for_reward_cb (void *cls, - PGresult *result, - unsigned int num_results) -{ - struct LookupReserveForRewardContext *lac = cls; - struct PostgresClosure *pg = lac->pg; - - for (unsigned int i = 0; i < num_results; i++) - { - struct TALER_ReservePublicKeyP reserve_pub; - struct TALER_Amount committed_amount; - struct TALER_Amount remaining; - struct TALER_Amount initial_balance; - struct GNUNET_TIME_Timestamp expiration; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", - &reserve_pub), - TALER_PQ_RESULT_SPEC_AMOUNT ("exchange_initial_balance", - &initial_balance), - TALER_PQ_RESULT_SPEC_AMOUNT ("rewards_committed", - &committed_amount), - GNUNET_PQ_result_spec_timestamp ("expiration", - &expiration), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, - rs, - i)) - { - GNUNET_break (0); - lac->ec = TALER_EC_GENERIC_DB_FETCH_FAILED; - return; - } - if (0 > - TALER_amount_subtract (&remaining, - &initial_balance, - &committed_amount)) - { - GNUNET_break (0); - continue; - } - if (0 > - TALER_amount_cmp (&remaining, - &lac->required_amount)) - { - /* insufficient balance */ - if (lac->ok) - continue; /* got another reserve */ - lac->ec = - TALER_EC_MERCHANT_PRIVATE_POST_REWARD_AUTHORIZE_INSUFFICIENT_FUNDS; - continue; - } - if ( (! GNUNET_TIME_absolute_is_never (lac->expiration.abs_time)) && - GNUNET_TIME_timestamp_cmp (expiration, - >, - lac->expiration) && - GNUNET_TIME_relative_cmp ( - GNUNET_TIME_absolute_get_remaining (lac->expiration.abs_time), - >, - MIN_EXPIRATION) ) - { - /* reserve expired */ - if (lac->ok) - continue; /* got another reserve */ - lac->ec = TALER_EC_MERCHANT_PRIVATE_POST_REWARD_AUTHORIZE_RESERVE_EXPIRED; - continue; - } - lac->ok = true; - lac->ec = TALER_EC_NONE; - lac->expiration = expiration; - lac->reserve_pub = reserve_pub; - } -} - - -/** - * Authorize a reward over @a amount from reserve @a reserve_pub. Remember - * the authorization under @a reward_id for later, together with the - * @a justification. - * - * @param cls closure, typically a connection to the db - * @param instance_id which instance should generate the reward - * @param reserve_pub which reserve is debited, NULL to pick one in the DB - * @param amount how high is the reward (with fees) - * @param justification why was the reward approved - * @param next_url where to send the URL post reward pickup - * @param[out] reward_id set to the unique ID for the reward - * @param[out] expiration set to when the reward expires - * @return transaction status, - * #TALER_EC_MERCHANT_PRIVATE_POST_REWARD_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but has expired - * #TALER_EC_MERCHANT_PRIVATE_POST_REWARD_AUTHORIZE_RESERVE_NOT_FOUND if the reserve is not known - * #TALER_EC_MERCHANT_PRIVATE_POST_REWARD_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has insufficient funds left - * #TALER_EC_GENERIC_DB_START_FAILED on hard DB errors - * #TALER_EC_GENERIC_DB_FETCH_FAILED on hard DB errors - * #TALER_EC_GENERIC_DB_STORE_FAILED on hard DB errors - * #TALER_EC_GENERIC_DB_INVARIANT_FAILURE on hard DB errors - * #TALER_EC_GENERIC_DB_SOFT_FAILURE soft DB errors (client should retry) - * #TALER_EC_NONE upon success - */ -static enum TALER_ErrorCode -postgres_authorize_reward (void *cls, - const char *instance_id, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_Amount *amount, - const char *justification, - const char *next_url, - struct TALER_RewardIdentifierP *reward_id, - struct GNUNET_TIME_Timestamp *expiration) -{ - struct PostgresClosure *pg = cls; - unsigned int retries = 0; - enum GNUNET_DB_QueryStatus qs; - struct TALER_Amount rewards_committed; - struct TALER_Amount exchange_initial_balance; - const struct TALER_ReservePublicKeyP *reserve_pubp; - struct LookupReserveForRewardContext lac = { - .pg = pg, - .required_amount = *amount, - .expiration = GNUNET_TIME_UNIT_FOREVER_TS - }; - - check_connection (pg); -RETRY: - reserve_pubp = reserve_pub; - if (MAX_RETRIES < ++retries) - { - GNUNET_break (0); - return - TALER_EC_GENERIC_DB_SOFT_FAILURE; - } - if (GNUNET_OK != - postgres_start (pg, - "authorize reward")) - { - GNUNET_break (0); - return TALER_EC_GENERIC_DB_START_FAILED; - } - if (NULL == reserve_pubp) - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - "lookup_reserve_for_reward", - params, - &lookup_reserve_for_reward_cb, - &lac); - switch (qs) - { - case GNUNET_DB_STATUS_SOFT_ERROR: - postgres_rollback (pg); - goto RETRY; - case GNUNET_DB_STATUS_HARD_ERROR: - GNUNET_break (0); - postgres_rollback (pg); - return TALER_EC_GENERIC_DB_FETCH_FAILED; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - postgres_rollback (pg); - return TALER_EC_MERCHANT_PRIVATE_POST_REWARD_AUTHORIZE_RESERVE_NOT_FOUND; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - default: - break; - } - if (TALER_EC_NONE != lac.ec) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Enabling reward reserved failed with status %d\n", - lac.ec); - postgres_rollback (pg); - return lac.ec; - } - GNUNET_assert (lac.ok); - reserve_pubp = &lac.reserve_pub; - } - - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (reserve_pubp), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_timestamp ("expiration", - expiration), - TALER_PQ_RESULT_SPEC_AMOUNT ("rewards_committed", - &rewards_committed), - TALER_PQ_RESULT_SPEC_AMOUNT ("exchange_initial_balance", - &exchange_initial_balance), - GNUNET_PQ_result_spec_end - }; - - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "lookup_reserve_status", - params, - rs); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - { - postgres_rollback (pg); - goto RETRY; - } - if (qs < 0) - { - GNUNET_break (0); - postgres_rollback (pg); - return TALER_EC_GENERIC_DB_FETCH_FAILED; - } - if (0 == qs) - { - postgres_rollback (pg); - return TALER_EC_MERCHANT_PRIVATE_POST_REWARD_AUTHORIZE_RESERVE_NOT_FOUND; - } - } - { - struct TALER_Amount remaining; - - if (0 > - TALER_amount_subtract (&remaining, - &exchange_initial_balance, - &rewards_committed)) - { - GNUNET_break (0); - postgres_rollback (pg); - return TALER_EC_GENERIC_DB_INVARIANT_FAILURE; - } - if (0 > - TALER_amount_cmp (&remaining, - amount)) - { - postgres_rollback (pg); - return TALER_EC_MERCHANT_PRIVATE_POST_REWARD_AUTHORIZE_INSUFFICIENT_FUNDS; - } - } - GNUNET_assert (0 <= - TALER_amount_add (&rewards_committed, - &rewards_committed, - amount)); - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (reserve_pubp), - TALER_PQ_query_param_amount (&rewards_committed), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_reserve_rewards_committed", - params); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - { - postgres_rollback (pg); - goto RETRY; - } - if (qs < 0) - { - GNUNET_break (0); - postgres_rollback (pg); - return TALER_EC_GENERIC_DB_STORE_FAILED; - } - } - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, - reward_id, - sizeof (*reward_id)); - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (reserve_pubp), - GNUNET_PQ_query_param_auto_from_type (reward_id), - GNUNET_PQ_query_param_string (justification), - GNUNET_PQ_query_param_string (next_url), - GNUNET_PQ_query_param_timestamp (expiration), - TALER_PQ_query_param_amount (amount), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_reward", - params); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - { - postgres_rollback (pg); - goto RETRY; - } - if (qs < 0) - { - GNUNET_break (0); - postgres_rollback (pg); - return TALER_EC_GENERIC_DB_STORE_FAILED; - } - } - qs = postgres_commit (pg); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto RETRY; - if (qs < 0) - { - GNUNET_break (0); - postgres_rollback (pg); - return TALER_EC_GENERIC_DB_COMMIT_FAILED; - } - return TALER_EC_NONE; -} - - -/** * Closure for #lookup_signatures_cb(). */ struct LookupSignaturesContext @@ -3653,117 +2285,6 @@ postgres_lookup_reward_details (void *cls, /** - * Insert details about a reward pickup operation. The @a total_picked_up - * UPDATES the total amount under the @a reward_id, while the @a - * total_requested is the amount to be associated with this @a pickup_id. - * While there is usually only one pickup event that picks up the entire - * amount, our schema allows for wallets to pick up the amount incrementally - * over mulrewardle pick up operations. - * - * @param cls closure, typically a connection to the db - * @param instance_id which instance gave the reward - * @param reward_id the unique ID for the reward - * @param total_picked_up how much was picked up overall at this - * point (includes @a total_requested) - * @param pickup_id unique ID for the operation - * @param total_requested how much is being picked up in this operation - * @return transaction status, usually - * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success - * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a credit_uuid already known - */ -static enum GNUNET_DB_QueryStatus -postgres_insert_pickup (void *cls, - const char *instance_id, - const struct TALER_RewardIdentifierP *reward_id, - const struct TALER_Amount *total_picked_up, - const struct TALER_PickupIdentifierP *pickup_id, - const struct TALER_Amount *total_requested) -{ - struct PostgresClosure *pg = cls; - enum GNUNET_DB_QueryStatus qs; - - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (reward_id), - GNUNET_PQ_query_param_auto_from_type (pickup_id), - TALER_PQ_query_param_amount (total_requested), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_pickup", - params); - if (0 > qs) - return qs; - } - - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (reward_id), - TALER_PQ_query_param_amount (total_picked_up), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_picked_up_reward", - params); - if (0 > qs) - return qs; - } - { - uint64_t reserve_serial; - struct TALER_Amount reserve_picked_up; - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (reward_id), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("reserve_serial", - &reserve_serial), - TALER_PQ_RESULT_SPEC_AMOUNT ("rewards_picked_up", - &reserve_picked_up), - GNUNET_PQ_result_spec_end - - }; - - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "lookup_picked_up_reserve", - params, - rs); - if (0 > qs) - return qs; - } - if (0 >= - TALER_amount_add (&reserve_picked_up, - &reserve_picked_up, - total_requested)) - { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&reserve_serial), - TALER_PQ_query_param_amount (&reserve_picked_up), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "update_picked_up_reserve", - params); - if (0 > qs) - return qs; - } - } - return qs; -} - - -/** * Insert blind signature obtained from the exchange during a * reward pickup operation. * @@ -4812,10 +3333,8 @@ postgres_connect (void *cls) " deposit_serial" ",exchange_url" ",h_wire" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",deposit_fee_val" - ",deposit_fee_frac" + ",amount_with_fee" + ",deposit_fee" ",coin_pub" " FROM merchant_deposits" " JOIN merchant_accounts USING (account_serial)" @@ -4826,10 +3345,8 @@ postgres_connect (void *cls) " md.deposit_serial" ",md.exchange_url" ",mt.wtid" - ",exchange_deposit_value_val" - ",exchange_deposit_value_frac" - ",exchange_deposit_fee_val" - ",exchange_deposit_fee_frac" + ",exchange_deposit_value" + ",exchange_deposit_fee" ",deposit_timestamp" ",mt.confirmed AS transfer_confirmed" " FROM merchant_transfer_to_coin" @@ -4839,64 +3356,11 @@ postgres_connect (void *cls) " (SELECT deposit_serial" " FROM merchant_deposits" " WHERE order_serial=$1)"), - /* for postgres_insert_deposit_to_transfer() */ - GNUNET_PQ_make_prepare ("insert_deposit_to_transfer", - "INSERT INTO merchant_deposit_to_transfer" - "(deposit_serial" - ",coin_contribution_value_val" - ",coin_contribution_value_frac" - ",credit_serial" - ",execution_time" - ",signkey_serial" - ",exchange_sig" - ") SELECT $1, $2, $3, credit_serial, $4, signkey_serial, $5" - " FROM merchant_transfers" - " CROSS JOIN merchant_exchange_signing_keys" - " WHERE exchange_pub=$6" - " AND wtid=$7"), /* for postgres_mark_order_wired() */ GNUNET_PQ_make_prepare ("mark_order_wired", "UPDATE merchant_contract_terms SET" " wired=true" " WHERE order_serial=$1"), - /* for process_refund_cb() used in postgres_increase_refund() */ - GNUNET_PQ_make_prepare ("find_refunds_by_coin", - "SELECT" - " refund_amount_val" - ",refund_amount_frac" - ",rtransaction_id" - " FROM merchant_refunds" - " WHERE coin_pub=$1" - " AND order_serial=$2"), - /* for process_deposits_for_refund_cb() used in postgres_increase_refund() */ - GNUNET_PQ_make_prepare ("insert_refund", - "INSERT INTO merchant_refunds" - "(order_serial" - ",rtransaction_id" - ",refund_timestamp" - ",coin_pub" - ",reason" - ",refund_amount_val" - ",refund_amount_frac" - ") VALUES" - "($1, $2, $3, $4, $5, $6, $7)"), - /* for postgres_increase_refund() */ - GNUNET_PQ_make_prepare ("find_deposits_for_refund", - "SELECT" - " coin_pub" - ",order_serial" - ",amount_with_fee_val" - ",amount_with_fee_frac" - " FROM merchant_deposits" - " WHERE order_serial=" - " (SELECT order_serial" - " FROM merchant_contract_terms" - " WHERE order_id=$2" - " AND paid=TRUE" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1))"), /* for postgres_lookup_refunds_detailed() */ GNUNET_PQ_make_prepare ("lookup_refunds_detailed", "SELECT" @@ -4906,8 +3370,7 @@ postgres_connect (void *cls) ",merchant_deposits.exchange_url" ",rtransaction_id" ",reason" - ",refund_amount_val" - ",refund_amount_frac" + ",refund_amount" ",merchant_refund_proofs.exchange_sig IS NULL AS pending" " FROM merchant_refunds" " JOIN merchant_deposits USING (order_serial, coin_pub)" @@ -4952,24 +3415,6 @@ postgres_connect (void *cls) " (SELECT merchant_serial" " FROM merchant_instances" " WHERE merchant_id=$1)"), - /* for postgres_insert_transfer() */ - GNUNET_PQ_make_prepare ("insert_transfer", - "INSERT INTO merchant_transfers" - "(exchange_url" - ",wtid" - ",credit_amount_val" - ",credit_amount_frac" - ",account_serial" - ",confirmed)" - "SELECT" - " $1, $2, $3, $4, account_serial, $6" - " FROM merchant_accounts" - " WHERE payto_uri=$5" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$7)" - " ON CONFLICT DO NOTHING;"), /* for postgres_delete_transfer() */ GNUNET_PQ_make_prepare ("delete_transfer", "DELETE FROM merchant_transfers" @@ -5006,84 +3451,11 @@ postgres_connect (void *cls) " (SELECT merchant_serial" " FROM merchant_instances" " WHERE merchant_id=$1)"), - /* for postgres_insert_transfer_details() */ - GNUNET_PQ_make_prepare ("lookup_credit_serial", - "SELECT" - " credit_serial" - " FROM merchant_transfers" - " WHERE exchange_url=$1" - " AND wtid=$4" - " AND account_serial=" - " (SELECT account_serial" - " FROM merchant_accounts" - " WHERE payto_uri=$2" - " AND exchange_url=$1" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$3))"), - /* for postgres_insert_transfer_details() */ - GNUNET_PQ_make_prepare ("insert_transfer_signature", - "INSERT INTO merchant_transfer_signatures" - "(credit_serial" - ",signkey_serial" - ",credit_amount_val" - ",credit_amount_frac" - ",wire_fee_val" - ",wire_fee_frac" - ",execution_time" - ",exchange_sig) " - "SELECT $1, signkey_serial, $2, $3, $4, $5, $6, $7" - " FROM merchant_exchange_signing_keys" - " WHERE exchange_pub=$8" - " ORDER BY start_date DESC" - " LIMIT 1"), - /* for postgres_insert_transfer_details() */ - GNUNET_PQ_make_prepare ("insert_transfer_to_coin_mapping", - "INSERT INTO merchant_transfer_to_coin" - "(deposit_serial" - ",credit_serial" - ",offset_in_exchange_list" - ",exchange_deposit_value_val" - ",exchange_deposit_value_frac" - ",exchange_deposit_fee_val" - ",exchange_deposit_fee_frac) " - "SELECT deposit_serial, $1, $2, $3, $4, $5, $6" - " FROM merchant_deposits" - " JOIN merchant_contract_terms USING (order_serial)" - " WHERE coin_pub=$7" - " AND h_contract_terms=$8" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$9)"), - /* for postgres_insert_transfer_details() */ - GNUNET_PQ_make_prepare ("update_wired_by_coin_pub", - "WITH os AS" /* select orders affected by the coin */ - "(SELECT order_serial" - " FROM merchant_deposits" - " WHERE coin_pub=$1)" - "UPDATE merchant_contract_terms " - " SET wired=TRUE " - " WHERE order_serial IN " - " (SELECT order_serial FROM merchant_deposits" /* only orders for which NO un-wired coin exists*/ - " WHERE NOT EXISTS " - " (SELECT order_serial FROM merchant_deposits" /* orders for which ANY un-wired coin exists */ - " JOIN os USING (order_serial)" /* filter early */ - " WHERE deposit_serial NOT IN" - " (SELECT deposit_serial " /* all coins associated with order that WERE wired */ - " FROM merchant_deposits " - " JOIN os USING (order_serial)" /* filter early */ - " JOIN merchant_deposit_to_transfer USING (deposit_serial)" - " JOIN merchant_transfers USING (credit_serial)" - " WHERE confirmed=TRUE)))"), /* for postgres_lookup_wire_fee() */ GNUNET_PQ_make_prepare ("lookup_wire_fee", "SELECT" - " wire_fee_val" - ",wire_fee_frac" - ",closing_fee_val" - ",closing_fee_frac" + " wire_fee" + ",closing_fee" ",start_date" ",end_date" ",master_sig" @@ -5096,14 +3468,10 @@ postgres_connect (void *cls) GNUNET_PQ_make_prepare ("lookup_deposits_by_contract_and_coin", "SELECT" " exchange_url" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",deposit_fee_val" - ",deposit_fee_frac" - ",refund_fee_val" - ",refund_fee_frac" - ",wire_fee_val" - ",wire_fee_frac" + ",amount_with_fee" + ",deposit_fee" + ",refund_fee" + ",wire_fee" ",h_wire" ",deposit_timestamp" ",refund_deadline" @@ -5122,12 +3490,9 @@ postgres_connect (void *cls) /* for postgres_lookup_transfer() */ GNUNET_PQ_make_prepare ("lookup_transfer", "SELECT" - " mt.credit_amount_val AS credit_amount_val" - ",mt.credit_amount_frac AS credit_amount_frac" - ",mts.credit_amount_val AS exchange_amount_val" - ",mts.credit_amount_frac AS exchange_amount_frac" - ",wire_fee_val" - ",wire_fee_frac" + " mt.credit_amount AS credit_amount" + ",mts.credit_amount AS exchange_amount" + ",wire_fee" ",execution_time" ",verified" " FROM merchant_transfers mt" @@ -5141,10 +3506,8 @@ postgres_connect (void *cls) GNUNET_PQ_make_prepare ("lookup_transfer_summary", "SELECT" " order_id" - ",exchange_deposit_value_val" - ",exchange_deposit_value_frac" - ",exchange_deposit_fee_val" - ",exchange_deposit_fee_frac" + ",exchange_deposit_value" + ",exchange_deposit_fee" " FROM merchant_transfers" " JOIN merchant_transfer_to_coin USING (credit_serial)" " JOIN merchant_deposits USING (deposit_serial)" @@ -5157,54 +3520,14 @@ postgres_connect (void *cls) " merchant_contract_terms.h_contract_terms" ",merchant_transfer_to_coin.offset_in_exchange_list" ",merchant_deposits.coin_pub" - ",exchange_deposit_value_val" - ",exchange_deposit_value_frac" - ",exchange_deposit_fee_val" - ",exchange_deposit_fee_frac" + ",exchange_deposit_value" + ",exchange_deposit_fee" " FROM merchant_transfer_to_coin" " JOIN merchant_deposits USING (deposit_serial)" " JOIN merchant_contract_terms USING (order_serial)" " JOIN merchant_transfers USING (credit_serial)" " WHERE merchant_transfers.wtid=$2" " AND merchant_transfers.exchange_url=$1"), - /* For postgres_store_wire_fee_by_exchange() */ - GNUNET_PQ_make_prepare ("insert_wire_fee", - "INSERT INTO merchant_exchange_wire_fees" - "(master_pub" - ",h_wire_method" - ",wire_fee_val" - ",wire_fee_frac" - ",closing_fee_val" - ",closing_fee_frac" - ",start_date" - ",end_date" - ",master_sig)" - " VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9)" - " ON CONFLICT DO NOTHING"), - /* For postgres_insert_reserve() */ - GNUNET_PQ_make_prepare ("insert_reserve", - "INSERT INTO merchant_reward_reserves" - "(reserve_pub" - ",merchant_serial" - ",creation_time" - ",expiration" - ",merchant_initial_balance_val" - ",merchant_initial_balance_frac" - ")" - "SELECT $2, merchant_serial, $3, $4, $5, $6" - " FROM merchant_instances" - " WHERE merchant_id=$1"), - /* For postgres_activate_reserve() */ - GNUNET_PQ_make_prepare ("activate_reserve", - "UPDATE merchant_reward_reserves SET" - " exchange_initial_balance_val=$3" - ",exchange_initial_balance_frac=$4" - " WHERE reserve_pub=$2" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1)"), /* For postgres_insert_reserve() */ GNUNET_PQ_make_prepare ("insert_reserve_key", "INSERT INTO merchant_reward_reserve_keys" @@ -5226,26 +3549,20 @@ postgres_connect (void *cls) " reserve_pub" ",merchant_id" ",exchange_url" - ",merchant_initial_balance_val" - ",merchant_initial_balance_frac" + ",merchant_initial_balance" " FROM merchant_reward_reserves" " JOIN merchant_instances USING (merchant_serial)" " JOIN merchant_reward_reserve_keys USING (reserve_serial)" - " WHERE exchange_initial_balance_val=0" - " AND exchange_initial_balance_frac=0"), + " WHERE exchange_initial_balance=CAST((0,0) AS taler_amount)"), /* For postgres_lookup_reserve() */ GNUNET_PQ_make_prepare ("lookup_reserve", "SELECT" " creation_time" ",expiration" - ",merchant_initial_balance_val" - ",merchant_initial_balance_frac" - ",exchange_initial_balance_val" - ",exchange_initial_balance_frac" - ",rewards_committed_val" - ",rewards_committed_frac" - ",rewards_picked_up_val" - ",rewards_picked_up_frac" + ",merchant_initial_balance" + ",exchange_initial_balance" + ",rewards_committed" + ",rewards_picked_up" ",reserve_priv IS NOT NULL AS active" ",exchange_url" ",master_pub" @@ -5261,8 +3578,7 @@ postgres_connect (void *cls) "SELECT" " justification" ",reward_id" - ",amount_val" - ",amount_frac" + ",amount" " FROM merchant_rewards" " WHERE reserve_serial =" " (SELECT reserve_serial" @@ -5293,65 +3609,6 @@ postgres_connect (void *cls) " (SELECT merchant_serial" " FROM merchant_instances" " WHERE merchant_id=$1)"), - /* For postgres_authorize_reward() */ - GNUNET_PQ_make_prepare ("lookup_reserve_for_reward", - "SELECT" - " reserve_pub" - ",expiration" - ",exchange_initial_balance_val" - ",exchange_initial_balance_frac" - ",rewards_committed_val" - ",rewards_committed_frac" - " FROM merchant_reward_reserves" - " WHERE" - " merchant_serial =" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1)"), - - /* For postgres_authorize_reward() */ - GNUNET_PQ_make_prepare ("lookup_reserve_status", - "SELECT" - " expiration" - ",exchange_initial_balance_val" - ",exchange_initial_balance_frac" - ",rewards_committed_val" - ",rewards_committed_frac" - " FROM merchant_reward_reserves" - " WHERE reserve_pub = $2" - " AND merchant_serial =" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1)"), - /* For postgres_authorize_reward() */ - GNUNET_PQ_make_prepare ("update_reserve_rewards_committed", - "UPDATE merchant_reward_reserves SET" - " rewards_committed_val=$3" - ",rewards_committed_frac=$4" - " WHERE reserve_pub = $2" - " AND merchant_serial =" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1)"), - /* For postgres_authorize_reward() */ - GNUNET_PQ_make_prepare ("insert_reward", - "INSERT INTO merchant_rewards" - "(reserve_serial" - ",reward_id" - ",justification" - ",next_url" - ",expiration" - ",amount_val" - ",amount_frac" - ") " - "SELECT" - " reserve_serial, $3, $4, $5, $6, $7, $8" - " FROM merchant_reward_reserves" - " WHERE reserve_pub=$2" - " AND merchant_serial = " - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1)"), /* For postgres_lookup_pickup() */ GNUNET_PQ_make_prepare ("lookup_pickup", "SELECT" @@ -5379,10 +3636,8 @@ postgres_connect (void *cls) /* For postgres_lookup_reward() */ GNUNET_PQ_make_prepare ("lookup_reward", "SELECT" - " amount_val" - ",amount_frac" - ",picked_up_val" - ",picked_up_frac" + " amount" + ",picked_up" ",merchant_rewards.expiration" ",exchange_url" ",next_url" @@ -5400,8 +3655,7 @@ postgres_connect (void *cls) "SELECT" " reward_serial" ",reward_id" - ",amount_val" - ",amount_frac" + ",amount" ",CAST($4 as BIGINT)" /* otherwise $4 is unused and Postgres unhappy */ ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ " FROM merchant_rewards" @@ -5418,8 +3672,7 @@ postgres_connect (void *cls) "SELECT" " reward_serial" ",reward_id" - ",amount_val" - ",amount_frac" + ",amount" ",CAST($4 as BIGINT)" /* otherwise $4 is unused and Postgres unhappy */ ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ " FROM merchant_rewards" @@ -5436,8 +3689,7 @@ postgres_connect (void *cls) "SELECT" " reward_serial" ",reward_id" - ",amount_val" - ",amount_frac" + ",amount" " FROM merchant_rewards" " JOIN merchant_reward_reserves USING (reserve_serial)" " WHERE merchant_serial =" @@ -5454,8 +3706,7 @@ postgres_connect (void *cls) "SELECT" " reward_serial" ",reward_id" - ",amount_val" - ",amount_frac" + ",amount" " FROM merchant_rewards" " JOIN merchant_reward_reserves USING (reserve_serial)" " WHERE merchant_serial =" @@ -5472,10 +3723,8 @@ postgres_connect (void *cls) GNUNET_PQ_make_prepare ("lookup_reward_details", "SELECT" " reward_serial" - ",amount_val" - ",amount_frac" - ",picked_up_val" - ",picked_up_frac" + ",amount" + ",picked_up" ",justification" ",merchant_rewards.expiration" ",reserve_pub" @@ -5490,56 +3739,12 @@ postgres_connect (void *cls) GNUNET_PQ_make_prepare ("lookup_pickup_details", "SELECT" " pickup_id" - ",amount_val" - ",amount_frac" + ",amount" ",COUNT(blind_sig) AS num_planchets" " FROM merchant_reward_pickups" " JOIN merchant_reward_pickup_signatures USING (pickup_serial)" " WHERE reward_serial = $1" " GROUP BY pickup_serial"), - /* for postgres_insert_pickup() */ - GNUNET_PQ_make_prepare ("insert_pickup", - "INSERT INTO merchant_reward_pickups" - "(reward_serial" - ",pickup_id" - ",amount_val" - ",amount_frac" - ") " - "SELECT" - " reward_serial, $3, $4, $5" - " FROM merchant_rewards" - " JOIN merchant_reward_reserves USING (reserve_serial)" - " WHERE reward_id=$2" - " AND merchant_serial = " - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1)"), - /* for postgres_insert_pickup() */ - GNUNET_PQ_make_prepare ("update_picked_up_reward", - "UPDATE merchant_rewards SET" - " picked_up_val=$2" - ",picked_up_frac=$3" - ",was_picked_up = ($2 = amount_val AND $3 = amount_frac)" - " WHERE reward_id = $1"), - /* for postgres_insert_pickup() */ - GNUNET_PQ_make_prepare ("lookup_picked_up_reserve", - "SELECT" - " reserve_serial" - ",rewards_picked_up_val" - ",rewards_picked_up_frac" - " FROM merchant_reward_reserves" - " JOIN merchant_rewards USING (reserve_serial)" - " WHERE reward_id=$2" - " AND merchant_serial =" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1)"), - /* for postgres_insert_pickup() */ - GNUNET_PQ_make_prepare ("update_picked_up_reserve", - "UPDATE merchant_reward_reserves SET" - " rewards_picked_up_val=$2" - ",rewards_picked_up_frac=$3" - " WHERE reserve_serial = $1"), /* for postgres_insert_pickup_blind_signature() */ GNUNET_PQ_make_prepare ("insert_pickup_blind_signature", "INSERT INTO merchant_reward_pickup_signatures" @@ -5812,10 +4017,10 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) plugin->event_listen_cancel = &postgres_event_listen_cancel; plugin->event_notify = &postgres_event_notify; plugin->preflight = &postgres_preflight; - plugin->start = &postgres_start; - plugin->start_read_committed = &postgres_start_read_committed; - plugin->rollback = &postgres_rollback; - plugin->commit = &postgres_commit; + plugin->start = &TMH_PG_start; + plugin->start_read_committed = &TMH_PG_start_read_committed; + plugin->rollback = &TMH_PG_rollback; + plugin->commit = &TMH_PG_commit; plugin->lookup_instance_auth = &TMH_PG_lookup_instance_auth; plugin->insert_instance @@ -5901,18 +4106,16 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) plugin->lookup_deposits_by_order = &postgres_lookup_deposits_by_order; plugin->lookup_transfer_details_by_order = &postgres_lookup_transfer_details_by_order; - plugin->insert_deposit_to_transfer = &postgres_insert_deposit_to_transfer; plugin->mark_order_wired = &postgres_mark_order_wired; - plugin->increase_refund = &postgres_increase_refund; + plugin->increase_refund + = &TMH_PG_increase_refund; plugin->lookup_refunds_detailed = &postgres_lookup_refunds_detailed; plugin->insert_refund_proof = &postgres_insert_refund_proof; plugin->lookup_refund_proof = &postgres_lookup_refund_proof; plugin->lookup_order_by_fulfillment = &postgres_lookup_order_by_fulfillment; - plugin->insert_transfer = &postgres_insert_transfer; plugin->delete_transfer = &postgres_delete_transfer; plugin->check_transfer_exists = &postgres_check_transfer_exists; plugin->lookup_account = &postgres_lookup_account; - plugin->insert_transfer_details = &postgres_insert_transfer_details; plugin->lookup_wire_fee = &postgres_lookup_wire_fee; plugin->lookup_deposits_by_contract_and_coin = &postgres_lookup_deposits_by_contract_and_coin; @@ -5931,21 +4134,16 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) = &TMH_PG_update_wirewatch_progress; plugin->select_wirewatch_accounts = &TMH_PG_select_wirewatch_accounts; - plugin->store_wire_fee_by_exchange = &postgres_store_wire_fee_by_exchange; - plugin->insert_reserve = &postgres_insert_reserve; - plugin->activate_reserve = &postgres_activate_reserve; plugin->lookup_reserves = &TMH_PG_lookup_reserves; plugin->lookup_pending_reserves = &postgres_lookup_pending_reserves; plugin->lookup_reserve = &postgres_lookup_reserve; plugin->delete_reserve = &postgres_delete_reserve; plugin->purge_reserve = &postgres_purge_reserve; - plugin->authorize_reward = &postgres_authorize_reward; plugin->lookup_pickup = &postgres_lookup_pickup; plugin->lookup_reward = &postgres_lookup_reward; plugin->lookup_rewards = &postgres_lookup_rewards; plugin->lookup_reward_details = &postgres_lookup_reward_details; - plugin->insert_pickup = &postgres_insert_pickup; plugin->insert_pickup_blind_signature = &postgres_insert_pickup_blind_signature; plugin->select_open_transfers @@ -5954,6 +4152,22 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) = &TMH_PG_insert_exchange_keys; plugin->select_exchange_keys = &TMH_PG_select_exchange_keys; + plugin->insert_deposit_to_transfer + = &TMH_PG_insert_deposit_to_transfer; + plugin->insert_transfer + = &TMH_PG_insert_transfer; + plugin->insert_transfer_details + = &TMH_PG_insert_transfer_details; + plugin->store_wire_fee_by_exchange + = &TMH_PG_store_wire_fee_by_exchange; + plugin->insert_reserve + = &TMH_PG_insert_reserve; + plugin->activate_reserve + = &TMH_PG_activate_reserve; + plugin->authorize_reward + = &TMH_PG_authorize_reward; + plugin->insert_pickup + = &TMH_PG_insert_pickup; plugin->lookup_templates = &postgres_lookup_templates; plugin->lookup_template = &postgres_lookup_template; plugin->delete_template = &postgres_delete_template; |