2015-01-08 18:37:20 +01:00
/*
2022-01-08 14:40:20 +01:00
This file is part of TALER
2022-02-17 15:10:14 +01:00
Copyright ( C ) 2014 - - 2022 Taler Systems SA
2015-01-08 18:37:20 +01:00
2022-01-08 14:40:20 +01:00
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 .
2015-01-08 18:37:20 +01:00
2022-01-08 14:40:20 +01:00
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 .
2015-01-08 18:37:20 +01:00
2022-01-08 14:40:20 +01:00
You should have received a copy of the GNU General Public License along with
TALER ; see the file COPYING . If not , see < http : //www.gnu.org/licenses/>
*/
2015-08-13 23:16:31 +02:00
2015-01-08 18:37:20 +01:00
/**
2016-03-01 15:35:04 +01:00
* @ file plugin_exchangedb_postgres . c
* @ brief Low - level ( statement - level ) Postgres database access for the exchange
2015-01-08 18:37:20 +01:00
* @ author Florian Dold
2015-01-28 22:35:57 +01:00
* @ author Christian Grothoff
2015-03-05 16:05:06 +01:00
* @ author Sree Harsha Totakura
2016-10-18 12:34:57 +02:00
* @ author Marcello Stanisci
2015-01-08 18:37:20 +01:00
*/
# include "platform.h"
2017-11-27 23:42:17 +01:00
# include "taler_error_codes.h"
2021-08-22 12:25:48 +02:00
# include "taler_dbevents.h"
2015-03-27 19:58:40 +01:00
# include "taler_pq_lib.h"
2021-11-09 20:36:30 +01:00
# include "taler_util.h"
2021-01-10 21:42:25 +01:00
# include "taler_json_lib.h"
2016-03-01 15:35:04 +01:00
# include "taler_exchangedb_plugin.h"
2022-10-13 22:43:22 +02:00
# include "plugin_exchangedb_common.h"
2022-11-07 16:35:34 +01:00
# include "pg_delete_aggregation_transient.h"
# include "pg_get_link_data.h"
2022-10-03 12:46:30 +02:00
# include "pg_helper.h"
2022-10-12 14:48:49 +02:00
# include "pg_do_reserve_open.h"
2022-11-08 13:34:53 +01:00
# include "pg_do_withdraw.h"
2022-10-13 22:43:22 +02:00
# include "pg_get_coin_transactions.h"
2022-10-13 19:07:25 +02:00
# include "pg_get_expired_reserves.h"
2022-11-08 13:28:17 +01:00
# include "pg_get_purse_request.h"
2022-10-15 16:19:14 +02:00
# include "pg_get_reserve_history.h"
2022-10-13 19:07:25 +02:00
# include "pg_get_unfinished_close_requests.h"
2022-10-03 12:46:30 +02:00
# include "pg_insert_close_request.h"
2022-10-08 18:07:05 +02:00
# include "pg_insert_records_by_table.h"
2022-10-03 12:46:30 +02:00
# include "pg_insert_reserve_open_deposit.h"
2022-10-03 23:54:12 +02:00
# include "pg_iterate_kyc_reference.h"
# include "pg_iterate_reserve_close_info.h"
2022-10-08 21:09:13 +02:00
# include "pg_lookup_records_by_table.h"
2022-10-10 08:20:36 +02:00
# include "pg_lookup_serial_by_table.h"
2022-11-02 12:17:05 +01:00
# include "pg_select_account_merges_above_serial_id.h"
# include "pg_select_all_purse_decisions_above_serial_id.h"
# include "pg_select_purse.h"
# include "pg_select_purse_deposits_above_serial_id.h"
# include "pg_select_purse_merges_above_serial_id.h"
# include "pg_select_purse_requests_above_serial_id.h"
2022-10-03 23:54:12 +02:00
# include "pg_select_reserve_close_info.h"
2022-10-30 17:36:57 +01:00
# include "pg_select_reserve_closed_above_serial_id.h"
# include "pg_select_reserve_open_above_serial_id.h"
2021-08-13 22:35:13 +02:00
# include <poll.h>
2015-01-08 18:37:20 +01:00
# include <pthread.h>
2015-03-20 23:51:28 +01:00
# include <libpq-fe.h>
2015-01-08 18:37:20 +01:00
2022-11-08 13:28:17 +01:00
/**WHAT I ADD**/
# include "pg_insert_purse_request.h"
2022-11-08 15:21:01 +01:00
# include "pg_iterate_active_signkeys.h"
2022-11-10 16:37:28 +01:00
# include "pg_preflight.h"
2022-11-08 15:21:01 +01:00
# include "pg_commit.h"
2022-11-08 17:40:47 +01:00
# include "pg_create_shard_tables.h"
# include "pg_insert_aggregation_tracking.h"
# include "pg_drop_tables.h"
# include "pg_setup_partitions.h"
2022-11-10 16:37:28 +01:00
# include "pg_select_satisfied_kyc_processes.h"
# include "pg_select_aggregation_amounts_for_kyc_check.h"
# include "pg_kyc_provider_account_lookup.h"
# include "pg_lookup_kyc_requirement_by_row.h"
# include "pg_insert_kyc_requirement_for_account.h"
# include "pg_lookup_kyc_process_by_account.h"
# include "pg_update_kyc_process_by_row.h"
# include "pg_insert_kyc_requirement_process.h"
# include "pg_select_withdraw_amounts_for_kyc_check.h"
# include "pg_select_merge_amounts_for_kyc_check.h"
# include "pg_profit_drains_set_finished.h"
# include "pg_profit_drains_get_pending.h"
# include "pg_get_drain_profit.h"
# include "pg_get_purse_deposit.h"
# include "pg_insert_contract.h"
# include "pg_select_contract.h"
# include "pg_select_purse_merge.h"
# include "pg_select_contract_by_purse.h"
# include "pg_insert_drain_profit.h"
# include "pg_do_reserve_purse.h"
# include "pg_lookup_global_fee_by_time.h"
# include "pg_do_purse_deposit.h"
# include "pg_activate_signing_key.h"
# include "pg_update_auditor.h"
# include "pg_begin_revolving_shard.h"
# include "pg_get_extension_manifest.h"
# include "pg_insert_history_request.h"
# include "pg_do_purse_merge.h"
# include "pg_start_read_committed.h"
# include "pg_start_read_only.h"
# include "pg_insert_denomination_info.h"
# include "pg_do_batch_withdraw_insert.h"
# include "pg_lookup_wire_fee_by_time.h"
# include "pg_start.h"
# include "pg_rollback.h"
2018-08-10 22:30:38 +02:00
/**
* Set to 1 to enable Postgres auto_explain module . This will
* slow down things a _lot_ , but also provide extensive logging
* in the Postgres database logger for performance analysis .
*/
# define AUTO_EXPLAIN 1
2015-01-08 18:37:20 +01:00
2019-08-17 21:35:21 +02:00
2015-06-03 11:31:51 +02:00
/**
2017-03-18 03:44:59 +01:00
* Log a really unexpected PQ error with all the details we can get hold of .
2015-06-03 11:31:51 +02:00
*
* @ param result PQ result object of the PQ operation that failed
2017-03-18 03:44:59 +01:00
* @ param conn SQL connection that was used
2015-06-03 11:31:51 +02:00
*/
2019-10-11 23:28:05 +02:00
# define BREAK_DB_ERR(result,conn) do { \
GNUNET_break ( 0 ) ; \
GNUNET_log ( GNUNET_ERROR_TYPE_ERROR , \
" Database failure: %s/%s/%s/%s/%s " , \
PQresultErrorField ( result , PG_DIAG_MESSAGE_PRIMARY ) , \
PQresultErrorField ( result , PG_DIAG_MESSAGE_DETAIL ) , \
PQresultErrorMessage ( result ) , \
PQresStatus ( PQresultStatus ( result ) ) , \
PQerrorMessage ( conn ) ) ; \
2019-08-25 16:18:24 +02:00
} while ( 0 )
2015-01-08 18:37:20 +01:00
2015-06-03 11:31:51 +02:00
2015-03-05 16:05:06 +01:00
/**
* Create the necessary tables if they are not present
*
2015-03-21 14:21:00 +01:00
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2015-03-05 16:05:06 +01:00
* @ return # GNUNET_OK upon success ; # GNUNET_SYSERR upon failure
*/
2021-09-17 11:35:10 +02:00
static enum GNUNET_GenericReturnValue
2016-05-02 06:36:58 +02:00
postgres_create_tables ( void * cls )
2015-03-05 16:05:06 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2019-10-11 23:28:05 +02:00
struct GNUNET_PQ_Context * conn ;
2022-07-24 13:30:33 +02:00
enum GNUNET_GenericReturnValue ret ;
2015-03-05 16:05:06 +01:00
2021-08-23 00:00:32 +02:00
conn = GNUNET_PQ_connect_with_cfg ( pg - > cfg ,
2020-02-09 15:53:28 +01:00
" exchangedb-postgres " ,
2020-02-09 16:34:40 +01:00
" exchange- " ,
2020-02-09 15:53:28 +01:00
NULL ,
NULL ) ;
2016-05-31 09:34:45 +02:00
if ( NULL = = conn )
2015-03-05 16:05:06 +01:00
return GNUNET_SYSERR ;
2022-07-24 13:30:33 +02:00
ret = GNUNET_PQ_exec_sql ( conn ,
" procedures " ) ;
2019-10-11 23:28:05 +02:00
GNUNET_PQ_disconnect ( conn ) ;
2022-07-24 13:30:33 +02:00
return ret ;
2015-01-08 18:37:20 +01:00
}
2022-03-31 17:00:44 +02:00
/**
2022-03-31 21:31:07 +02:00
* Setup foreign servers ( shards ) for already existing tables
2022-03-31 17:00:44 +02:00
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2022-03-31 21:31:07 +02:00
* @ param num the number of foreign servers ( shards ) to create for each partitioned table
2022-03-31 17:00:44 +02:00
* @ return # GNUNET_OK upon success ; # GNUNET_SYSERR upon failure
*/
static enum GNUNET_GenericReturnValue
2022-03-31 21:31:07 +02:00
postgres_setup_foreign_servers ( void * cls ,
uint32_t num )
2022-03-31 17:00:44 +02:00
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_Context * conn ;
2022-04-02 14:25:04 +02:00
enum GNUNET_GenericReturnValue ret = GNUNET_OK ;
2022-05-02 00:27:59 +02:00
char * shard_domain = NULL ;
char * remote_user = NULL ;
char * remote_user_pw = NULL ;
if ( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_string ( pg - > cfg ,
" exchange " ,
" SHARD_DOMAIN " ,
& shard_domain ) )
{
GNUNET_log_config_missing ( GNUNET_ERROR_TYPE_ERROR ,
" exchange " ,
" SHARD_DOMAIN " ) ;
return GNUNET_SYSERR ;
}
if ( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_string ( pg - > cfg ,
" exchangedb-postgres " ,
" SHARD_REMOTE_USER " ,
& remote_user ) )
{
GNUNET_log_config_missing ( GNUNET_ERROR_TYPE_ERROR ,
" exchangedb-postgres " ,
" SHARD_REMOTE_USER " ) ;
GNUNET_free ( shard_domain ) ;
return GNUNET_SYSERR ;
}
if ( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_string ( pg - > cfg ,
" exchangedb-postgres " ,
" SHARD_REMOTE_USER_PW " ,
& remote_user_pw ) )
{
GNUNET_log_config_missing ( GNUNET_ERROR_TYPE_ERROR ,
" exchangedb-postgres " ,
" SHARD_REMOTE_USER_PW " ) ;
GNUNET_free ( shard_domain ) ;
GNUNET_free ( remote_user ) ;
return GNUNET_SYSERR ;
}
2022-03-31 17:00:44 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint32 ( & num ) ,
2022-05-02 00:27:59 +02:00
GNUNET_PQ_query_param_string ( shard_domain ) ,
GNUNET_PQ_query_param_string ( remote_user ) ,
GNUNET_PQ_query_param_string ( remote_user_pw ) ,
2022-03-31 17:00:44 +02:00
GNUNET_PQ_query_param_end
} ;
2022-07-25 20:18:08 +02:00
struct GNUNET_PQ_ExecuteStatement es [ ] = {
GNUNET_PQ_make_try_execute ( " SET search_path TO exchange; " ) ,
GNUNET_PQ_EXECUTE_STATEMENT_END
} ;
2022-03-31 17:00:44 +02:00
struct GNUNET_PQ_PreparedStatement ps [ ] = {
2022-03-31 21:31:07 +02:00
GNUNET_PQ_make_prepare ( " create_foreign_servers " ,
2022-03-31 17:00:44 +02:00
" SELECT "
2022-03-31 21:31:07 +02:00
" create_foreign_servers "
2022-10-12 14:48:49 +02:00
" ($1, $2, $3, $4); " ) ,
2022-03-31 17:00:44 +02:00
GNUNET_PQ_PREPARED_STATEMENT_END
} ;
conn = GNUNET_PQ_connect_with_cfg ( pg - > cfg ,
" exchangedb-postgres " ,
2022-03-31 21:31:07 +02:00
NULL ,
2022-07-25 20:18:08 +02:00
es ,
2022-03-31 17:00:44 +02:00
ps ) ;
if ( NULL = = conn )
2022-05-02 00:27:59 +02:00
{
2022-03-31 17:00:44 +02:00
ret = GNUNET_SYSERR ;
2022-05-02 00:27:59 +02:00
}
else if ( 0 > GNUNET_PQ_eval_prepared_non_select ( conn ,
" create_foreign_servers " ,
params ) )
{
ret = GNUNET_SYSERR ;
}
GNUNET_free ( shard_domain ) ;
GNUNET_free ( remote_user ) ;
GNUNET_free ( remote_user_pw ) ;
2022-03-31 17:00:44 +02:00
GNUNET_PQ_disconnect ( conn ) ;
return ret ;
}
2021-08-13 22:35:13 +02:00
/**
2021-08-23 00:06:36 +02:00
* Initialize prepared statements for @ a pg .
2021-08-13 22:35:13 +02:00
*
2021-08-23 00:06:36 +02:00
* @ param [ in , out ] pg connection to initialize
2021-08-13 22:35:13 +02:00
* @ return # GNUNET_OK on success
*/
2022-11-14 05:08:11 +01:00
enum GNUNET_GenericReturnValue
2021-08-23 00:00:32 +02:00
prepare_statements ( struct PostgresClosure * pg )
2021-08-13 22:35:13 +02:00
{
enum GNUNET_GenericReturnValue ret ;
struct GNUNET_PQ_PreparedStatement ps [ ] = {
/* Used in #postgres_insert_denomination_info() and
2022-01-08 14:40:20 +01:00
# postgres_add_denomination_key() * /
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" denomination_insert " ,
" INSERT INTO denominations "
" (denom_pub_hash "
" ,denom_pub "
" ,master_sig "
" ,valid_from "
" ,expire_withdraw "
" ,expire_deposit "
" ,expire_legal "
2022-01-08 14:40:20 +01:00
" ,coin_val " /* value of this denom */
" ,coin_frac " /* fractional value of this denom */
2021-10-31 13:27:50 +01:00
" ,fee_withdraw_val "
" ,fee_withdraw_frac "
" ,fee_deposit_val "
" ,fee_deposit_frac "
" ,fee_refresh_val "
" ,fee_refresh_frac "
" ,fee_refund_val "
" ,fee_refund_frac "
2022-02-16 22:01:05 +01:00
" ,age_mask "
2021-10-31 13:27:50 +01:00
" ) VALUES "
" ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, "
2022-10-12 14:48:49 +02:00
" $11, $12, $13, $14, $15, $16, $17, $18); " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_iterate_denomination_info() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" denomination_iterate " ,
" SELECT "
" master_sig "
2022-02-28 16:13:24 +01:00
" ,denom_pub_hash "
2021-10-31 13:27:50 +01:00
" ,valid_from "
" ,expire_withdraw "
" ,expire_deposit "
" ,expire_legal "
2022-01-08 14:40:20 +01:00
" ,coin_val " /* value of this denom */
" ,coin_frac " /* fractional value of this denom */
2021-10-31 13:27:50 +01:00
" ,fee_withdraw_val "
" ,fee_withdraw_frac "
" ,fee_deposit_val "
" ,fee_deposit_frac "
" ,fee_refresh_val "
" ,fee_refresh_frac "
" ,fee_refund_val "
" ,fee_refund_frac "
" ,denom_pub "
2022-02-16 22:01:05 +01:00
" ,age_mask "
2022-10-12 14:48:49 +02:00
" FROM denominations; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_iterate_denominations() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" select_denominations " ,
" SELECT "
" denominations.master_sig "
" ,denom_revocations_serial_id IS NOT NULL AS revoked "
" ,valid_from "
" ,expire_withdraw "
" ,expire_deposit "
" ,expire_legal "
2022-01-08 14:40:20 +01:00
" ,coin_val " /* value of this denom */
" ,coin_frac " /* fractional value of this denom */
2021-10-31 13:27:50 +01:00
" ,fee_withdraw_val "
" ,fee_withdraw_frac "
" ,fee_deposit_val "
" ,fee_deposit_frac "
" ,fee_refresh_val "
" ,fee_refresh_frac "
" ,fee_refund_val "
" ,fee_refund_frac "
2022-02-28 21:02:12 +01:00
" ,denom_type "
2022-02-16 22:01:05 +01:00
" ,age_mask "
2022-02-28 21:02:12 +01:00
" ,denom_pub "
2021-10-31 13:27:50 +01:00
" FROM denominations "
" LEFT JOIN "
2022-10-12 14:48:49 +02:00
" denomination_revocations USING (denominations_serial); " ) ,
2022-11-14 05:08:11 +01:00
2021-08-13 22:35:13 +02:00
/* Used in #postgres_iterate_auditor_denominations() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" select_auditor_denoms " ,
" SELECT "
" auditors.auditor_pub "
" ,denominations.denom_pub_hash "
" ,auditor_denom_sigs.auditor_sig "
" FROM auditor_denom_sigs "
" JOIN auditors USING (auditor_uuid) "
" JOIN denominations USING (denominations_serial) "
2022-10-12 14:48:49 +02:00
" WHERE auditors.is_active; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_iterate_active_auditors() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" select_auditors " ,
" SELECT "
" auditor_pub "
" ,auditor_url "
" ,auditor_name "
" FROM auditors "
" WHERE "
2022-10-12 14:48:49 +02:00
" is_active; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_get_denomination_info() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" denomination_get " ,
" SELECT "
" master_sig "
" ,valid_from "
" ,expire_withdraw "
" ,expire_deposit "
" ,expire_legal "
2022-01-08 14:40:20 +01:00
" ,coin_val " /* value of this denom */
" ,coin_frac " /* fractional value of this denom */
2021-10-31 13:27:50 +01:00
" ,fee_withdraw_val "
" ,fee_withdraw_frac "
" ,fee_deposit_val "
" ,fee_deposit_frac "
" ,fee_refresh_val "
" ,fee_refresh_frac "
" ,fee_refund_val "
" ,fee_refund_frac "
2022-02-16 22:01:05 +01:00
" ,age_mask "
2021-10-31 13:27:50 +01:00
" FROM denominations "
2022-10-12 14:48:49 +02:00
" WHERE denom_pub_hash=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_insert_denomination_revocation() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" denomination_revocation_insert " ,
" INSERT INTO denomination_revocations "
" (denominations_serial "
" ,master_sig "
" ) SELECT denominations_serial,$2 "
" FROM denominations "
2022-10-12 14:48:49 +02:00
" WHERE denom_pub_hash=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_get_denomination_revocation() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" denomination_revocation_get " ,
" SELECT "
" master_sig "
" ,denom_revocations_serial_id "
" FROM denomination_revocations "
" WHERE denominations_serial= "
" (SELECT denominations_serial "
" FROM denominations "
2022-10-12 14:48:49 +02:00
" WHERE denom_pub_hash=$1); " ) ,
2022-08-11 23:35:33 +02:00
/* Used in #postgres_reserves_get_origin() */
GNUNET_PQ_make_prepare (
" get_h_wire_source_of_reserve " ,
" SELECT "
" wire_source_h_payto "
" FROM reserves_in "
2022-10-12 14:48:49 +02:00
" WHERE reserve_pub=$1 " ) ,
2021-11-15 14:39:18 +01:00
GNUNET_PQ_make_prepare (
" get_kyc_h_payto " ,
" SELECT "
2022-03-03 23:52:08 +01:00
" wire_target_h_payto "
2021-11-15 14:39:18 +01:00
" FROM wire_targets "
2022-03-03 23:52:08 +01:00
" WHERE wire_target_h_payto=$1 "
2022-10-12 14:48:49 +02:00
" LIMIT 1; " ) ,
2022-04-04 20:42:26 +02:00
/* Used in #postgres_insert_partner() */
GNUNET_PQ_make_prepare (
" insert_partner " ,
" INSERT INTO partners "
" (partner_master_pub "
" ,start_date "
" ,end_date "
" ,wad_frequency "
" ,wad_fee_val "
" ,wad_fee_frac "
" ,master_sig "
" ,partner_base_url "
" ) VALUES "
2022-10-12 14:48:49 +02:00
" ($1, $2, $3, $4, $5, $6, $7, $8); " ) ,
2022-08-14 18:59:48 +02:00
/* Used in #setup_wire_target() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
2021-10-31 13:58:20 +01:00
" insert_kyc_status " ,
" INSERT INTO wire_targets "
2022-03-03 23:52:08 +01:00
" (wire_target_h_payto "
2021-10-31 13:27:50 +01:00
" ,payto_uri "
" ) VALUES "
" ($1, $2) "
2022-10-12 14:48:49 +02:00
" ON CONFLICT DO NOTHING " ) ,
2022-08-11 23:35:33 +02:00
/* Used in #postgres_drain_kyc_alert() */
GNUNET_PQ_make_prepare (
" drain_kyc_alert " ,
" DELETE FROM kyc_alerts "
" WHERE trigger_type=$1 "
" AND h_payto = "
" (SELECT h_payto "
" FROM kyc_alerts "
" WHERE trigger_type=$1 "
" LIMIT 1) "
2022-10-12 14:48:49 +02:00
" RETURNING h_payto; " ) ,
2022-08-14 18:04:09 +02:00
/* Used in #postgres_reserves_get() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" reserves_get " ,
" SELECT "
" current_balance_val "
" ,current_balance_frac "
" ,expiration_date "
" ,gc_date "
" FROM reserves "
" WHERE reserve_pub=$1 "
2022-10-12 14:48:49 +02:00
" LIMIT 1; " ) ,
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" reserve_create " ,
" INSERT INTO reserves "
" (reserve_pub "
" ,current_balance_val "
" ,current_balance_frac "
" ,expiration_date "
" ,gc_date "
" ) VALUES "
" ($1, $2, $3, $4, $5) "
" ON CONFLICT DO NOTHING "
2022-10-12 14:48:49 +02:00
" RETURNING reserve_uuid; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_insert_reserve_closed() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" reserves_close_insert " ,
" INSERT INTO reserves_close "
2021-12-19 13:43:33 +01:00
" (reserve_pub "
2021-10-31 13:27:50 +01:00
" ,execution_date "
" ,wtid "
2022-03-03 23:52:08 +01:00
" ,wire_target_h_payto "
2021-10-31 13:27:50 +01:00
" ,amount_val "
" ,amount_frac "
" ,closing_fee_val "
" ,closing_fee_frac "
2022-10-30 17:36:57 +01:00
" ,close_request_row "
" ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9); " ) ,
2022-11-14 05:08:11 +01:00
2022-07-30 23:13:15 +02:00
/* Used in #postgres_reserves_update() when the reserve is updated */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" reserve_update " ,
" UPDATE reserves "
" SET "
" expiration_date=$1 "
" ,gc_date=$2 "
" ,current_balance_val=$3 "
" ,current_balance_frac=$4 "
2022-10-12 14:48:49 +02:00
" WHERE reserve_pub=$5; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_reserves_in_insert() to store transaction details */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" reserves_in_add_transaction " ,
" INSERT INTO reserves_in "
2021-12-19 13:43:33 +01:00
" (reserve_pub "
2021-10-31 13:27:50 +01:00
" ,wire_reference "
" ,credit_val "
" ,credit_frac "
" ,exchange_account_section "
2022-03-03 23:52:08 +01:00
" ,wire_source_h_payto "
2021-10-31 13:27:50 +01:00
" ,execution_date "
2021-12-19 13:43:33 +01:00
" ) VALUES ($1, $2, $3, $4, $5, $6, $7) "
2022-10-12 14:48:49 +02:00
" ON CONFLICT DO NOTHING; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
transactions for reserves with serial id ' \ geq ' the given parameter */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" audit_reserves_in_get_transactions_incr " ,
" SELECT "
" reserves.reserve_pub "
" ,wire_reference "
" ,credit_val "
" ,credit_frac "
" ,execution_date "
" ,payto_uri AS sender_account_details "
" ,reserve_in_serial_id "
" FROM reserves_in "
" JOIN reserves "
2021-12-19 13:43:33 +01:00
" USING (reserve_pub) "
2021-10-31 13:27:50 +01:00
" JOIN wire_targets "
2022-03-03 23:52:08 +01:00
" ON (wire_source_h_payto = wire_target_h_payto) "
2021-10-31 13:27:50 +01:00
" WHERE reserve_in_serial_id>=$1 "
2022-10-12 14:48:49 +02:00
" ORDER BY reserve_in_serial_id; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
transactions for reserves with serial id ' \ geq ' the given parameter */
GNUNET_PQ_make_prepare (
" audit_reserves_in_get_transactions_incr_by_account " ,
" SELECT "
" reserves.reserve_pub "
" ,wire_reference "
" ,credit_val "
" ,credit_frac "
" ,execution_date "
2021-10-30 13:52:03 +02:00
" ,payto_uri AS sender_account_details "
2021-08-13 22:35:13 +02:00
" ,reserve_in_serial_id "
" FROM reserves_in "
" JOIN reserves "
2021-12-19 13:43:33 +01:00
" USING (reserve_pub) "
2021-10-30 13:52:03 +02:00
" JOIN wire_targets "
2022-03-03 23:52:08 +01:00
" ON (wire_source_h_payto = wire_target_h_payto) "
2021-08-13 22:35:13 +02:00
" WHERE reserve_in_serial_id>=$1 AND exchange_account_section=$2 "
2022-10-12 14:48:49 +02:00
" ORDER BY reserve_in_serial_id; " ) ,
2022-05-01 12:45:12 +02:00
/* Used in #postgres_do_batch_withdraw() to
update the reserve balance and check its status */
GNUNET_PQ_make_prepare (
" call_batch_withdraw " ,
" SELECT "
" reserve_found "
" ,balance_ok "
" ,ruuid "
" FROM exchange_do_batch_withdraw "
2022-10-12 14:48:49 +02:00
" ($1,$2,$3,$4,$5); " ) ,
2022-11-14 05:08:11 +01:00
2021-12-25 13:56:33 +01:00
/* Used in #postgres_do_deposit() to execute a deposit,
checking the coin ' s balance in the process as needed . */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
2021-12-25 13:56:33 +01:00
" call_deposit " ,
" SELECT "
" out_exchange_timestamp AS exchange_timestamp "
" ,out_balance_ok AS balance_ok "
" ,out_conflict AS conflicted "
" FROM exchange_do_deposit "
2022-10-12 14:48:49 +02:00
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17); " ) ,
2022-11-10 16:37:28 +01:00
2022-06-19 14:04:41 +02:00
/* Used in #postgres_update_aggregation_transient() */
GNUNET_PQ_make_prepare (
" set_purse_balance " ,
" UPDATE purse_requests "
" SET balance_val=$2 "
" ,balance_frac=$3 "
2022-10-12 14:48:49 +02:00
" WHERE purse_pub=$1; " ) ,
2022-05-17 08:50:28 +02:00
/* used in #postgres_expire_purse() */
GNUNET_PQ_make_prepare (
" call_expire_purse " ,
" SELECT "
" out_found AS found "
" FROM exchange_do_expire_purse "
2022-10-30 17:36:57 +01:00
" ($1,$2,$3); " ) ,
2021-12-25 13:56:33 +01:00
/* Used in #postgres_do_melt() to melt a coin. */
GNUNET_PQ_make_prepare (
" call_melt " ,
" SELECT "
" out_balance_ok AS balance_ok "
" ,out_zombie_bad AS zombie_required "
" ,out_noreveal_index AS noreveal_index "
" FROM exchange_do_melt "
2022-10-12 14:48:49 +02:00
" ($1,$2,$3,$4,$5,$6,$7,$8,$9); " ) ,
2021-12-25 13:56:33 +01:00
/* Used in #postgres_do_refund() to refund a deposit. */
GNUNET_PQ_make_prepare (
" call_refund " ,
" SELECT "
" out_not_found AS not_found "
" ,out_refund_ok AS refund_ok "
" ,out_gone AS gone "
" ,out_conflict AS conflict "
" FROM exchange_do_refund "
2022-10-12 14:48:49 +02:00
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13); " ) ,
2021-12-25 13:56:33 +01:00
/* Used in #postgres_do_recoup() to recoup a coin to a reserve. */
GNUNET_PQ_make_prepare (
" call_recoup " ,
" SELECT "
" out_recoup_timestamp AS recoup_timestamp "
" ,out_recoup_ok AS recoup_ok "
" ,out_internal_failure AS internal_failure "
" FROM exchange_do_recoup_to_reserve "
2022-10-12 14:48:49 +02:00
" ($1,$2,$3,$4,$5,$6,$7,$8,$9); " ) ,
2021-12-25 13:56:33 +01:00
/* Used in #postgres_do_recoup_refresh() to recoup a coin to a zombie coin. */
GNUNET_PQ_make_prepare (
" call_recoup_refresh " ,
" SELECT "
" out_recoup_timestamp AS recoup_timestamp "
" ,out_recoup_ok AS recoup_ok "
" ,out_internal_failure AS internal_failure "
" FROM exchange_do_recoup_to_coin "
2022-10-12 14:48:49 +02:00
" ($1,$2,$3,$4,$5,$6,$7); " ) ,
2021-08-13 22:35:13 +02:00
/* 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 . */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_withdraw_info " ,
" SELECT "
" denom.denom_pub_hash "
" ,denom_sig "
" ,reserve_sig "
" ,reserves.reserve_pub "
" ,execution_date "
2022-02-15 17:07:13 +01:00
" ,h_blind_ev "
2021-10-31 13:27:50 +01:00
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
" ,denom.fee_withdraw_val "
" ,denom.fee_withdraw_frac "
" FROM reserves_out "
" JOIN reserves "
2021-12-25 13:56:33 +01:00
" USING (reserve_uuid) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denom "
" USING (denominations_serial) "
2022-10-12 14:48:49 +02:00
" WHERE h_blind_ev=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_select_withdrawals_above_serial_id() */
2022-03-21 02:39:36 +01:00
GNUNET_PQ_make_prepare (
" get_reserve_balance " ,
" SELECT "
" current_balance_val "
" ,current_balance_frac "
" FROM reserves "
2022-10-12 14:48:49 +02:00
" WHERE reserve_pub=$1; " ) ,
2022-03-21 02:39:36 +01:00
/* Fetch deposits with rowid '\geq' the given parameter */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" audit_get_reserves_out_incr " ,
" SELECT "
" h_blind_ev "
" ,denom.denom_pub "
" ,reserve_sig "
" ,reserves.reserve_pub "
" ,execution_date "
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
" ,reserve_out_serial_id "
" FROM reserves_out "
" JOIN reserves "
2021-12-25 13:56:33 +01:00
" USING (reserve_uuid) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denom "
" USING (denominations_serial) "
" WHERE reserve_out_serial_id>=$1 "
2022-10-12 14:48:49 +02:00
" ORDER BY reserve_out_serial_id ASC; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_count_known_coins() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" count_known_coins " ,
" SELECT "
" COUNT(*) AS count "
" FROM known_coins "
" WHERE denominations_serial= "
" (SELECT denominations_serial "
" FROM denominations "
2022-10-12 14:48:49 +02:00
" WHERE denom_pub_hash=$1); " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_get_known_coin() to fetch
the denomination public key and signature for
a coin known to the exchange . */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_known_coin " ,
" SELECT "
" denominations.denom_pub_hash "
2022-02-22 14:27:15 +01:00
" ,age_commitment_hash "
2021-10-31 13:27:50 +01:00
" ,denom_sig "
" FROM known_coins "
" JOIN denominations USING (denominations_serial) "
2022-10-12 14:48:49 +02:00
" WHERE coin_pub=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_ensure_coin_known() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_known_coin_dh " ,
" SELECT "
" denominations.denom_pub_hash "
" FROM known_coins "
" JOIN denominations USING (denominations_serial) "
2022-10-12 14:48:49 +02:00
" WHERE coin_pub=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_get_coin_denomination() to fetch
the denomination public key hash for
a coin known to the exchange . */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_coin_denomination " ,
" SELECT "
" denominations.denom_pub_hash "
2021-12-25 13:56:33 +01:00
" ,known_coin_id "
2021-10-31 13:27:50 +01:00
" FROM known_coins "
" JOIN denominations USING (denominations_serial) "
" WHERE coin_pub=$1 "
2022-10-12 14:48:49 +02:00
" FOR SHARE; " ) ,
2021-12-25 13:56:33 +01:00
/* Used in #postgres_insert_known_coin() to store the denomination public
key and signature for a coin known to the exchange .
See also :
https : //stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql/37543015#37543015
2022-01-08 14:40:20 +01:00
*/
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_known_coin " ,
2021-12-25 13:56:33 +01:00
" WITH dd "
" (denominations_serial "
" ,coin_val "
" ,coin_frac "
" ) AS ( "
" SELECT "
" denominations_serial "
" ,coin_val "
" ,coin_frac "
" FROM denominations "
" WHERE denom_pub_hash=$2 "
" ), input_rows "
" (coin_pub) AS ( "
" VALUES ($1::BYTEA) "
" ), ins AS ( "
" INSERT INTO known_coins "
" (coin_pub "
" ,denominations_serial "
2022-02-22 14:27:15 +01:00
" ,age_commitment_hash "
2021-12-25 13:56:33 +01:00
" ,denom_sig "
" ,remaining_val "
" ,remaining_frac "
" ) SELECT "
" $1 "
" ,denominations_serial "
" ,$3 "
" ,$4 "
" ,coin_val "
" ,coin_frac "
" FROM dd "
2022-02-24 14:31:19 +01:00
" ON CONFLICT DO NOTHING " /* CONFLICT on (coin_pub) */
2021-12-25 13:56:33 +01:00
" RETURNING "
" known_coin_id "
" ) "
" SELECT "
" FALSE AS existed "
" ,known_coin_id "
" ,NULL AS denom_pub_hash "
2022-02-22 14:27:15 +01:00
" ,NULL AS age_commitment_hash "
2021-12-25 13:56:33 +01:00
" FROM ins "
" UNION ALL "
" SELECT "
" TRUE AS existed "
" ,known_coin_id "
" ,denom_pub_hash "
2022-02-22 14:27:15 +01:00
" ,kc.age_commitment_hash "
2021-12-25 13:56:33 +01:00
" FROM input_rows "
" JOIN known_coins kc USING (coin_pub) "
" JOIN denominations USING (denominations_serial) "
2022-10-12 14:48:49 +02:00
" LIMIT 1 " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_get_melt() to fetch
high - level information about a melt operation */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_melt " ,
2022-04-06 13:33:47 +02:00
/* "SELECT"
2021-10-31 13:27:50 +01:00
" denoms.denom_pub_hash "
" ,denoms.fee_refresh_val "
" ,denoms.fee_refresh_frac "
2021-12-25 13:56:33 +01:00
" ,old_coin_pub "
2021-10-31 13:27:50 +01:00
" ,old_coin_sig "
2022-03-17 14:16:19 +01:00
" ,kc.age_commitment_hash "
2021-10-31 13:27:50 +01:00
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
" ,noreveal_index "
2021-12-25 13:56:33 +01:00
" ,melt_serial_id "
2021-10-31 13:27:50 +01:00
" FROM refresh_commitments "
" JOIN known_coins kc "
2021-12-25 13:56:33 +01:00
" ON (old_coin_pub = kc.coin_pub) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denoms "
" ON (kc.denominations_serial = denoms.denominations_serial) "
2022-04-06 13:33:47 +02:00
" WHERE rc=$1; " , */
" WITH rc AS MATERIALIZED ( "
" SELECT "
" * FROM refresh_commitments "
" WHERE rc=$1 "
" ) "
" SELECT "
" denoms.denom_pub_hash "
" ,denoms.fee_refresh_val "
" ,denoms.fee_refresh_frac "
" ,rc.old_coin_pub "
" ,rc.old_coin_sig "
" ,kc.age_commitment_hash "
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
" ,noreveal_index "
" ,melt_serial_id "
" FROM ( "
" SELECT "
" * "
" FROM known_coins "
" WHERE coin_pub=(SELECT old_coin_pub from rc) "
" ) kc "
" JOIN rc "
" ON (kc.coin_pub=rc.old_coin_pub) "
" JOIN denominations denoms "
2022-10-12 14:48:49 +02:00
" USING (denominations_serial); " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_select_refreshes_above_serial_id() to fetch
refresh session with id ' \ geq ' the given parameter */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" audit_get_refresh_commitments_incr " ,
" SELECT "
" denom.denom_pub "
" ,kc.coin_pub AS old_coin_pub "
2022-03-17 14:16:19 +01:00
" ,kc.age_commitment_hash "
2021-10-31 13:27:50 +01:00
" ,old_coin_sig "
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
" ,noreveal_index "
" ,melt_serial_id "
" ,rc "
" FROM refresh_commitments "
" JOIN known_coins kc "
2021-12-25 13:56:33 +01:00
" ON (refresh_commitments.old_coin_pub = kc.coin_pub) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denom "
" ON (kc.denominations_serial = denom.denominations_serial) "
" WHERE melt_serial_id>=$1 "
2022-10-12 14:48:49 +02:00
" ORDER BY melt_serial_id ASC; " ) ,
2021-08-13 22:35:13 +02:00
/* Store information about the desired denominations for a
refresh operation , used in # postgres_insert_refresh_reveal ( ) */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_refresh_revealed_coin " ,
" INSERT INTO refresh_revealed_coins "
" (melt_serial_id "
" ,freshcoin_index "
" ,link_sig "
" ,denominations_serial "
" ,coin_ev "
2022-02-10 23:39:00 +01:00
" ,ewv "
2021-10-31 13:27:50 +01:00
" ,h_coin_ev "
" ,ev_sig "
2021-12-25 13:56:33 +01:00
" ) SELECT $1, $2, $3, "
2022-02-10 23:39:00 +01:00
" denominations_serial, $5, $6, $7, $8 "
2021-10-31 13:27:50 +01:00
" FROM denominations "
2022-05-12 13:31:15 +02:00
" WHERE denom_pub_hash=$4 "
2022-10-12 14:48:49 +02:00
" ON CONFLICT DO NOTHING; " ) ,
2021-08-13 22:35:13 +02:00
/* Obtain information about the coins created in a refresh
operation , used in # postgres_get_refresh_reveal ( ) */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_refresh_revealed_coins " ,
" SELECT "
2021-11-17 11:26:19 +01:00
" rrc.freshcoin_index "
2021-12-25 13:56:33 +01:00
" ,denom.denom_pub_hash "
2021-12-25 15:39:01 +01:00
" ,rrc.h_coin_ev "
2021-11-17 11:26:19 +01:00
" ,rrc.link_sig "
" ,rrc.coin_ev "
2022-02-10 23:39:00 +01:00
" ,rrc.ewv "
2021-11-17 11:26:19 +01:00
" ,rrc.ev_sig "
" FROM refresh_commitments "
" JOIN refresh_revealed_coins rrc "
" USING (melt_serial_id) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denom "
" USING (denominations_serial) "
2022-10-12 14:48:49 +02:00
" WHERE rc=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_insert_refresh_reveal() to store the transfer
keys we learned */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_refresh_transfer_keys " ,
" INSERT INTO refresh_transfer_keys "
" (melt_serial_id "
" ,transfer_pub "
" ,transfer_privs "
2022-05-12 13:31:15 +02:00
" ) VALUES ($1, $2, $3) "
2022-10-12 14:48:49 +02:00
" ON CONFLICT DO NOTHING; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_insert_refund() to store refund information */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_refund " ,
" INSERT INTO refunds "
2022-03-26 10:46:37 +01:00
" (coin_pub "
" ,deposit_serial_id "
2021-10-31 13:27:50 +01:00
" ,merchant_sig "
" ,rtransaction_id "
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
2022-03-26 10:46:37 +01:00
" ) SELECT $1, deposit_serial_id, $3, $5, $6, $7 "
" FROM deposits "
2022-03-24 17:33:29 +01:00
" WHERE coin_pub=$1 "
" AND h_contract_terms=$4 "
2022-10-12 14:48:49 +02:00
" AND merchant_pub=$2 " ) ,
2021-08-13 22:35:13 +02:00
/* Query the 'refunds' by coin public key */
/* Query the 'refunds' by coin public key, merchant_pub and contract hash */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_refunds_by_coin_and_contract " ,
" SELECT "
2022-03-18 15:40:24 +01:00
" ref.amount_with_fee_val "
" ,ref.amount_with_fee_frac "
2022-03-26 10:46:37 +01:00
" FROM refunds ref "
" JOIN deposits dep "
" USING (coin_pub,deposit_serial_id) "
" WHERE ref.coin_pub=$1 "
2022-03-18 15:40:24 +01:00
" AND dep.merchant_pub=$2 "
2022-10-12 14:48:49 +02:00
" AND dep.h_contract_terms=$3; " ) ,
2021-08-13 22:35:13 +02:00
/* Fetch refunds with rowid '\geq' the given parameter */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" audit_get_refunds_incr " ,
" SELECT "
2022-03-26 10:46:37 +01:00
" dep.merchant_pub "
" ,ref.merchant_sig "
" ,dep.h_contract_terms "
" ,ref.rtransaction_id "
2021-10-31 13:27:50 +01:00
" ,denom.denom_pub "
" ,kc.coin_pub "
2022-03-26 10:46:37 +01:00
" ,ref.amount_with_fee_val "
" ,ref.amount_with_fee_frac "
" ,ref.refund_serial_id "
" FROM refunds ref "
" JOIN deposits dep "
" ON (ref.coin_pub=dep.coin_pub AND ref.deposit_serial_id=dep.deposit_serial_id) "
" JOIN known_coins kc "
" ON (dep.coin_pub=kc.coin_pub) "
" JOIN denominations denom "
" ON (kc.denominations_serial=denom.denominations_serial) "
" WHERE ref.refund_serial_id>=$1 "
2022-10-12 14:48:49 +02:00
" ORDER BY ref.refund_serial_id ASC; " ) ,
2022-06-13 15:31:52 +02:00
GNUNET_PQ_make_prepare (
" test_refund_full " ,
" SELECT "
" CAST(SUM(CAST(ref.amount_with_fee_frac AS INT8)) AS INT8) AS s_f "
" ,CAST(SUM(ref.amount_with_fee_val) AS INT8) AS s_v "
" ,dep.amount_with_fee_val "
" ,dep.amount_with_fee_frac "
" FROM refunds ref "
" JOIN deposits dep "
" ON (ref.coin_pub=dep.coin_pub AND ref.deposit_serial_id=dep.deposit_serial_id) "
" WHERE ref.refund_serial_id=$1 "
2022-10-12 14:48:49 +02:00
" GROUP BY (dep.amount_with_fee_val, dep.amount_with_fee_frac); " ) ,
2022-03-26 10:46:37 +01:00
2021-08-13 22:35:13 +02:00
/* Store information about a /deposit the exchange is to execute.
2022-05-02 19:55:40 +02:00
Used in # postgres_insert_deposit ( ) . Only used in test cases . */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_deposit " ,
" INSERT INTO deposits "
" (known_coin_id "
2022-03-18 01:57:39 +01:00
" ,coin_pub "
2021-10-31 13:27:50 +01:00
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
" ,wallet_timestamp "
" ,refund_deadline "
" ,wire_deadline "
" ,merchant_pub "
" ,h_contract_terms "
" ,wire_salt "
2022-03-03 23:52:08 +01:00
" ,wire_target_h_payto "
2021-10-31 13:27:50 +01:00
" ,coin_sig "
" ,exchange_timestamp "
" ,shard "
2022-03-18 01:57:39 +01:00
" ) SELECT known_coin_id, $1, $2, $3, $4, $5, $6, "
2021-10-31 13:27:50 +01:00
" $7, $8, $9, $10, $11, $12, $13 "
" FROM known_coins "
2022-05-02 19:55:40 +02:00
" WHERE coin_pub=$1 "
2022-10-12 14:48:49 +02:00
" ON CONFLICT DO NOTHING; " ) ,
2021-08-13 22:35:13 +02:00
/* Fetch an existing deposit request, used to ensure idempotency
during / deposit processing . Used in # postgres_have_deposit ( ) . */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_deposit " ,
" SELECT "
2022-03-18 15:40:24 +01:00
" dep.amount_with_fee_val "
" ,dep.amount_with_fee_frac "
2021-10-31 13:27:50 +01:00
" ,denominations.fee_deposit_val "
" ,denominations.fee_deposit_frac "
2022-03-18 15:40:24 +01:00
" ,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 "
2022-03-24 17:33:29 +01:00
" FROM deposits dep "
" JOIN known_coins kc ON (kc.coin_pub = dep.coin_pub) "
2021-10-31 13:27:50 +01:00
" JOIN denominations USING (denominations_serial) "
2022-03-18 15:40:24 +01:00
" JOIN wire_targets wt USING (wire_target_h_payto) "
2022-03-24 17:33:29 +01:00
" WHERE dep.coin_pub=$1 "
2022-03-18 15:40:24 +01:00
" AND dep.merchant_pub=$3 "
2022-10-12 14:48:49 +02:00
" AND dep.h_contract_terms=$2; " ) ,
2021-08-13 22:35:13 +02:00
/* Fetch deposits with rowid '\geq' the given parameter */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" audit_get_deposits_incr " ,
" SELECT "
" amount_with_fee_val "
" ,amount_with_fee_frac "
" ,wallet_timestamp "
" ,exchange_timestamp "
" ,merchant_pub "
" ,denom.denom_pub "
" ,kc.coin_pub "
2022-02-28 16:13:24 +01:00
" ,kc.age_commitment_hash "
2021-10-31 13:27:50 +01:00
" ,coin_sig "
" ,refund_deadline "
" ,wire_deadline "
" ,h_contract_terms "
" ,wire_salt "
" ,payto_uri AS receiver_wire_account "
" ,done "
" ,deposit_serial_id "
" FROM deposits "
2022-03-03 23:52:08 +01:00
" JOIN wire_targets USING (wire_target_h_payto) "
2022-03-18 01:57:39 +01:00
" JOIN known_coins kc USING (coin_pub) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denom USING (denominations_serial) "
" WHERE ( "
2022-06-12 17:23:31 +02:00
" (deposit_serial_id>=$1) "
2021-10-31 13:27:50 +01:00
" ) "
2022-10-12 14:48:49 +02:00
" ORDER BY deposit_serial_id ASC; " ) ,
2022-06-15 20:49:39 +02:00
GNUNET_PQ_make_prepare (
" audit_get_history_requests_incr " ,
" SELECT "
" history_request_serial_id "
" ,history_fee_val "
" ,history_fee_frac "
" ,request_timestamp "
" ,reserve_pub "
" ,reserve_sig "
" FROM history_requests "
" WHERE ( "
" (history_request_serial_id>=$1) "
" ) "
2022-10-12 14:48:49 +02:00
" ORDER BY history_request_serial_id ASC; " ) ,
2022-06-15 20:49:39 +02:00
2022-06-13 15:31:52 +02:00
GNUNET_PQ_make_prepare (
" audit_get_purse_deposits_by_purse " ,
" SELECT "
2022-06-14 15:57:48 +02:00
" pd.purse_deposit_serial_id "
" ,pd.amount_with_fee_val "
2022-06-13 15:31:52 +02:00
" ,pd.amount_with_fee_frac "
" ,pd.coin_pub "
" ,denom.denom_pub "
" FROM purse_deposits pd "
" JOIN known_coins kc USING (coin_pub) "
" JOIN denominations denom USING (denominations_serial) "
2022-10-12 14:48:49 +02:00
" WHERE purse_pub=$1; " ) ,
2022-06-13 15:31:52 +02:00
GNUNET_PQ_make_prepare (
2022-10-30 17:36:57 +01:00
" audit_get_purse_decisions_incr " ,
2022-06-13 15:31:52 +02:00
" SELECT "
2022-10-30 17:36:57 +01:00
" pd.purse_pub "
" ,pm.reserve_pub "
" ,pd.purse_decision_serial_id "
" ,pr.amount_with_fee_val "
" ,pr.amount_with_fee_frac "
" FROM purse_decision pd "
" JOIN purse_requests pr ON (pd.purse_pub = pr.purse_pub) "
" LEFT JOIN purse_merges pm ON (pm.purse_pub = pd.purse_pub) "
2022-06-13 15:31:52 +02:00
" WHERE ( "
2022-10-30 17:36:57 +01:00
" (purse_decision_serial_id>=$1) AND "
" (refunded=$2) "
2022-06-13 15:31:52 +02:00
" ) "
2022-10-30 17:36:57 +01:00
" ORDER BY purse_decision_serial_id ASC; " ) ,
2021-08-13 22:35:13 +02:00
/* Fetch an existing deposit request.
Used in # postgres_lookup_transfer_by_deposit ( ) . */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
2021-11-07 11:41:53 +01:00
" get_deposit_without_wtid " ,
2021-10-31 13:27:50 +01:00
" SELECT "
2022-08-20 21:29:29 +02:00
" agt.legitimization_requirement_serial_id "
2022-03-18 15:40:24 +01:00
" ,dep.wire_salt "
" ,wt.payto_uri "
" ,dep.amount_with_fee_val "
" ,dep.amount_with_fee_frac "
2021-10-31 13:27:50 +01:00
" ,denom.fee_deposit_val "
" ,denom.fee_deposit_frac "
2022-03-18 15:40:24 +01:00
" ,dep.wire_deadline "
2022-03-24 17:33:29 +01:00
" FROM deposits dep "
2022-08-20 21:29:29 +02:00
" JOIN wire_targets wt "
" USING (wire_target_h_payto) "
" JOIN known_coins kc "
" ON (kc.coin_pub = dep.coin_pub) "
" JOIN denominations denom "
" USING (denominations_serial) "
" LEFT JOIN aggregation_transient agt "
" ON ( (dep.wire_target_h_payto = agt.wire_target_h_payto) AND "
" (dep.merchant_pub = agt.merchant_pub) ) "
2022-03-24 17:33:29 +01:00
" WHERE dep.coin_pub=$1 "
2022-03-18 15:40:24 +01:00
" AND dep.merchant_pub=$3 "
2022-08-11 23:35:33 +02:00
" AND dep.h_contract_terms=$2 "
2022-10-12 14:48:49 +02:00
" LIMIT 1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_get_ready_deposit() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" deposits_get_ready " ,
" SELECT "
2022-03-27 13:48:25 +02:00
" payto_uri "
2021-10-31 13:27:50 +01:00
" ,merchant_pub "
2022-03-24 17:33:29 +01:00
" FROM deposits_by_ready dbr "
" JOIN deposits dep "
2022-08-11 23:35:33 +02:00
" ON (dbr.coin_pub = dep.coin_pub AND "
" dbr.deposit_serial_id = dep.deposit_serial_id) "
2022-03-27 13:48:25 +02:00
" JOIN wire_targets wt "
2022-03-03 23:52:08 +01:00
" USING (wire_target_h_payto) "
2022-03-24 17:33:29 +01:00
" WHERE dbr.wire_deadline<=$1 "
" AND dbr.shard >= $2 "
" AND dbr.shard <= $3 "
2021-10-31 13:27:50 +01:00
" ORDER BY "
2022-03-24 17:33:29 +01:00
" dbr.wire_deadline ASC "
" ,dbr.shard ASC "
2022-10-12 14:48:49 +02:00
" LIMIT 1; " ) ,
2022-03-27 10:32:28 +02:00
/* Used in #postgres_aggregate() */
GNUNET_PQ_make_prepare (
" aggregate " ,
2022-03-27 13:48:25 +02:00
" WITH rdy AS ( " /* find deposits ready by merchant */
2022-03-27 10:32:28 +02:00
" SELECT "
" coin_pub "
" FROM deposits_for_matching "
2022-03-27 13:48:25 +02:00
" WHERE refund_deadline<$1 " /* filter by shard, only actually executable deposits */
" AND merchant_pub=$2 " /* filter by target merchant */
2022-03-27 10:32:28 +02:00
" ORDER BY refund_deadline ASC " /* ordering is not critical */
" LIMIT "
2022-03-27 13:48:25 +02:00
TALER_QUOTE ( TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT ) /* limits transaction size */
2022-03-27 10:32:28 +02:00
" ) "
2022-03-27 13:48:25 +02:00
" ,dep AS ( " /* restrict to our merchant and account and mark as done */
2022-03-27 10:32:28 +02:00
" UPDATE deposits "
" SET done=TRUE "
" WHERE coin_pub IN (SELECT coin_pub FROM rdy) "
2022-03-27 13:48:25 +02:00
" AND merchant_pub=$2 " /* theoretically, same coin could be spent at another merchant */
" AND wire_target_h_payto=$3 " /* merchant could have a 2nd bank account */
" AND done=FALSE " /* theoretically, same coin could be spend at the same merchant a 2nd time */
2022-03-27 10:32:28 +02:00
" RETURNING "
" deposit_serial_id "
" ,coin_pub "
" ,amount_with_fee_val AS amount_val "
" ,amount_with_fee_frac AS amount_frac) "
2022-05-12 11:10:32 +02:00
" ,ref AS ( " /* find applicable refunds -- NOTE: may do a full join on the master, maybe find a left-join way to integrate with query above to push it to the shards? */
2022-03-27 10:32:28 +02:00
" SELECT "
" amount_with_fee_val AS refund_val "
" ,amount_with_fee_frac AS refund_frac "
" ,coin_pub "
2022-03-27 13:48:25 +02:00
" ,deposit_serial_id " /* theoretically, coin could be in multiple refunded transactions */
2022-03-27 10:32:28 +02:00
" FROM refunds "
" WHERE coin_pub IN (SELECT coin_pub FROM dep) "
" AND deposit_serial_id IN (SELECT deposit_serial_id FROM dep)) "
2022-07-09 12:14:20 +02:00
" ,ref_by_coin AS ( " /* total up refunds by coin */
" SELECT "
" SUM(refund_val) AS sum_refund_val "
" ,SUM(refund_frac) AS sum_refund_frac "
" ,coin_pub "
" ,deposit_serial_id " /* theoretically, coin could be in multiple refunded transactions */
" FROM ref "
" GROUP BY coin_pub, deposit_serial_id) "
" ,norm_ref_by_coin AS ( " /* normalize */
" SELECT "
" sum_refund_val + sum_refund_frac / 100000000 AS norm_refund_val "
" ,sum_refund_frac % 100000000 AS norm_refund_frac "
" ,coin_pub "
" ,deposit_serial_id " /* theoretically, coin could be in multiple refunded transactions */
" FROM ref_by_coin) "
" ,fully_refunded_coins AS ( " /* find applicable refunds -- NOTE: may do a full join on the master, maybe find a left-join way to integrate with query above to push it to the shards? */
" 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)) "
" ,fees AS ( " /* find deposit fees for not fully refunded deposits */
2022-03-27 10:32:28 +02:00
" SELECT "
" denom.fee_deposit_val AS fee_val "
" ,denom.fee_deposit_frac AS fee_frac "
2022-03-27 13:48:25 +02:00
" ,cs.deposit_serial_id " /* ensures we get the fee for each coin, not once per denomination */
2022-07-06 18:36:51 +02:00
" FROM dep cs "
2022-05-12 11:10:32 +02:00
" JOIN known_coins kc " /* NOTE: may do a full join on the master, maybe find a left-join way to integrate with query above to push it to the shards? */
2022-03-27 13:48:25 +02:00
" USING (coin_pub) "
2022-03-27 10:32:28 +02:00
" JOIN denominations denom "
2022-07-09 12:14:20 +02:00
" USING (denominations_serial) "
" WHERE coin_pub NOT IN (SELECT coin_pub FROM fully_refunded_coins)) "
2022-03-27 10:32:28 +02:00
" ,dummy AS ( " /* add deposits to aggregation_tracking */
" INSERT INTO aggregation_tracking "
" (deposit_serial_id "
" ,wtid_raw) "
" SELECT deposit_serial_id,$4 "
" FROM dep) "
" SELECT " /* calculate totals (deposits, refunds and fees) */
2022-03-27 13:48:25 +02:00
" CAST(COALESCE(SUM(dep.amount_val),0) AS INT8) AS sum_deposit_value " /* cast needed, otherwise we get NUMBER */
" ,COALESCE(SUM(dep.amount_frac),0) AS sum_deposit_fraction " /* SUM over INT returns INT8 */
2022-03-27 10:32:28 +02:00
" ,CAST(COALESCE(SUM(ref.refund_val),0) AS INT8) AS sum_refund_value "
" ,COALESCE(SUM(ref.refund_frac),0) AS sum_refund_fraction "
" ,CAST(COALESCE(SUM(fees.fee_val),0) AS INT8) AS sum_fee_value "
" ,COALESCE(SUM(fees.fee_frac),0) AS sum_fee_fraction "
" FROM dep "
2022-03-27 13:48:25 +02:00
" FULL OUTER JOIN ref ON (FALSE) " /* We just want all sums */
2022-10-12 14:48:49 +02:00
" FULL OUTER JOIN fees ON (FALSE); " ) ,
2022-03-27 10:32:28 +02:00
/* Used in #postgres_create_aggregation_transient() */
GNUNET_PQ_make_prepare (
" create_aggregation_transient " ,
" INSERT INTO aggregation_transient "
" (amount_val "
" ,amount_frac "
2022-08-11 23:35:33 +02:00
" ,merchant_pub "
2022-03-27 10:32:28 +02:00
" ,wire_target_h_payto "
2022-08-20 21:29:29 +02:00
" ,legitimization_requirement_serial_id "
2022-03-27 10:32:28 +02:00
" ,exchange_account_section "
" ,wtid_raw) "
2022-10-12 14:48:49 +02:00
" VALUES ($1, $2, $3, $4, $5, $6, $7); " ) ,
2022-03-27 10:32:28 +02:00
/* Used in #postgres_select_aggregation_transient() */
GNUNET_PQ_make_prepare (
" select_aggregation_transient " ,
" SELECT "
" amount_val "
" ,amount_frac "
" ,wtid_raw "
" FROM aggregation_transient "
" WHERE wire_target_h_payto=$1 "
2022-08-11 23:35:33 +02:00
" AND merchant_pub=$2 "
2022-10-12 14:48:49 +02:00
" AND exchange_account_section=$3; " ) ,
2022-08-11 23:35:33 +02:00
/* Used in #postgres_find_aggregation_transient() */
GNUNET_PQ_make_prepare (
" find_transient_aggregations " ,
" SELECT "
" amount_val "
" ,amount_frac "
" ,wtid_raw "
" ,merchant_pub "
" ,payto_uri "
" FROM aggregation_transient atr "
" JOIN wire_targets wt USING (wire_target_h_payto) "
2022-10-12 14:48:49 +02:00
" WHERE atr.wire_target_h_payto=$1; " ) ,
2022-03-27 10:32:28 +02:00
/* Used in #postgres_update_aggregation_transient() */
GNUNET_PQ_make_prepare (
" update_aggregation_transient " ,
" UPDATE aggregation_transient "
" SET amount_val=$1 "
" ,amount_frac=$2 "
2022-08-20 21:29:29 +02:00
" ,legitimization_requirement_serial_id=$5 "
2022-03-27 10:32:28 +02:00
" WHERE wire_target_h_payto=$3 "
2022-10-12 14:48:49 +02:00
" AND wtid_raw=$4 " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_lookup_wire_transfer */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" lookup_transactions " ,
" SELECT "
" aggregation_serial_id "
" ,deposits.h_contract_terms "
" ,payto_uri "
2022-03-03 23:52:08 +01:00
" ,wire_targets.wire_target_h_payto "
2021-10-31 13:27:50 +01:00
" ,kc.coin_pub "
" ,deposits.merchant_pub "
" ,wire_out.execution_date "
" ,deposits.amount_with_fee_val "
" ,deposits.amount_with_fee_frac "
" ,denom.fee_deposit_val "
" ,denom.fee_deposit_frac "
" ,denom.denom_pub "
" FROM aggregation_tracking "
" JOIN deposits "
" USING (deposit_serial_id) "
" JOIN wire_targets "
2022-03-03 23:52:08 +01:00
" USING (wire_target_h_payto) "
2021-10-31 13:27:50 +01:00
" JOIN known_coins kc "
2022-03-18 01:57:39 +01:00
" USING (coin_pub) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denom "
" USING (denominations_serial) "
" JOIN wire_out "
" USING (wtid_raw) "
2022-10-12 14:48:49 +02:00
" WHERE wtid_raw=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_lookup_transfer_by_deposit */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" lookup_deposit_wtid " ,
" SELECT "
" aggregation_tracking.wtid_raw "
" ,wire_out.execution_date "
2022-03-18 15:40:24 +01:00
" ,dep.amount_with_fee_val "
" ,dep.amount_with_fee_frac "
" ,dep.wire_salt "
" ,wt.payto_uri "
2021-10-31 13:27:50 +01:00
" ,denom.fee_deposit_val "
" ,denom.fee_deposit_frac "
2022-03-24 17:33:29 +01:00
" FROM deposits dep "
2022-03-18 15:40:24 +01:00
" JOIN wire_targets wt "
2022-03-03 23:52:08 +01:00
" USING (wire_target_h_payto) "
2021-10-31 13:27:50 +01:00
" JOIN aggregation_tracking "
" USING (deposit_serial_id) "
2022-03-18 15:40:24 +01:00
" JOIN known_coins kc "
2022-03-24 17:33:29 +01:00
" ON (kc.coin_pub = dep.coin_pub) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denom "
" USING (denominations_serial) "
" JOIN wire_out "
" USING (wtid_raw) "
2022-03-24 17:33:29 +01:00
" WHERE dep.coin_pub=$1 "
2022-03-18 15:40:24 +01:00
" AND dep.merchant_pub=$3 "
2022-10-12 14:48:49 +02:00
" AND dep.h_contract_terms=$2 " ) ,
2022-11-14 05:08:11 +01:00
2021-08-13 22:35:13 +02:00
/* Used in #postgres_get_wire_fee() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" 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 "
2022-10-12 14:48:49 +02:00
" AND end_date > $2; " ) ,
2022-03-05 17:14:32 +01:00
/* Used in #postgres_get_global_fee() */
GNUNET_PQ_make_prepare (
" 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 "
2022-10-12 14:48:49 +02:00
" AND end_date > $1; " ) ,
2022-03-20 09:44:42 +01:00
/* Used in #postgres_get_global_fees() */
GNUNET_PQ_make_prepare (
" get_global_fees " ,
" 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 "
2022-10-12 14:48:49 +02:00
" WHERE start_date >= $1 " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_insert_wire_fee */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_wire_fee " ,
" INSERT INTO wire_fee "
" (wire_method "
" ,start_date "
" ,end_date "
" ,wire_fee_val "
" ,wire_fee_frac "
" ,closing_fee_val "
" ,closing_fee_frac "
" ,master_sig "
" ) VALUES "
2022-11-01 16:43:59 +01:00
" ($1, $2, $3, $4, $5, $6, $7, $8); " ) ,
2022-03-05 17:14:32 +01:00
/* Used in #postgres_insert_global_fee */
GNUNET_PQ_make_prepare (
" insert_global_fee " ,
" INSERT INTO global_fee "
" (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 "
" ) VALUES "
2022-11-01 16:43:59 +01:00
" ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_store_wire_transfer_out */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_wire_out " ,
" INSERT INTO wire_out "
" (execution_date "
" ,wtid_raw "
2022-03-03 23:52:08 +01:00
" ,wire_target_h_payto "
2021-10-31 13:27:50 +01:00
" ,exchange_account_section "
" ,amount_val "
" ,amount_frac "
" ) VALUES "
2022-10-12 14:48:49 +02:00
" ($1, $2, $3, $4, $5, $6); " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_wire_prepare_data_insert() to store
wire transfer information before actually committing it with the bank */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" wire_prepare_data_insert " ,
" INSERT INTO prewire "
2021-12-25 13:56:33 +01:00
" (wire_method "
2021-10-31 13:27:50 +01:00
" ,buf "
" ) VALUES "
2022-10-12 14:48:49 +02:00
" ($1, $2); " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_wire_prepare_data_mark_finished() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" wire_prepare_data_mark_done " ,
" UPDATE prewire "
" SET finished=TRUE "
2022-10-12 14:48:49 +02:00
" WHERE prewire_uuid=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_wire_prepare_data_mark_failed() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" wire_prepare_data_mark_failed " ,
" UPDATE prewire "
" SET failed=TRUE "
2022-10-12 14:48:49 +02:00
" WHERE prewire_uuid=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_wire_prepare_data_get() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" wire_prepare_data_get " ,
" SELECT "
" prewire_uuid "
2021-12-25 13:56:33 +01:00
" ,wire_method "
2021-10-31 13:27:50 +01:00
" ,buf "
" FROM prewire "
" WHERE prewire_uuid >= $1 "
" AND finished=FALSE "
" AND failed=FALSE "
" ORDER BY prewire_uuid ASC "
2022-10-12 14:48:49 +02:00
" LIMIT $2; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_select_deposits_missing_wire */
2022-03-18 08:54:08 +01:00
// FIXME: used by the auditor; can probably be done
2022-03-27 14:34:44 +02:00
// smarter by checking if 'done' or 'blocked'
2022-03-18 08:54:08 +01:00
// are set correctly when going over deposits, instead
// of JOINing with refunds.
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" deposits_get_overdue " ,
" SELECT "
" deposit_serial_id "
" ,coin_pub "
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
" ,payto_uri "
" ,wire_deadline "
" ,done "
" FROM deposits d "
" JOIN known_coins "
2022-03-18 01:57:39 +01:00
" USING (coin_pub) "
2021-10-31 13:27:50 +01:00
" JOIN wire_targets "
2022-03-03 23:52:08 +01:00
" USING (wire_target_h_payto) "
2021-10-31 13:27:50 +01:00
" WHERE wire_deadline >= $1 "
" AND wire_deadline < $2 "
" AND NOT (EXISTS (SELECT 1 "
2022-03-26 10:46:37 +01:00
" FROM refunds r "
" WHERE (r.coin_pub = d.coin_pub) AND (r.deposit_serial_id = d.deposit_serial_id)) "
2021-10-31 13:27:50 +01:00
" OR EXISTS (SELECT 1 "
" FROM aggregation_tracking "
" WHERE (aggregation_tracking.deposit_serial_id = d.deposit_serial_id))) "
2022-10-12 14:48:49 +02:00
" ORDER BY wire_deadline ASC " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_select_wire_out_above_serial_id() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" audit_get_wire_incr " ,
" SELECT "
" wireout_uuid "
" ,execution_date "
" ,wtid_raw "
" ,payto_uri "
" ,amount_val "
" ,amount_frac "
" FROM wire_out "
" JOIN wire_targets "
2022-03-03 23:52:08 +01:00
" USING (wire_target_h_payto) "
2021-10-31 13:27:50 +01:00
" WHERE wireout_uuid>=$1 "
2022-10-12 14:48:49 +02:00
" ORDER BY wireout_uuid ASC; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_select_wire_out_above_serial_id_by_account() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" audit_get_wire_incr_by_account " ,
" SELECT "
" wireout_uuid "
" ,execution_date "
" ,wtid_raw "
" ,payto_uri "
" ,amount_val "
" ,amount_frac "
" FROM wire_out "
" JOIN wire_targets "
2022-03-03 23:52:08 +01:00
" USING (wire_target_h_payto) "
2021-10-31 13:27:50 +01:00
" WHERE "
" wireout_uuid>=$1 "
" AND exchange_account_section=$2 "
2022-10-12 14:48:49 +02:00
" ORDER BY wireout_uuid ASC; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_select_recoup_above_serial_id() to obtain recoup transactions */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" recoup_get_incr " ,
" SELECT "
" recoup_uuid "
2021-12-25 13:56:33 +01:00
" ,recoup_timestamp "
2021-10-31 13:27:50 +01:00
" ,reserves.reserve_pub "
" ,coins.coin_pub "
" ,coin_sig "
" ,coin_blind "
" ,ro.h_blind_ev "
" ,denoms.denom_pub_hash "
" ,coins.denom_sig "
2022-03-17 14:16:19 +01:00
" ,coins.age_commitment_hash "
2021-10-31 13:27:50 +01:00
" ,denoms.denom_pub "
" ,amount_val "
" ,amount_frac "
" FROM recoup "
" JOIN known_coins coins "
2022-03-18 01:57:39 +01:00
" USING (coin_pub) "
2021-10-31 13:27:50 +01:00
" JOIN reserves_out ro "
" USING (reserve_out_serial_id) "
" JOIN reserves "
2021-12-25 13:56:33 +01:00
" USING (reserve_uuid) "
2021-10-31 13:27:50 +01:00
" JOIN denominations denoms "
" ON (coins.denominations_serial = denoms.denominations_serial) "
" WHERE recoup_uuid>=$1 "
2022-10-12 14:48:49 +02:00
" ORDER BY recoup_uuid ASC; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_select_recoup_refresh_above_serial_id() to obtain
recoup - refresh transactions */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" recoup_refresh_get_incr " ,
" SELECT "
" recoup_refresh_uuid "
2021-12-25 13:56:33 +01:00
" ,recoup_timestamp "
2021-10-31 13:27:50 +01:00
" ,old_coins.coin_pub AS old_coin_pub "
2022-03-17 14:45:12 +01:00
" ,new_coins.age_commitment_hash "
2021-10-31 13:27:50 +01:00
" ,old_denoms.denom_pub_hash AS old_denom_pub_hash "
" ,new_coins.coin_pub As coin_pub "
" ,coin_sig "
" ,coin_blind "
" ,new_denoms.denom_pub AS denom_pub "
" ,rrc.h_coin_ev AS h_blind_ev "
" ,new_denoms.denom_pub_hash "
" ,new_coins.denom_sig AS denom_sig "
" ,amount_val "
" ,amount_frac "
" FROM recoup_refresh "
" INNER JOIN refresh_revealed_coins rrc "
" USING (rrc_serial) "
" INNER JOIN refresh_commitments rfc "
" ON (rrc.melt_serial_id = rfc.melt_serial_id) "
" INNER JOIN known_coins old_coins "
2021-12-25 13:56:33 +01:00
" ON (rfc.old_coin_pub = old_coins.coin_pub) "
2021-10-31 13:27:50 +01:00
" INNER JOIN known_coins new_coins "
2022-03-18 01:57:39 +01:00
" ON (new_coins.coin_pub = recoup_refresh.coin_pub) "
2021-10-31 13:27:50 +01:00
" INNER JOIN denominations new_denoms "
" ON (new_coins.denominations_serial = new_denoms.denominations_serial) "
" INNER JOIN denominations old_denoms "
" ON (old_coins.denominations_serial = old_denoms.denominations_serial) "
" WHERE recoup_refresh_uuid>=$1 "
2022-10-12 14:48:49 +02:00
" ORDER BY recoup_refresh_uuid ASC; " ) ,
2022-02-17 15:10:14 +01:00
/* Used in #postgres_get_reserve_by_h_blind() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
2022-02-17 15:10:14 +01:00
" reserve_by_h_blind " ,
2021-10-31 13:27:50 +01:00
" SELECT "
" reserves.reserve_pub "
2021-12-25 13:56:33 +01:00
" ,reserve_out_serial_id "
2021-10-31 13:27:50 +01:00
" FROM reserves_out "
" JOIN reserves "
2021-12-25 13:56:33 +01:00
" USING (reserve_uuid) "
2022-02-17 15:10:14 +01:00
" WHERE h_blind_ev=$1 "
2022-10-12 14:48:49 +02:00
" LIMIT 1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_get_old_coin_by_h_blind() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" old_coin_by_h_blind " ,
" SELECT "
" okc.coin_pub AS old_coin_pub "
2021-12-25 13:56:33 +01:00
" ,rrc_serial "
2021-10-31 13:27:50 +01:00
" FROM refresh_revealed_coins rrc "
" JOIN refresh_commitments rcom USING (melt_serial_id) "
2021-12-25 13:56:33 +01:00
" JOIN known_coins okc ON (rcom.old_coin_pub = okc.coin_pub) "
2021-10-31 13:27:50 +01:00
" WHERE h_coin_ev=$1 "
2022-10-12 14:48:49 +02:00
" LIMIT 1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_lookup_auditor_timestamp() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" lookup_auditor_timestamp " ,
" SELECT "
" last_change "
" FROM auditors "
2022-10-12 14:48:49 +02:00
" WHERE auditor_pub=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_lookup_auditor_status() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" lookup_auditor_status " ,
" SELECT "
" auditor_url "
" ,is_active "
" FROM auditors "
2022-10-12 14:48:49 +02:00
" WHERE auditor_pub=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* Used in #postgres_lookup_wire_timestamp() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" lookup_wire_timestamp " ,
" SELECT "
" last_change "
" FROM wire_accounts "
2022-10-12 14:48:49 +02:00
" WHERE payto_uri=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_insert_auditor() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_auditor " ,
" INSERT INTO auditors "
" (auditor_pub "
" ,auditor_name "
" ,auditor_url "
" ,is_active "
" ,last_change "
" ) VALUES "
2022-10-12 14:48:49 +02:00
" ($1, $2, $3, true, $4); " ) ,
2022-11-10 16:37:28 +01:00
2021-08-13 22:35:13 +02:00
/* used in #postgres_insert_wire() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_wire " ,
" INSERT INTO wire_accounts "
" (payto_uri "
" ,master_sig "
" ,is_active "
" ,last_change "
" ) VALUES "
2022-10-12 14:48:49 +02:00
" ($1, $2, true, $3); " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_update_wire() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" update_wire " ,
" UPDATE wire_accounts "
" SET "
" is_active=$2 "
" ,last_change=$3 "
2022-10-12 14:48:49 +02:00
" WHERE payto_uri=$1 " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_update_wire() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_wire_accounts " ,
" SELECT "
" payto_uri "
" ,master_sig "
" FROM wire_accounts "
2022-10-12 14:48:49 +02:00
" WHERE is_active " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_update_wire() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_wire_fees " ,
" SELECT "
" wire_fee_val "
" ,wire_fee_frac "
" ,closing_fee_val "
" ,closing_fee_frac "
" ,start_date "
" ,end_date "
" ,master_sig "
" FROM wire_fee "
2022-10-12 14:48:49 +02:00
" WHERE wire_method=$1 " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_insert_signkey_revocation() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_signkey_revocation " ,
" INSERT INTO signkey_revocations "
" (esk_serial "
" ,master_sig "
" ) SELECT esk_serial, $2 "
" FROM exchange_sign_keys "
2022-10-12 14:48:49 +02:00
" WHERE exchange_pub=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_insert_signkey_revocation() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" lookup_signkey_revocation " ,
" SELECT "
" master_sig "
" FROM signkey_revocations "
" WHERE esk_serial= "
" (SELECT esk_serial "
" FROM exchange_sign_keys "
2022-10-12 14:48:49 +02:00
" WHERE exchange_pub=$1); " ) ,
2022-11-10 16:37:28 +01:00
2021-08-13 22:35:13 +02:00
/* used in #postgres_lookup_signing_key() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" lookup_signing_key " ,
" SELECT "
" valid_from "
" ,expire_sign "
" ,expire_legal "
" FROM exchange_sign_keys "
2022-10-12 14:48:49 +02:00
" WHERE exchange_pub=$1 " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_lookup_denomination_key() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" lookup_denomination_key " ,
" SELECT "
" valid_from "
" ,expire_withdraw "
" ,expire_deposit "
" ,expire_legal "
" ,coin_val "
" ,coin_frac "
" ,fee_withdraw_val "
" ,fee_withdraw_frac "
" ,fee_deposit_val "
" ,fee_deposit_frac "
" ,fee_refresh_val "
" ,fee_refresh_frac "
" ,fee_refund_val "
" ,fee_refund_frac "
2022-02-16 22:01:05 +01:00
" ,age_mask "
2021-10-31 13:27:50 +01:00
" FROM denominations "
2022-10-12 14:48:49 +02:00
" WHERE denom_pub_hash=$1; " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_insert_auditor_denom_sig() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" insert_auditor_denom_sig " ,
" WITH ax AS "
" (SELECT auditor_uuid "
" FROM auditors "
" WHERE auditor_pub=$1) "
" INSERT INTO auditor_denom_sigs "
" (auditor_uuid "
" ,denominations_serial "
" ,auditor_sig "
" ) SELECT ax.auditor_uuid, denominations_serial, $3 "
" FROM denominations "
" CROSS JOIN ax "
2022-10-12 14:48:49 +02:00
" WHERE denom_pub_hash=$2; " ) ,
2021-08-13 22:35:13 +02:00
/* used in #postgres_select_auditor_denom_sig() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" select_auditor_denom_sig " ,
" SELECT "
" auditor_sig "
" FROM auditor_denom_sigs "
" WHERE auditor_uuid= "
" (SELECT auditor_uuid "
" FROM auditors "
" WHERE auditor_pub=$1) "
" AND denominations_serial= "
" (SELECT denominations_serial "
" FROM denominations "
2022-10-12 14:48:49 +02:00
" WHERE denom_pub_hash=$2); " ) ,
2022-11-10 16:37:28 +01:00
2022-11-14 05:08:11 +01:00
/* Used in #postgres_begin_shard() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_open_shard " ,
" SELECT "
" start_row "
" ,end_row "
" FROM work_shards "
" WHERE job_name=$1 "
" AND completed=FALSE "
2022-05-22 14:46:23 +02:00
" AND last_attempt<$2 "
2021-10-31 13:27:50 +01:00
" ORDER BY last_attempt ASC "
2022-10-12 14:48:49 +02:00
" LIMIT 1; " ) ,
2022-11-10 16:37:28 +01:00
2021-09-03 19:08:02 +02:00
/* Used in #postgres_begin_shard() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" reclaim_shard " ,
" UPDATE work_shards "
" SET last_attempt=$2 "
" WHERE job_name=$1 "
" AND start_row=$3 "
2022-10-12 14:48:49 +02:00
" AND end_row=$4 " ) ,
2022-11-10 16:37:28 +01:00
2021-09-03 19:08:02 +02:00
/* Used in #postgres_begin_shard() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" get_last_shard " ,
" SELECT "
" end_row "
" FROM work_shards "
" WHERE job_name=$1 "
" ORDER BY end_row DESC "
2022-10-12 14:48:49 +02:00
" LIMIT 1; " ) ,
2022-11-10 16:37:28 +01:00
2022-04-14 00:00:50 +02:00
/* Used in #postgres_abort_shard() */
GNUNET_PQ_make_prepare (
" abort_shard " ,
" UPDATE work_shards "
" SET last_attempt=0 "
" WHERE job_name = $1 "
" AND start_row = $2 "
2022-10-12 14:48:49 +02:00
" AND end_row = $3; " ) ,
2021-09-03 19:08:02 +02:00
/* Used in #postgres_begin_shard() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" claim_next_shard " ,
" INSERT INTO work_shards "
" (job_name "
" ,last_attempt "
" ,start_row "
" ,end_row "
" ) VALUES "
2022-10-12 14:48:49 +02:00
" ($1, $2, $3, $4); " ) ,
2022-11-10 16:37:28 +01:00
2021-08-13 22:35:13 +02:00
/* Used in #postgres_complete_shard() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" complete_shard " ,
" UPDATE work_shards "
" SET completed=TRUE "
" WHERE job_name=$1 "
" AND start_row=$2 "
2022-10-12 14:48:49 +02:00
" AND end_row=$3 " ) ,
2021-09-03 19:08:02 +02:00
/* Used in #postgres_complete_shard() */
2021-10-31 13:27:50 +01:00
GNUNET_PQ_make_prepare (
" release_revolving_shard " ,
" UPDATE revolving_work_shards "
" SET active=FALSE "
" WHERE job_name=$1 "
" AND start_row=$2 "
2022-10-12 14:48:49 +02:00
" AND end_row=$3 " ) ,
2022-11-04 12:18:16 +01:00
/* Used in #postgres_set_extension_manifest */
2022-01-08 14:40:20 +01:00
GNUNET_PQ_make_prepare (
2022-11-04 12:18:16 +01:00
" set_extension_manifest " ,
" INSERT INTO extensions (name, manifest) VALUES ($1, $2) "
2022-01-08 19:45:00 +01:00
" ON CONFLICT (name) "
2022-11-04 12:18:16 +01:00
" DO UPDATE SET manifest=$2 " ) ,
2022-11-10 16:37:28 +01:00
2022-04-04 20:42:26 +02:00
/* Used in #postgres_select_purse_by_merge_pub */
GNUNET_PQ_make_prepare (
" select_purse_by_merge_pub " ,
" SELECT "
" purse_pub "
" ,purse_expiration "
" ,h_contract_terms "
" ,age_limit "
" ,amount_with_fee_val "
" ,amount_with_fee_frac "
" ,balance_val "
" ,balance_frac "
" ,purse_sig "
" FROM purse_requests "
2022-10-12 14:48:49 +02:00
" WHERE merge_pub=$1; " ) ,
2022-11-14 05:08:11 +01:00
2022-03-23 12:25:22 +01:00
/* Used in #postgres_do_account_merge() */
GNUNET_PQ_make_prepare (
" call_account_merge " ,
" SELECT 1 "
" FROM exchange_do_account_merge "
2022-10-12 14:48:49 +02:00
" ($1, $2, $3); " ) ,
2022-10-03 12:46:30 +02:00
2022-11-10 16:37:28 +01:00
2022-08-05 13:32:27 +02:00
/* Used in #postgres_update_kyc_requirement_by_row() */
GNUNET_PQ_make_prepare (
2022-08-20 21:29:29 +02:00
" update_legitimization_process " ,
" UPDATE legitimization_processes "
2022-08-05 13:32:27 +02:00
" SET provider_user_id=$4 "
" ,provider_legitimization_id=$5 "
2022-08-11 23:35:33 +02:00
" ,expiration_time=GREATEST(expiration_time,$6) "
2022-08-05 13:32:27 +02:00
" WHERE "
" h_payto=$3 "
2022-08-20 21:29:29 +02:00
" AND legitimization_process_serial_id=$1 "
2022-10-12 14:48:49 +02:00
" AND provider_section=$2; " ) ,
2022-08-05 14:22:08 +02:00
2021-08-13 22:35:13 +02:00
GNUNET_PQ_PREPARED_STATEMENT_END
} ;
2021-08-23 00:00:32 +02:00
ret = GNUNET_PQ_prepare_statements ( pg - > conn ,
2021-08-13 22:35:13 +02:00
ps ) ;
if ( GNUNET_OK ! = ret )
return ret ;
2021-08-23 00:00:32 +02:00
pg - > init = true ;
2021-08-13 22:35:13 +02:00
return GNUNET_OK ;
}
2015-01-08 18:37:20 +01:00
/**
2021-08-23 00:00:32 +02:00
* Connect to the database if the connection does not exist yet .
2015-01-08 18:37:20 +01:00
*
2021-08-23 00:00:32 +02:00
* @ param pg the plugin - specific state
2021-08-13 22:35:13 +02:00
* @ param skip_prepare true if we should skip prepared statement setup
2021-08-23 00:00:32 +02:00
* @ return # GNUNET_OK on success
2015-01-08 18:37:20 +01:00
*/
2022-11-14 05:08:11 +01:00
enum GNUNET_GenericReturnValue
TEH_PG_internal_setup ( struct PostgresClosure * pg ,
bool skip_prepare )
2015-01-08 18:37:20 +01:00
{
2021-08-23 00:00:32 +02:00
if ( NULL = = pg - > conn )
2015-01-08 18:37:20 +01:00
{
2018-08-10 22:30:38 +02:00
# if AUTO_EXPLAIN
2019-10-11 23:28:05 +02:00
/* Enable verbose logging to see where queries do not
properly use indices */
2018-08-10 22:30:38 +02:00
struct GNUNET_PQ_ExecuteStatement es [ ] = {
2019-05-09 12:55:09 +02:00
GNUNET_PQ_make_try_execute ( " LOAD 'auto_explain'; " ) ,
GNUNET_PQ_make_try_execute ( " SET auto_explain.log_min_duration=50; " ) ,
GNUNET_PQ_make_try_execute ( " SET auto_explain.log_timing=TRUE; " ) ,
GNUNET_PQ_make_try_execute ( " SET auto_explain.log_analyze=TRUE; " ) ,
2020-08-08 20:01:56 +02:00
/* https://wiki.postgresql.org/wiki/Serializable suggests to really
force the default to ' serializable ' if SSI is to be used . */
GNUNET_PQ_make_try_execute (
" SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE; " ) ,
2019-05-09 12:55:09 +02:00
GNUNET_PQ_make_try_execute ( " SET enable_sort=OFF; " ) ,
GNUNET_PQ_make_try_execute ( " SET enable_seqscan=OFF; " ) ,
2022-07-25 20:18:08 +02:00
GNUNET_PQ_make_try_execute ( " SET search_path TO exchange; " ) ,
2018-08-10 22:30:38 +02:00
GNUNET_PQ_EXECUTE_STATEMENT_END
} ;
2019-10-11 23:28:05 +02:00
# else
2021-12-25 13:56:33 +01:00
struct GNUNET_PQ_ExecuteStatement es [ ] = {
GNUNET_PQ_make_try_execute (
" SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE; " ) ,
GNUNET_PQ_make_try_execute ( " SET enable_sort=OFF; " ) ,
GNUNET_PQ_make_try_execute ( " SET enable_seqscan=OFF; " ) ,
GNUNET_PQ_make_try_execute ( " SET autocommit=OFF; " ) ,
2022-07-25 20:18:08 +02:00
GNUNET_PQ_make_try_execute ( " SET search_path TO exchange; " ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_EXECUTE_STATEMENT_END
} ;
2018-08-10 22:30:38 +02:00
# endif
2021-08-23 00:00:32 +02:00
struct GNUNET_PQ_Context * db_conn ;
2018-08-10 22:30:38 +02:00
2021-08-23 00:00:32 +02:00
db_conn = GNUNET_PQ_connect_with_cfg ( pg - > cfg ,
2020-02-09 16:34:40 +01:00
" exchangedb-postgres " ,
NULL ,
es ,
2021-08-13 22:35:13 +02:00
NULL ) ;
2021-08-23 00:00:32 +02:00
if ( NULL = = db_conn )
return GNUNET_SYSERR ;
2022-10-03 12:46:30 +02:00
pg - > prep_gen + + ;
2021-08-23 00:00:32 +02:00
pg - > conn = db_conn ;
2019-10-11 23:28:05 +02:00
}
2021-08-23 00:00:32 +02:00
if ( NULL = = pg - > transaction_name )
GNUNET_PQ_reconnect_if_down ( pg - > conn ) ;
if ( pg - > init )
return GNUNET_OK ;
if ( skip_prepare )
return GNUNET_OK ;
return prepare_statements ( pg ) ;
2015-01-08 18:37:20 +01:00
}
2020-01-15 15:44:24 +01:00
2015-01-08 18:37:20 +01:00
/**
2022-11-10 16:37:28 +01:00
* Register callback to be invoked on events of type @ a es .
2015-01-08 18:37:20 +01:00
*
2022-11-10 16:37:28 +01:00
* @ param cls database context to use
* @ param timeout how long until to generate a timeout event
* @ param es specification of the event to listen for
* @ param cb function to call when the event happens , possibly
* multiple times ( until cancel is invoked )
* @ param cb_cls closure for @ a cb
* @ return handle useful to cancel the listener
2015-01-08 18:37:20 +01:00
*/
2022-11-10 16:37:28 +01:00
static struct GNUNET_DB_EventHandler *
postgres_event_listen ( void * cls ,
struct GNUNET_TIME_Relative timeout ,
const struct GNUNET_DB_EventHeaderP * es ,
GNUNET_DB_EventCallback cb ,
void * cb_cls )
2015-01-08 18:37:20 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2015-01-28 22:18:53 +01:00
2022-11-10 16:37:28 +01:00
return GNUNET_PQ_event_listen ( pg - > conn ,
es ,
timeout ,
cb ,
cb_cls ) ;
2015-01-08 18:37:20 +01:00
}
2021-06-22 13:15:50 +02:00
/**
2022-11-10 16:37:28 +01:00
* Stop notifications .
2021-06-22 13:15:50 +02:00
*
2022-11-10 16:37:28 +01:00
* @ param cls the plugin ' s ` struct PostgresClosure `
* @ param eh handle to unregister .
2021-06-22 13:15:50 +02:00
*/
2022-11-10 16:37:28 +01:00
static void
postgres_event_listen_cancel ( void * cls ,
struct GNUNET_DB_EventHandler * eh )
2021-06-22 13:15:50 +02:00
{
2022-11-10 16:37:28 +01:00
( void ) cls ;
GNUNET_PQ_event_listen_cancel ( eh ) ;
2021-06-22 13:15:50 +02:00
}
2022-07-05 12:13:58 +02:00
/**
2022-11-10 16:37:28 +01:00
* Notify all that listen on @ a es of an event .
2022-07-05 12:13:58 +02:00
*
2022-11-10 16:37:28 +01:00
* @ param cls database context to use
* @ param es specification of the event to generate
* @ param extra additional event data provided
* @ param extra_size number of bytes in @ a extra
2022-07-05 12:13:58 +02:00
*/
2022-11-10 16:37:28 +01:00
static void
postgres_event_notify ( void * cls ,
const struct GNUNET_DB_EventHeaderP * es ,
const void * extra ,
size_t extra_size )
2022-07-05 12:13:58 +02:00
{
struct PostgresClosure * pg = cls ;
2022-11-10 16:37:28 +01:00
GNUNET_PQ_event_notify ( pg - > conn ,
es ,
extra ,
extra_size ) ;
2022-07-05 12:13:58 +02:00
}
2015-06-12 10:28:17 +02:00
/**
* Fetch information about a denomination key .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
2019-05-02 21:16:51 +02:00
* @ param denom_pub_hash hash of the public key used for signing coins of this denomination
2017-06-23 13:16:12 +02:00
* @ param [ out ] issue set to issue information with value , fees and other info about the coin
* @ return transaction status code
2015-06-12 10:28:17 +02:00
*/
2017-06-23 13:16:12 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_get_denomination_info (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_DenominationHashP * denom_pub_hash ,
2022-03-31 12:37:39 +02:00
struct TALER_EXCHANGEDB_DenominationKeyInformation * issue )
2015-06-12 10:28:17 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2017-06-23 13:16:12 +02:00
enum GNUNET_DB_QueryStatus qs ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2019-05-02 21:16:51 +02:00
GNUNET_PQ_query_param_auto_from_type ( denom_pub_hash ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_end
2015-06-12 10:28:17 +02:00
} ;
2017-06-23 13:16:12 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
2019-08-17 21:35:21 +02:00
& issue - > signature ) ,
2022-03-31 12:37:39 +02:00
GNUNET_PQ_result_spec_timestamp ( " valid_from " ,
& issue - > start ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_withdraw " ,
& issue - > expire_withdraw ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_deposit " ,
& issue - > expire_deposit ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_legal " ,
& issue - > expire_legal ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " coin " ,
& issue - > value ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_withdraw " ,
& issue - > fees . withdraw ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_deposit " ,
& issue - > fees . deposit ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refresh " ,
& issue - > fees . refresh ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refund " ,
& issue - > fees . refund ) ,
2022-02-16 22:01:05 +01:00
GNUNET_PQ_result_spec_uint32 ( " age_mask " ,
2022-03-02 10:59:42 +01:00
& issue - > age_mask . bits ) ,
2017-06-23 13:16:12 +02:00
GNUNET_PQ_result_spec_end
} ;
2015-06-12 10:28:17 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" denomination_get " ,
params ,
rs ) ;
2017-06-23 13:16:12 +02:00
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ! = qs )
return qs ;
2022-03-31 12:37:39 +02:00
issue - > denom_hash = * denom_pub_hash ;
2017-06-23 13:16:12 +02:00
return qs ;
2015-06-12 10:28:17 +02:00
}
2019-02-16 23:52:12 +01:00
/**
* Closure for # domination_cb_helper ( )
*/
2019-02-16 21:38:12 +01:00
struct DenomIteratorContext
{
2019-02-16 23:52:12 +01:00
/**
* Function to call with the results .
*/
2020-03-05 23:02:38 +01:00
TALER_EXCHANGEDB_DenominationCallback cb ;
2019-02-16 23:52:12 +01:00
/**
* Closure to pass to @ e cb
*/
2019-02-16 21:38:12 +01:00
void * cb_cls ;
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2019-02-16 21:38:12 +01:00
} ;
/**
* Helper function for # postgres_iterate_denomination_info ( ) .
* Calls the callback with each denomination key .
*
* @ param cls a ` struct DenomIteratorContext `
* @ param result db results
* @ param num_results number of results in @ a result
*/
static void
domination_cb_helper ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct DenomIteratorContext * dic = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = dic - > pg ;
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2019-02-16 21:38:12 +01:00
{
2022-03-31 12:37:39 +02:00
struct TALER_EXCHANGEDB_DenominationKeyInformation issue ;
2019-02-16 21:38:12 +01:00
struct TALER_DenominationPublicKey denom_pub ;
2022-02-28 16:13:24 +01:00
struct TALER_DenominationHashP denom_hash ;
2019-02-16 21:38:12 +01:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2019-08-25 16:18:24 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
& issue . signature ) ,
2022-02-28 16:13:24 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
& denom_hash ) ,
2022-03-31 12:37:39 +02:00
GNUNET_PQ_result_spec_timestamp ( " valid_from " ,
& issue . start ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_withdraw " ,
& issue . expire_withdraw ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_deposit " ,
& issue . expire_deposit ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_legal " ,
& issue . expire_legal ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " coin " ,
& issue . value ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_withdraw " ,
& issue . fees . withdraw ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_deposit " ,
& issue . fees . deposit ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refresh " ,
& issue . fees . refresh ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refund " ,
& issue . fees . refund ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
2022-02-16 22:01:05 +01:00
GNUNET_PQ_result_spec_uint32 ( " age_mask " ,
2022-03-02 10:59:42 +01:00
& issue . age_mask . bits ) ,
2019-08-25 16:18:24 +02:00
GNUNET_PQ_result_spec_end
2019-02-16 21:38:12 +01:00
} ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
return ;
}
2022-02-16 22:01:05 +01:00
/* Unfortunately we have to carry the age mask in both, the
* TALER_DenominationPublicKey and
2022-03-31 12:37:39 +02:00
* TALER_EXCHANGEDB_DenominationKeyInformation at different times .
2022-02-16 22:01:05 +01:00
* Here we use _both_ so let ' s make sure the values are the same . */
denom_pub . age_mask = issue . age_mask ;
2021-10-25 10:52:15 +02:00
TALER_denom_pub_hash ( & denom_pub ,
2022-03-31 12:37:39 +02:00
& issue . denom_hash ) ;
2022-02-28 16:13:24 +01:00
if ( 0 ! =
2022-03-31 12:37:39 +02:00
GNUNET_memcmp ( & issue . denom_hash ,
2022-02-28 16:13:24 +01:00
& denom_hash ) )
{
GNUNET_break ( 0 ) ;
}
else
{
dic - > cb ( dic - > cb_cls ,
& denom_pub ,
& issue ) ;
}
2021-10-25 10:52:15 +02:00
TALER_denom_pub_free ( & denom_pub ) ;
2019-02-16 21:38:12 +01:00
}
}
2019-02-14 13:41:46 +01:00
/**
* Fetch information about all known denomination keys .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param cb function to call on each denomination key
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_iterate_denomination_info ( void * cls ,
2020-03-05 23:02:38 +01:00
TALER_EXCHANGEDB_DenominationCallback cb ,
2019-02-14 13:41:46 +01:00
void * cb_cls )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2019-02-14 13:41:46 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_end
} ;
2019-02-16 21:38:12 +01:00
struct DenomIteratorContext dic = {
. cb = cb ,
2019-08-17 21:35:21 +02:00
. cb_cls = cb_cls ,
2021-08-23 00:00:32 +02:00
. pg = pg
2019-02-16 21:38:12 +01:00
} ;
2019-02-14 13:41:46 +01:00
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" denomination_iterate " ,
params ,
& domination_cb_helper ,
& dic ) ;
2019-02-14 13:41:46 +01:00
}
2020-12-06 21:48:31 +01:00
/**
* Closure for # dominations_cb_helper ( )
*/
struct DenomsIteratorContext
{
/**
* Function to call with the results .
*/
TALER_EXCHANGEDB_DenominationsCallback cb ;
/**
* Closure to pass to @ e cb
*/
void * cb_cls ;
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
} ;
/**
* Helper function for # postgres_iterate_denominations ( ) .
* Calls the callback with each denomination key .
*
* @ param cls a ` struct DenomsIteratorContext `
* @ param result db results
* @ param num_results number of results in @ a result
*/
static void
dominations_cb_helper ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct DenomsIteratorContext * dic = cls ;
struct PostgresClosure * pg = dic - > pg ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
2022-02-16 22:01:05 +01:00
struct TALER_EXCHANGEDB_DenominationKeyMetaData meta = { 0 } ;
struct TALER_DenominationPublicKey denom_pub = { 0 } ;
struct TALER_MasterSignatureP master_sig = { 0 } ;
2022-02-21 00:23:23 +01:00
struct TALER_DenominationHashP h_denom_pub = { 0 } ;
2021-12-05 17:16:00 +01:00
bool revoked ;
2020-12-06 21:48:31 +01:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
& master_sig ) ,
2021-12-05 17:16:00 +01:00
GNUNET_PQ_result_spec_bool ( " revoked " ,
& revoked ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " valid_from " ,
& meta . start ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_withdraw " ,
& meta . expire_withdraw ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_deposit " ,
& meta . expire_deposit ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_legal " ,
& meta . expire_legal ) ,
2020-12-06 21:48:31 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " coin " ,
& meta . value ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_withdraw " ,
2022-02-17 15:10:14 +01:00
& meta . fees . withdraw ) ,
2020-12-06 21:48:31 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_deposit " ,
2022-02-17 15:10:14 +01:00
& meta . fees . deposit ) ,
2020-12-06 21:48:31 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refresh " ,
2022-02-17 15:10:14 +01:00
& meta . fees . refresh ) ,
2020-12-06 21:48:31 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refund " ,
2022-02-17 15:10:14 +01:00
& meta . fees . refund ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
2022-02-16 22:01:05 +01:00
GNUNET_PQ_result_spec_uint32 ( " age_mask " ,
2022-03-02 10:59:42 +01:00
& meta . age_mask . bits ) ,
2020-12-06 21:48:31 +01:00
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
return ;
}
2022-02-16 22:01:05 +01:00
/* make sure the mask information is the same */
denom_pub . age_mask = meta . age_mask ;
2021-10-25 10:52:15 +02:00
TALER_denom_pub_hash ( & denom_pub ,
& h_denom_pub ) ;
2020-12-06 21:48:31 +01:00
dic - > cb ( dic - > cb_cls ,
& denom_pub ,
& h_denom_pub ,
& meta ,
& master_sig ,
2021-12-05 17:16:00 +01:00
revoked ) ;
2020-12-06 21:48:31 +01:00
GNUNET_PQ_cleanup_result ( rs ) ;
}
}
/**
2022-01-08 14:40:20 +01:00
* Function called to invoke @ a cb on every known denomination key ( revoked
* and non - revoked ) that has been signed by the master key . Runs in its own
* read - only transaction .
*
*
2020-12-06 21:48:31 +01:00
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param cb function to call on each denomination key
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_iterate_denominations ( void * cls ,
TALER_EXCHANGEDB_DenominationsCallback cb ,
void * cb_cls )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-12-06 21:48:31 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_end
} ;
struct DenomsIteratorContext dic = {
. cb = cb ,
. cb_cls = cb_cls ,
2021-08-23 00:00:32 +02:00
. pg = pg
2020-12-06 21:48:31 +01:00
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2020-12-06 21:48:31 +01:00
" select_denominations " ,
params ,
& dominations_cb_helper ,
& dic ) ;
}
/**
* Closure for # auditors_cb_helper ( )
*/
struct AuditorsIteratorContext
{
/**
* Function to call with the results .
*/
TALER_EXCHANGEDB_AuditorsCallback cb ;
/**
* Closure to pass to @ e cb
*/
void * cb_cls ;
} ;
/**
2020-12-20 17:10:09 +01:00
* Helper function for # postgres_iterate_active_auditors ( ) .
2020-12-06 21:48:31 +01:00
* Calls the callback with each auditor .
*
* @ param cls a ` struct SignkeysIteratorContext `
* @ param result db results
* @ param num_results number of results in @ a result
*/
static void
auditors_cb_helper ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct AuditorsIteratorContext * dic = cls ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
struct TALER_AuditorPublicKeyP auditor_pub ;
char * auditor_url ;
char * auditor_name ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " auditor_pub " ,
& auditor_pub ) ,
GNUNET_PQ_result_spec_string ( " auditor_url " ,
& auditor_url ) ,
GNUNET_PQ_result_spec_string ( " auditor_name " ,
& auditor_name ) ,
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
return ;
}
dic - > cb ( dic - > cb_cls ,
& auditor_pub ,
auditor_url ,
auditor_name ) ;
GNUNET_PQ_cleanup_result ( rs ) ;
}
}
/**
* Function called to invoke @ a cb on every active auditor . Disabled
2021-08-23 00:00:32 +02:00
* auditors are skipped . Runs in its own read - only transaction .
2022-01-08 14:40:20 +01:00
*
2020-12-06 21:48:31 +01:00
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param cb function to call on each active auditor
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_iterate_active_auditors ( void * cls ,
TALER_EXCHANGEDB_AuditorsCallback cb ,
void * cb_cls )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-12-06 21:48:31 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_end
} ;
struct AuditorsIteratorContext dic = {
. cb = cb ,
. cb_cls = cb_cls ,
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2020-12-06 21:48:31 +01:00
" select_auditors " ,
params ,
& auditors_cb_helper ,
& dic ) ;
}
/**
* Closure for # auditor_denoms_cb_helper ( )
*/
struct AuditorDenomsIteratorContext
{
/**
* Function to call with the results .
*/
TALER_EXCHANGEDB_AuditorDenominationsCallback cb ;
/**
* Closure to pass to @ e cb
*/
void * cb_cls ;
} ;
/**
* Helper function for # postgres_iterate_auditor_denominations ( ) .
* Calls the callback with each auditor and denomination pair .
*
* @ param cls a ` struct AuditorDenomsIteratorContext `
* @ param result db results
* @ param num_results number of results in @ a result
*/
static void
auditor_denoms_cb_helper ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct AuditorDenomsIteratorContext * dic = cls ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
struct TALER_AuditorPublicKeyP auditor_pub ;
2022-02-21 00:23:23 +01:00
struct TALER_DenominationHashP h_denom_pub ;
2020-12-06 21:48:31 +01:00
struct TALER_AuditorSignatureP auditor_sig ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " auditor_pub " ,
& auditor_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
& h_denom_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " auditor_sig " ,
& auditor_sig ) ,
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
return ;
}
dic - > cb ( dic - > cb_cls ,
& auditor_pub ,
& h_denom_pub ,
& auditor_sig ) ;
}
}
/**
* Function called to invoke @ a cb on every denomination with an active
* auditor . Disabled auditors and denominations without auditor are
2021-08-23 00:00:32 +02:00
* skipped . Runs in its own read - only transaction .
2020-12-06 21:48:31 +01:00
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param cb function to call on each active auditor
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_iterate_auditor_denominations (
void * cls ,
TALER_EXCHANGEDB_AuditorDenominationsCallback cb ,
void * cb_cls )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-12-06 21:48:31 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_end
} ;
struct AuditorDenomsIteratorContext dic = {
. cb = cb ,
. cb_cls = cb_cls ,
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2020-12-06 21:48:31 +01:00
" select_auditor_denoms " ,
params ,
& auditor_denoms_cb_helper ,
& dic ) ;
}
2015-03-05 16:16:38 +01:00
/**
* Get the summary of a reserve .
*
2015-03-20 23:51:28 +01:00
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2015-06-04 10:35:37 +02:00
* @ param [ in , out ] reserve the reserve data . The public key of the reserve should be
* set in this structure ; it is used to query the database . The balance
2015-03-05 16:31:33 +01:00
* and expiration are then filled accordingly .
2017-06-11 02:12:56 +02:00
* @ return transaction status
2015-03-05 16:16:38 +01:00
*/
2017-06-11 02:12:56 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-05 23:02:38 +01:00
postgres_reserves_get ( void * cls ,
2022-08-14 18:04:09 +02:00
struct TALER_EXCHANGEDB_Reserve * reserve )
2021-10-14 14:45:10 +02:00
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( & reserve - > pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
TALER_PQ_RESULT_SPEC_AMOUNT ( " current_balance " ,
& reserve - > balance ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " expiration_date " ,
& reserve - > expiry ) ,
GNUNET_PQ_result_spec_timestamp ( " gc_date " ,
& reserve - > gc ) ,
2021-10-14 14:45:10 +02:00
GNUNET_PQ_result_spec_end
} ;
2021-12-05 17:16:00 +01:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2022-08-14 18:04:09 +02:00
" reserves_get " ,
2021-12-05 17:16:00 +01:00
params ,
rs ) ;
2021-10-14 14:45:10 +02:00
}
2022-08-11 23:35:33 +02:00
/**
* Get the origin of funds of a reserve .
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param reserve_pub public key of the reserve
* @ param [ out ] h_payto set to hash of the wire source payto : //-URI
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_reserves_get_origin (
void * cls ,
const struct TALER_ReservePublicKeyP * reserve_pub ,
struct TALER_PaytoHashP * h_payto )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( reserve_pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " wire_source_h_payto " ,
h_payto ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" get_h_wire_source_of_reserve " ,
params ,
rs ) ;
}
/**
* Extract next KYC alert . Deletes the alert .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param trigger_type which type of alert to drain
* @ param [ out ] h_payto set to hash of payto - URI where KYC status changed
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_drain_kyc_alert ( void * cls ,
uint32_t trigger_type ,
struct TALER_PaytoHashP * h_payto )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint32 ( & trigger_type ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " h_payto " ,
h_payto ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" drain_kyc_alert " ,
params ,
rs ) ;
}
2015-03-05 18:16:32 +01:00
/**
* Updates a reserve with the data from the given reserve structure .
*
2015-03-20 23:51:28 +01:00
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2015-03-05 18:16:32 +01:00
* @ param reserve the reserve structure whose data will be used to update the
* corresponding record in the database .
2017-06-18 14:43:28 +02:00
* @ return transaction status
2015-03-05 18:16:32 +01:00
*/
2017-06-18 14:43:28 +02:00
static enum GNUNET_DB_QueryStatus
2015-06-04 10:35:37 +02:00
reserves_update ( void * cls ,
2016-03-01 15:35:04 +01:00
const struct TALER_EXCHANGEDB_Reserve * reserve )
2015-03-05 18:16:32 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & reserve - > expiry ) ,
GNUNET_PQ_query_param_timestamp ( & reserve - > gc ) ,
2015-05-16 20:33:01 +02:00
TALER_PQ_query_param_amount ( & reserve - > balance ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_auto_from_type ( & reserve - > pub ) ,
GNUNET_PQ_query_param_end
2015-03-05 18:16:32 +01:00
} ;
2017-05-14 15:44:36 +02:00
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2019-07-21 20:15:11 +02:00
" reserve_update " ,
params ) ;
2015-03-05 18:16:32 +01:00
}
2022-08-14 18:59:48 +02:00
/**
* Setup new wire target for @ a payto_uri .
*
* @ param pg the plugin - specific state
* @ param payto_uri the payto URI to check
* @ param [ out ] h_payto set to the hash of @ a payto_uri
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
setup_wire_target (
struct PostgresClosure * pg ,
const char * payto_uri ,
struct TALER_PaytoHashP * h_payto )
{
struct GNUNET_PQ_QueryParam iparams [ ] = {
GNUNET_PQ_query_param_auto_from_type ( h_payto ) ,
GNUNET_PQ_query_param_string ( payto_uri ) ,
GNUNET_PQ_query_param_end
} ;
TALER_payto_hash ( payto_uri ,
h_payto ) ;
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" insert_kyc_status " ,
iparams ) ;
}
2021-08-22 12:25:48 +02:00
/**
* Generate event notification for the reserve
* change .
*
2021-08-23 00:00:32 +02:00
* @ param pg plugin state
2021-08-22 12:25:48 +02:00
* @ param reserve_pub reserve to notfiy on
*/
static void
notify_on_reserve ( struct PostgresClosure * pg ,
const struct TALER_ReservePublicKeyP * reserve_pub )
{
struct TALER_ReserveEventP rep = {
. header . size = htons ( sizeof ( rep ) ) ,
. header . type = htons ( TALER_DBEVENT_EXCHANGE_RESERVE_INCOMING ) ,
. reserve_pub = * reserve_pub
} ;
2021-08-23 00:00:32 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_INFO ,
" Notifying on reserve! \n " ) ;
2021-08-22 12:25:48 +02:00
postgres_event_notify ( pg ,
& rep . header ,
NULL ,
0 ) ;
}
2015-03-05 18:16:32 +01:00
/**
2021-11-19 16:45:55 +01:00
* Insert an incoming transaction into reserves . New reserves are also
* created through this function . Started within the scope of an ongoing
* transaction .
2015-03-05 18:16:32 +01:00
*
2015-03-20 23:51:28 +01:00
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2015-05-13 15:57:35 +02:00
* @ param reserve_pub public key of the reserve
2015-03-05 18:16:32 +01:00
* @ param balance the amount that has to be added to the reserve
2015-07-01 00:01:21 +02:00
* @ param execution_time when was the amount added
2018-04-02 14:24:45 +02:00
* @ param sender_account_details account information for the sender ( payto : //-URL)
* @ param exchange_account_section name of the section in the configuration for the exchange ' s
* account into which the deposit was made
2020-01-11 15:19:56 +01:00
* @ param wire_ref unique reference identifying the wire transfer
2017-06-23 14:13:54 +02:00
* @ return transaction status code
2015-03-05 18:16:32 +01:00
*/
2017-06-23 14:13:54 +02:00
static enum GNUNET_DB_QueryStatus
2015-03-20 23:51:28 +01:00
postgres_reserves_in_insert ( void * cls ,
2015-05-13 20:25:02 +02:00
const struct TALER_ReservePublicKeyP * reserve_pub ,
2015-03-20 23:51:28 +01:00
const struct TALER_Amount * balance ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp execution_time ,
2018-04-02 14:24:45 +02:00
const char * sender_account_details ,
const char * exchange_account_section ,
2020-01-11 15:19:56 +01:00
uint64_t wire_ref )
2015-03-05 18:16:32 +01:00
{
2017-04-20 21:38:02 +02:00
struct PostgresClosure * pg = cls ;
2021-06-21 11:47:34 +02:00
enum GNUNET_DB_QueryStatus qs1 ;
2016-03-01 15:35:04 +01:00
struct TALER_EXCHANGEDB_Reserve reserve ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp expiry ;
struct GNUNET_TIME_Timestamp gc ;
2021-06-22 14:47:54 +02:00
uint64_t reserve_uuid ;
2015-01-29 00:09:48 +01:00
2015-05-13 15:57:35 +02:00
reserve . pub = * reserve_pub ;
2021-12-14 16:04:32 +01:00
expiry = GNUNET_TIME_absolute_to_timestamp (
GNUNET_TIME_absolute_add ( 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 ) ) ;
2021-06-19 17:11:11 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG ,
2017-06-11 17:04:54 +02:00
" Creating reserve %s with expiration in %s \n " ,
TALER_B2S ( reserve_pub ) ,
2019-08-25 16:18:24 +02:00
GNUNET_STRINGS_relative_time_to_string (
pg - > idle_reserve_expiration_time ,
GNUNET_NO ) ) ;
2021-06-21 11:47:34 +02:00
/* 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
2021-11-19 16:45:55 +01:00
the ' add ' operation needs the reserve entry as a foreign key . */
2015-03-05 18:16:32 +01:00
{
2021-01-10 18:06:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_auto_from_type ( reserve_pub ) ,
2015-05-16 20:33:01 +02:00
TALER_PQ_query_param_amount ( balance ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & expiry ) ,
GNUNET_PQ_query_param_timestamp ( & gc ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_end
2015-03-05 18:16:32 +01:00
} ;
2021-06-22 14:47:54 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " reserve_uuid " ,
& reserve_uuid ) ,
GNUNET_PQ_result_spec_end
} ;
2015-06-04 10:43:44 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG ,
" Reserve does not exist; creating a new one \n " ) ;
2021-06-21 11:47:34 +02:00
/* Note: query uses 'on conflict do nothing' */
2021-08-23 00:00:32 +02:00
qs1 = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2021-06-22 14:47:54 +02:00
" reserve_create " ,
params ,
rs ) ;
2021-06-21 11:47:34 +02:00
if ( qs1 < 0 )
return qs1 ;
2015-06-05 13:48:57 +02:00
}
2021-06-21 11:47:34 +02:00
2018-02-05 21:49:35 +01:00
/* Create new incoming transaction, "ON CONFLICT DO NOTHING"
2021-06-21 11:47:34 +02:00
is again used to guard against duplicates . */
2015-06-04 10:43:44 +02:00
{
2021-06-21 11:47:34 +02:00
enum GNUNET_DB_QueryStatus qs2 ;
2021-10-30 13:52:03 +02:00
enum GNUNET_DB_QueryStatus qs3 ;
2022-03-03 23:52:08 +01:00
struct TALER_PaytoHashP h_payto ;
2015-06-04 10:43:44 +02:00
2022-08-14 18:59:48 +02:00
qs3 = setup_wire_target ( pg ,
sender_account_details ,
& h_payto ) ;
if ( qs3 < 0 )
2021-10-30 13:52:03 +02:00
return qs3 ;
2021-12-19 13:43:33 +01:00
/* We do not have the UUID, so insert by public key */
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( & reserve . pub ) ,
GNUNET_PQ_query_param_uint64 ( & wire_ref ) ,
TALER_PQ_query_param_amount ( balance ) ,
GNUNET_PQ_query_param_string ( exchange_account_section ) ,
2022-03-03 23:52:08 +01:00
GNUNET_PQ_query_param_auto_from_type ( & h_payto ) ,
2021-12-19 13:43:33 +01:00
GNUNET_PQ_query_param_timestamp ( & execution_time ) ,
GNUNET_PQ_query_param_end
} ;
2021-06-22 14:47:54 +02:00
2021-12-19 13:43:33 +01:00
qs2 = GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" reserves_in_add_transaction " ,
params ) ;
/* qs2 could be 0 as statement used 'ON CONFLICT DO NOTHING' */
2021-06-21 11:47:34 +02:00
if ( 0 > = qs2 )
{
2021-06-22 13:15:50 +02:00
if ( ( GNUNET_DB_STATUS_SUCCESS_NO_RESULTS = = qs2 ) & &
( GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ! = qs1 ) )
{
2021-11-19 16:45:55 +01:00
/* Conflict for the transaction, but the reserve was
just now created , that should be impossible . */
2021-06-22 13:15:50 +02:00
GNUNET_break ( 0 ) ; /* should be impossible: reserve was fresh,
but transaction already known */
return GNUNET_DB_STATUS_HARD_ERROR ;
}
2021-06-21 11:47:34 +02:00
/* Transaction was already known or error. We are finished. */
return qs2 ;
}
}
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT = = qs1 )
2021-08-22 12:25:48 +02:00
{
2021-11-19 16:45:55 +01:00
/* New reserve, we are finished */
2021-08-22 12:25:48 +02:00
notify_on_reserve ( pg ,
reserve_pub ) ;
2021-11-19 16:45:55 +01:00
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ;
2021-08-22 12:25:48 +02:00
}
2021-06-21 11:47:34 +02:00
/* we were wrong with our optimistic assumption:
2021-11-19 16:45:55 +01:00
reserve did already exist , need to do an update instead */
2021-06-22 13:15:50 +02:00
{
2021-11-19 16:45:55 +01:00
/* We need to move away from 'read committed' to serializable.
Also , we know that it should be safe to commit at this point .
( We are only run in a larger transaction for performance . ) */
2021-06-22 13:15:50 +02:00
enum GNUNET_DB_QueryStatus cs ;
2022-11-14 05:08:11 +01:00
cs = TEH_PG_commit ( pg ) ;
2021-06-22 13:15:50 +02:00
if ( cs < 0 )
return cs ;
if ( GNUNET_OK ! =
2022-11-10 16:37:28 +01:00
TEH_PG_start ( pg ,
2022-11-14 05:08:11 +01:00
" reserve-update-serializable " ) )
2021-06-22 13:15:50 +02:00
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
}
2021-06-21 11:47:34 +02:00
{
enum GNUNET_DB_QueryStatus reserve_exists ;
2022-08-14 18:04:09 +02:00
reserve_exists = postgres_reserves_get ( pg ,
2021-06-21 11:47:34 +02:00
& reserve ) ;
switch ( reserve_exists )
{
case GNUNET_DB_STATUS_HARD_ERROR :
GNUNET_break ( 0 ) ;
return reserve_exists ;
case GNUNET_DB_STATUS_SOFT_ERROR :
return reserve_exists ;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
/* First we got a conflict, but then we cannot select? Very strange. */
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_SOFT_ERROR ;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
/* continued below */
break ;
2018-04-04 17:01:59 +02:00
}
2015-03-05 18:16:32 +01:00
}
2015-06-05 13:48:57 +02:00
{
2021-06-21 11:47:34 +02:00
struct TALER_EXCHANGEDB_Reserve updated_reserve ;
enum GNUNET_DB_QueryStatus qs3 ;
2015-06-05 13:48:57 +02:00
/* If the reserve already existed, we need to still update the
balance ; we do this after checking for duplication , as
otherwise we might have to actually pay the cost to roll this
back for duplicate transactions ; like this , we should virtually
2021-06-21 00:17:16 +02:00
never actually have to rollback anything . */
2015-06-05 13:48:57 +02:00
updated_reserve . pub = reserve . pub ;
2020-04-08 23:52:01 +02:00
if ( 0 >
2015-06-05 13:48:57 +02:00
TALER_amount_add ( & updated_reserve . balance ,
& reserve . balance ,
balance ) )
{
/* currency overflow or incompatible currency */
2018-04-04 17:01:59 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_ERROR ,
2015-06-05 13:48:57 +02:00
" Attempt to deposit incompatible amount into reserve \n " ) ;
2017-06-23 14:13:54 +02:00
return GNUNET_DB_STATUS_HARD_ERROR ;
2015-06-05 13:48:57 +02:00
}
2021-12-14 16:04:32 +01:00
updated_reserve . expiry = GNUNET_TIME_timestamp_max ( expiry ,
reserve . expiry ) ;
updated_reserve . gc = GNUNET_TIME_timestamp_max ( gc ,
reserve . gc ) ;
2021-08-23 00:00:32 +02:00
qs3 = reserves_update ( pg ,
2021-06-21 11:47:34 +02:00
& updated_reserve ) ;
switch ( qs3 )
{
case GNUNET_DB_STATUS_HARD_ERROR :
GNUNET_break ( 0 ) ;
return qs3 ;
case GNUNET_DB_STATUS_SOFT_ERROR :
return qs3 ;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
/* How can the UPDATE not work here? Very strange. */
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
/* continued below */
break ;
}
2017-03-14 15:36:19 +01:00
}
2021-08-22 12:25:48 +02:00
notify_on_reserve ( pg ,
reserve_pub ) ;
2021-06-22 13:15:50 +02:00
/* Go back to original transaction mode */
{
enum GNUNET_DB_QueryStatus cs ;
2022-11-08 15:21:01 +01:00
cs = TEH_PG_commit ( pg ) ;
2021-06-22 13:15:50 +02:00
if ( cs < 0 )
return cs ;
if ( GNUNET_OK ! =
2022-11-14 05:08:11 +01:00
TEH_PG_start_read_committed ( pg , " reserve-insert-continued " ) )
2021-06-22 13:15:50 +02:00
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
}
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ;
2015-03-05 18:16:32 +01:00
}
2015-01-29 00:09:48 +01:00
2015-01-28 22:18:53 +01:00
/**
2015-09-19 22:08:49 +02:00
* Locate the response for a / reserve / withdraw request under the
2015-01-28 22:18:53 +01:00
* key of the hash of the blinded message .
*
2015-03-20 23:51:28 +01:00
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2022-02-17 15:10:14 +01:00
* @ param bch hash that uniquely identifies the withdraw operation
2015-01-28 22:18:53 +01:00
* @ param collectable corresponding collectable coin ( blind signature )
* if a coin is found
2017-06-19 00:00:21 +02:00
* @ return statement execution status
2015-01-28 22:18:53 +01:00
*/
2017-06-19 00:00:21 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_get_withdraw_info (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_BlindedCoinHashP * bch ,
2020-03-07 00:28:07 +01:00
struct TALER_EXCHANGEDB_CollectableBlindcoin * collectable )
2015-01-28 22:18:53 +01:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2022-02-17 15:10:14 +01:00
GNUNET_PQ_query_param_auto_from_type ( bch ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_end
2015-01-28 22:18:53 +01:00
} ;
2017-06-19 00:00:21 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2019-05-02 21:16:51 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
& collectable - > denom_pub_hash ) ,
2021-10-31 17:56:56 +01:00
TALER_PQ_result_spec_blinded_denom_sig ( " denom_sig " ,
& collectable - > sig ) ,
2017-06-19 00:00:21 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " reserve_sig " ,
2019-08-17 21:35:21 +02:00
& collectable - > reserve_sig ) ,
2017-06-19 00:00:21 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " reserve_pub " ,
2019-08-17 21:35:21 +02:00
& collectable - > reserve_pub ) ,
2022-02-15 17:07:13 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " h_blind_ev " ,
& collectable - > h_coin_envelope ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
& collectable - > amount_with_fee ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_withdraw " ,
& collectable - > withdraw_fee ) ,
2017-06-19 00:00:21 +02:00
GNUNET_PQ_result_spec_end
} ;
2015-06-11 13:02:57 +02:00
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-06-05 21:26:27 +02:00
" get_withdraw_info " ,
params ,
rs ) ;
2015-01-28 22:18:53 +01:00
}
2022-05-01 12:45:12 +02:00
/**
* Perform reserve update as part of a batch withdraw operation , checking
* for sufficient balance . Persisting the withdrawal details is done
* separately !
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param now current time ( rounded )
* @ param reserve_pub public key of the reserve to debit
* @ param amount total amount to withdraw
* @ 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 )
* @ return query execution status
*/
static enum GNUNET_DB_QueryStatus
postgres_do_batch_withdraw (
void * cls ,
struct GNUNET_TIME_Timestamp now ,
const struct TALER_ReservePublicKeyP * reserve_pub ,
const struct TALER_Amount * amount ,
bool * found ,
bool * balance_ok ,
uint64_t * ruuid )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_TIME_Timestamp gc ;
struct GNUNET_PQ_QueryParam params [ ] = {
TALER_PQ_query_param_amount ( amount ) ,
GNUNET_PQ_query_param_auto_from_type ( reserve_pub ) ,
GNUNET_PQ_query_param_timestamp ( & now ) ,
GNUNET_PQ_query_param_timestamp ( & gc ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_bool ( " reserve_found " ,
found ) ,
GNUNET_PQ_result_spec_bool ( " balance_ok " ,
balance_ok ) ,
GNUNET_PQ_result_spec_uint64 ( " ruuid " ,
ruuid ) ,
GNUNET_PQ_result_spec_end
} ;
gc = GNUNET_TIME_absolute_to_timestamp (
GNUNET_TIME_absolute_add ( now . abs_time ,
pg - > legal_reserve_expiration_time ) ) ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" call_batch_withdraw " ,
params ,
rs ) ;
}
2015-01-29 00:09:48 +01:00
/**
2022-02-12 10:33:23 +01:00
* Compute the shard number of a given @ a merchant_pub .
2021-12-25 13:56:33 +01:00
*
2022-02-12 10:33:23 +01:00
* @ param merchant_pub merchant public key to compute shard for
2021-12-25 13:56:33 +01:00
* @ return shard number
2015-01-29 00:09:48 +01:00
*/
2021-12-25 13:56:33 +01:00
static uint64_t
compute_shard ( const struct TALER_MerchantPublicKeyP * merchant_pub )
2015-01-29 00:09:48 +01:00
{
2021-12-25 13:56:33 +01:00
uint32_t res ;
2017-06-18 22:48:54 +02:00
2021-12-25 13:56:33 +01:00
GNUNET_assert ( GNUNET_YES = =
GNUNET_CRYPTO_kdf ( & res ,
sizeof ( res ) ,
merchant_pub ,
sizeof ( * merchant_pub ) ,
" VOID " ,
4 ,
NULL , 0 ) ) ;
/* interpret hash result as NBO for platform independence,
convert to HBO and map to [ 0. .2 ^ 31 - 1 ] range */
res = ntohl ( res ) ;
if ( res > INT32_MAX )
res + = INT32_MIN ;
GNUNET_assert ( res < = INT32_MAX ) ;
return ( uint64_t ) res ;
}
2017-09-26 12:30:24 +02:00
2015-01-29 00:09:48 +01:00
2021-12-25 13:56:33 +01:00
/**
* Perform deposit operation , checking for sufficient balance
* of the coin and possibly persisting the deposit details .
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param deposit deposit operation details
* @ param known_coin_id row of the coin in the known_coins table
2022-02-12 10:33:23 +01:00
* @ param h_payto hash of the merchant ' s bank account details
2022-11-04 12:58:03 +01:00
* @ param policy_details_serial_id pointer to the ID of the entry in policy_details , maybe NULL
2021-12-25 13:56:33 +01:00
* @ param [ in , out ] exchange_timestamp time to use for the deposit ( possibly updated )
* @ param [ out ] balance_ok set to true if the balance was sufficient
* @ param [ out ] in_conflict set to true if the deposit conflicted
* @ return query execution status
*/
static enum GNUNET_DB_QueryStatus
postgres_do_deposit (
void * cls ,
const struct TALER_EXCHANGEDB_Deposit * deposit ,
uint64_t known_coin_id ,
2022-02-21 00:23:23 +01:00
const struct TALER_PaytoHashP * h_payto ,
2022-11-04 12:18:16 +01:00
uint64_t * policy_details_serial_id ,
2021-12-25 13:56:33 +01:00
struct GNUNET_TIME_Timestamp * exchange_timestamp ,
bool * balance_ok ,
bool * in_conflict )
{
struct PostgresClosure * pg = cls ;
uint64_t deposit_shard = compute_shard ( & deposit - > merchant_pub ) ;
struct GNUNET_PQ_QueryParam params [ ] = {
TALER_PQ_query_param_amount ( & deposit - > amount_with_fee ) ,
GNUNET_PQ_query_param_auto_from_type ( & deposit - > h_contract_terms ) ,
GNUNET_PQ_query_param_auto_from_type ( & deposit - > wire_salt ) ,
GNUNET_PQ_query_param_timestamp ( & deposit - > timestamp ) ,
GNUNET_PQ_query_param_timestamp ( exchange_timestamp ) ,
GNUNET_PQ_query_param_timestamp ( & deposit - > refund_deadline ) ,
GNUNET_PQ_query_param_timestamp ( & deposit - > wire_deadline ) ,
GNUNET_PQ_query_param_auto_from_type ( & deposit - > merchant_pub ) ,
GNUNET_PQ_query_param_string ( deposit - > receiver_wire_account ) ,
GNUNET_PQ_query_param_auto_from_type ( h_payto ) ,
GNUNET_PQ_query_param_uint64 ( & known_coin_id ) ,
GNUNET_PQ_query_param_auto_from_type ( & deposit - > coin . coin_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( & deposit - > csig ) ,
GNUNET_PQ_query_param_uint64 ( & deposit_shard ) ,
2022-11-04 12:18:16 +01:00
GNUNET_PQ_query_param_bool ( deposit - > has_policy ) ,
( NULL = = policy_details_serial_id )
2021-12-25 13:56:33 +01:00
? GNUNET_PQ_query_param_null ( )
2022-11-04 12:18:16 +01:00
: GNUNET_PQ_query_param_uint64 ( policy_details_serial_id ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_bool ( " balance_ok " ,
balance_ok ) ,
GNUNET_PQ_result_spec_bool ( " conflicted " ,
in_conflict ) ,
GNUNET_PQ_result_spec_timestamp ( " exchange_timestamp " ,
exchange_timestamp ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" call_deposit " ,
params ,
rs ) ;
}
2022-11-04 12:18:16 +01:00
/* Get the details of a policy, referenced by its hash code
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param hc The hash code under which the details to a particular policy should be found
* @ param [ out ] details The found details
* @ return query execution status
* */
static enum GNUNET_DB_QueryStatus
postgres_get_policy_details (
void * cls ,
const struct GNUNET_HashCode * hc ,
struct TALER_PolicyDetails * details )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( hc ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_timestamp ( " deadline " ,
& details - > deadline ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " commitment " ,
& details - > commitment ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " accumulated_total " ,
& details - > accumulated_total ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " policy_fee " ,
& details - > policy_fee ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " transferable_amount " ,
& details - > transferable_amount ) ,
GNUNET_PQ_result_spec_auto_from_type ( " state " ,
& details - > fulfillment_state ) ,
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_uint64 ( " policy_fulfillment_id " ,
& details - > policy_fulfillment_id ) ,
& details - > no_policy_fulfillment_id ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" get_policy_details " ,
params ,
rs ) ;
}
/* Persist the details to a policy in the policy_details table. If there
* already exists a policy , update the fields accordingly .
*
* @ param details The policy details that should be persisted . If an entry for
* the given details - > hash_code exists , the values will be updated .
* @ param [ out ] policy_details_serial_id The row ID of the policy details
* @ param [ out ] accumulated_total The total amount accumulated in that policy
* @ param [ out ] fulfillment_state The state of policy . If the state was Insufficient prior to the call and the provided deposit raises the accumulated_total above the commitment , it will be set to Ready .
* @ return query execution status
*/
static enum GNUNET_DB_QueryStatus
postgres_persist_policy_details (
void * cls ,
const struct TALER_PolicyDetails * details ,
uint64_t * policy_details_serial_id ,
struct TALER_Amount * accumulated_total ,
enum TALER_PolicyFulfillmentState * fulfillment_state )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( & details - > hash_code ) ,
TALER_PQ_query_param_json ( details - > policy_json ) ,
GNUNET_PQ_query_param_timestamp ( & details - > deadline ) ,
TALER_PQ_query_param_amount ( & details - > commitment ) ,
TALER_PQ_query_param_amount ( & details - > accumulated_total ) ,
TALER_PQ_query_param_amount ( & details - > policy_fee ) ,
TALER_PQ_query_param_amount ( & details - > transferable_amount ) ,
GNUNET_PQ_query_param_auto_from_type ( & details - > fulfillment_state ) ,
( details - > no_policy_fulfillment_id )
? GNUNET_PQ_query_param_null ( )
: GNUNET_PQ_query_param_uint64 ( & details - > policy_fulfillment_id ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " policy_details_serial_id " ,
policy_details_serial_id ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " accumulated_total " ,
accumulated_total ) ,
GNUNET_PQ_result_spec_uint32 ( " fulfillment_state " ,
fulfillment_state ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" call_insert_or_update_policy_details " ,
params ,
rs ) ;
}
2021-12-25 13:56:33 +01:00
/**
* Perform melt operation , checking for sufficient balance
* of the coin and possibly persisting the melt details .
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2022-06-25 20:38:31 +02:00
* @ param rms client - contributed input for CS denominations that must be checked for idempotency , or NULL for non - CS withdrawals
2021-12-25 13:56:33 +01:00
* @ param [ in , out ] refresh refresh operation details ; the noreveal_index
* is set in case the coin was already melted before
* @ param known_coin_id row of the coin in the known_coins table
* @ param [ in , out ] zombie_required true if the melt must only succeed if the coin is a zombie , set to false if the requirement was satisfied
* @ param [ out ] balance_ok set to true if the balance was sufficient
* @ return query execution status
*/
static enum GNUNET_DB_QueryStatus
postgres_do_melt (
void * cls ,
2022-02-17 15:10:14 +01:00
const struct TALER_RefreshMasterSecretP * rms ,
2021-12-25 13:56:33 +01:00
struct TALER_EXCHANGEDB_Refresh * refresh ,
uint64_t known_coin_id ,
bool * zombie_required ,
bool * balance_ok )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
2022-02-17 15:10:14 +01:00
NULL = = rms
? GNUNET_PQ_query_param_null ( )
: GNUNET_PQ_query_param_auto_from_type ( rms ) ,
2021-12-25 13:56:33 +01:00
TALER_PQ_query_param_amount ( & refresh - > amount_with_fee ) ,
GNUNET_PQ_query_param_auto_from_type ( & refresh - > rc ) ,
GNUNET_PQ_query_param_auto_from_type ( & refresh - > coin . coin_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( & refresh - > coin_sig ) ,
GNUNET_PQ_query_param_uint64 ( & known_coin_id ) ,
GNUNET_PQ_query_param_uint32 ( & refresh - > noreveal_index ) ,
GNUNET_PQ_query_param_bool ( * zombie_required ) ,
GNUNET_PQ_query_param_end
} ;
bool is_null ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_bool ( " balance_ok " ,
balance_ok ) ,
GNUNET_PQ_result_spec_bool ( " zombie_required " ,
zombie_required ) ,
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_uint32 ( " noreveal_index " ,
& refresh - > noreveal_index ) ,
& is_null ) ,
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_DB_QueryStatus qs ;
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" call_melt " ,
params ,
rs ) ;
if ( is_null )
refresh - > noreveal_index = UINT32_MAX ; /* set to very invalid value */
return qs ;
}
/**
* Perform refund operation , checking for sufficient deposits
* of the coin and possibly persisting the refund details .
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param refund refund operation details
* @ param deposit_fee deposit fee applicable for the coin , possibly refunded
* @ param known_coin_id row of the coin in the known_coins table
* @ param [ out ] not_found set if the deposit was not found
* @ param [ out ] refund_ok set if the refund succeeded ( below deposit amount )
* @ param [ out ] gone if the merchant was already paid
* @ param [ out ] conflict set if the refund ID was re - used
* @ return query execution status
*/
static enum GNUNET_DB_QueryStatus
postgres_do_refund (
void * cls ,
const struct TALER_EXCHANGEDB_Refund * refund ,
const struct TALER_Amount * deposit_fee ,
uint64_t known_coin_id ,
bool * not_found ,
bool * refund_ok ,
bool * gone ,
bool * conflict )
{
struct PostgresClosure * pg = cls ;
uint64_t deposit_shard = compute_shard ( & refund - > details . merchant_pub ) ;
struct TALER_Amount amount_without_fee ;
struct GNUNET_PQ_QueryParam params [ ] = {
TALER_PQ_query_param_amount ( & refund - > details . refund_amount ) ,
TALER_PQ_query_param_amount ( & amount_without_fee ) ,
TALER_PQ_query_param_amount ( deposit_fee ) ,
GNUNET_PQ_query_param_auto_from_type ( & refund - > details . h_contract_terms ) ,
GNUNET_PQ_query_param_uint64 ( & refund - > details . rtransaction_id ) ,
GNUNET_PQ_query_param_uint64 ( & deposit_shard ) ,
GNUNET_PQ_query_param_uint64 ( & known_coin_id ) ,
GNUNET_PQ_query_param_auto_from_type ( & refund - > coin . coin_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( & refund - > details . merchant_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( & refund - > details . merchant_sig ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_bool ( " not_found " ,
not_found ) ,
GNUNET_PQ_result_spec_bool ( " refund_ok " ,
refund_ok ) ,
GNUNET_PQ_result_spec_bool ( " gone " ,
gone ) ,
GNUNET_PQ_result_spec_bool ( " conflict " ,
conflict ) ,
GNUNET_PQ_result_spec_end
} ;
if ( 0 >
TALER_amount_subtract ( & amount_without_fee ,
& refund - > details . refund_amount ,
& refund - > details . refund_fee ) )
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" call_refund " ,
params ,
rs ) ;
}
/**
* Perform recoup operation , checking for sufficient deposits
* of the coin and possibly persisting the recoup details .
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param reserve_pub public key of the reserve to credit
* @ param reserve_out_serial_id row in the reserves_out table justifying the recoup
* @ param coin_bks coin blinding key secret to persist
* @ param coin_pub public key of the coin being recouped
* @ param known_coin_id row of the @ a coin_pub in the known_coins table
* @ param coin_sig signature of the coin requesting the recoup
* @ param [ in , out ] recoup_timestamp recoup timestamp , set if recoup existed
* @ param [ out ] recoup_ok set if the recoup succeeded ( balance ok )
* @ param [ out ] internal_failure set on internal failures
* @ return query execution status
*/
static enum GNUNET_DB_QueryStatus
postgres_do_recoup (
void * cls ,
const struct TALER_ReservePublicKeyP * reserve_pub ,
uint64_t reserve_out_serial_id ,
const union TALER_DenominationBlindingKeyP * coin_bks ,
const struct TALER_CoinSpendPublicKeyP * coin_pub ,
uint64_t known_coin_id ,
const struct TALER_CoinSpendSignatureP * coin_sig ,
struct GNUNET_TIME_Timestamp * recoup_timestamp ,
bool * recoup_ok ,
bool * internal_failure )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_TIME_Timestamp reserve_gc
= GNUNET_TIME_relative_to_timestamp ( pg - > legal_reserve_expiration_time ) ;
struct GNUNET_TIME_Timestamp reserve_expiration
= GNUNET_TIME_relative_to_timestamp ( pg - > idle_reserve_expiration_time ) ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( reserve_pub ) ,
GNUNET_PQ_query_param_uint64 ( & reserve_out_serial_id ) ,
GNUNET_PQ_query_param_auto_from_type ( coin_bks ) ,
GNUNET_PQ_query_param_auto_from_type ( coin_pub ) ,
GNUNET_PQ_query_param_uint64 ( & known_coin_id ) ,
GNUNET_PQ_query_param_auto_from_type ( coin_sig ) ,
GNUNET_PQ_query_param_timestamp ( & reserve_gc ) ,
GNUNET_PQ_query_param_timestamp ( & reserve_expiration ) ,
GNUNET_PQ_query_param_timestamp ( recoup_timestamp ) ,
GNUNET_PQ_query_param_end
} ;
bool is_null ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_timestamp ( " recoup_timestamp " ,
recoup_timestamp ) ,
& is_null ) ,
GNUNET_PQ_result_spec_bool ( " recoup_ok " ,
recoup_ok ) ,
GNUNET_PQ_result_spec_bool ( " internal_failure " ,
internal_failure ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" call_recoup " ,
params ,
rs ) ;
}
/**
* Perform recoup - refresh operation , checking for sufficient deposits of the
* coin and possibly persisting the recoup - refresh details .
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param old_coin_pub public key of the old coin to credit
* @ param rrc_serial row in the refresh_revealed_coins table justifying the recoup - refresh
* @ param coin_bks coin blinding key secret to persist
* @ param coin_pub public key of the coin being recouped
* @ param known_coin_id row of the @ a coin_pub in the known_coins table
* @ param coin_sig signature of the coin requesting the recoup
* @ param [ in , out ] recoup_timestamp recoup timestamp , set if recoup existed
* @ param [ out ] recoup_ok set if the recoup - refresh succeeded ( balance ok )
* @ param [ out ] internal_failure set on internal failures
* @ return query execution status
*/
static enum GNUNET_DB_QueryStatus
postgres_do_recoup_refresh (
void * cls ,
const struct TALER_CoinSpendPublicKeyP * old_coin_pub ,
uint64_t rrc_serial ,
const union TALER_DenominationBlindingKeyP * coin_bks ,
const struct TALER_CoinSpendPublicKeyP * coin_pub ,
uint64_t known_coin_id ,
const struct TALER_CoinSpendSignatureP * coin_sig ,
struct GNUNET_TIME_Timestamp * recoup_timestamp ,
bool * recoup_ok ,
bool * internal_failure )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( old_coin_pub ) ,
GNUNET_PQ_query_param_uint64 ( & rrc_serial ) ,
GNUNET_PQ_query_param_auto_from_type ( coin_bks ) ,
GNUNET_PQ_query_param_auto_from_type ( coin_pub ) ,
GNUNET_PQ_query_param_uint64 ( & known_coin_id ) ,
GNUNET_PQ_query_param_auto_from_type ( coin_sig ) ,
GNUNET_PQ_query_param_timestamp ( recoup_timestamp ) ,
GNUNET_PQ_query_param_end
} ;
bool is_null ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_timestamp ( " recoup_timestamp " ,
recoup_timestamp ) ,
& is_null ) ,
GNUNET_PQ_result_spec_bool ( " recoup_ok " ,
recoup_ok ) ,
GNUNET_PQ_result_spec_bool ( " internal_failure " ,
internal_failure ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" call_recoup_refresh " ,
params ,
rs ) ;
}
2022-11-04 12:18:16 +01:00
/*
* Compares two indices into an array of hash codes according to
* GNUNET_CRYPTO_hash_cmp of the content at those index positions .
*
* Used in a call qsort_t in order to generate sorted policy_hash_codes .
*/
static int
hash_code_cmp (
const void * hc1 ,
const void * hc2 ,
void * arg )
{
size_t i1 = * ( size_t * ) hc1 ;
size_t i2 = * ( size_t * ) hc2 ;
const struct TALER_PolicyDetails * d = arg ;
return GNUNET_CRYPTO_hash_cmp ( & d [ i1 ] . hash_code ,
& d [ i2 ] . hash_code ) ;
}
/**
* Add a proof of fulfillment into the policy_fulfillments table
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2022-11-04 12:58:03 +01:00
* @ param fulfillment fullfilment transaction data to be added
2022-11-04 12:18:16 +01:00
* @ return query execution status
*/
static enum GNUNET_DB_QueryStatus
postgres_add_policy_fulfillment_proof (
void * cls ,
struct TALER_PolicyFulfillmentTransactionData * fulfillment )
{
enum GNUNET_DB_QueryStatus qs ;
struct PostgresClosure * pg = cls ;
size_t count = fulfillment - > details_count ;
struct GNUNET_HashCode hcs [ count ] ;
/* Create the sorted policy_hash_codes */
{
size_t idx [ count ] ;
for ( size_t i = 0 ; i < count ; i + + )
idx [ i ] = i ;
/* Sort the indices according to the hash codes of the corresponding
* details . */
qsort_r ( idx ,
count ,
sizeof ( size_t ) ,
hash_code_cmp ,
fulfillment - > details ) ;
/* Finally, concatenate all hash_codes in sorted order */
for ( size_t i = 0 ; i < count ; i + + )
hcs [ i ] = fulfillment - > details [ idx [ i ] ] . hash_code ;
}
/* Now, add the proof to the policy_fulfillments table, retrieve the
* record_id */
{
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_timestamp ( & fulfillment - > timestamp ) ,
TALER_PQ_query_param_json ( fulfillment - > proof ) ,
GNUNET_PQ_query_param_auto_from_type ( & fulfillment - > h_proof ) ,
GNUNET_PQ_query_param_fixed_size ( hcs ,
count * sizeof ( struct GNUNET_HashCode ) ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " fulfillment_id " ,
& fulfillment - > fulfillment_id ) ,
GNUNET_PQ_result_spec_end
} ;
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" insert_proof_into_policy_fulfillments " ,
params ,
rs ) ;
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ! = qs )
return qs ;
}
/* Now, set the states of each entry corresponding to the hash_codes in
* policy_details accordingly */
for ( size_t i = 0 ; i < count ; i + + )
{
struct TALER_PolicyDetails * pos = & fulfillment - > details [ i ] ;
{
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( & pos - > hash_code ) ,
GNUNET_PQ_query_param_timestamp ( & pos - > deadline ) ,
TALER_PQ_query_param_amount ( & pos - > commitment ) ,
TALER_PQ_query_param_amount ( & pos - > accumulated_total ) ,
TALER_PQ_query_param_amount ( & pos - > policy_fee ) ,
TALER_PQ_query_param_amount ( & pos - > transferable_amount ) ,
GNUNET_PQ_query_param_auto_from_type ( & pos - > fulfillment_state ) ,
GNUNET_PQ_query_param_end
} ;
qs = GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" update_policy_details " ,
params ) ;
if ( qs < 0 )
return qs ;
}
}
return qs ;
}
2022-03-21 02:39:36 +01:00
/**
* Get the balance of the specified reserve .
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param reserve_pub public key of the reserve
* @ param [ out ] balance set to the reserve balance
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_get_reserve_balance ( void * cls ,
const struct TALER_ReservePublicKeyP * reserve_pub ,
struct TALER_Amount * balance )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( reserve_pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
TALER_PQ_RESULT_SPEC_AMOUNT ( " current_balance " ,
balance ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" get_reserve_balance " ,
params ,
rs ) ;
}
2021-10-30 19:28:11 +02:00
/**
* Check if we have the specified deposit already in the database .
*
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
* @ param h_contract_terms contract to check for
* @ param h_wire wire hash to check for
* @ param coin_pub public key of the coin to check for
* @ param merchant merchant public key to check for
* @ param refund_deadline expected refund deadline
* @ param [ out ] deposit_fee set to the deposit fee the exchange charged
* @ param [ out ] exchange_timestamp set to the time when the exchange received the deposit
* @ return 1 if we know this operation ,
* 0 if this exact deposit is unknown to us ,
* otherwise transaction error status
*/
static enum GNUNET_DB_QueryStatus
postgres_have_deposit2 (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_PrivateContractHashP * h_contract_terms ,
const struct TALER_MerchantWireHashP * h_wire ,
2021-10-30 19:28:11 +02:00
const struct TALER_CoinSpendPublicKeyP * coin_pub ,
const struct TALER_MerchantPublicKeyP * merchant ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp refund_deadline ,
2021-10-30 19:28:11 +02:00
struct TALER_Amount * deposit_fee ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp * exchange_timestamp )
2021-10-30 19:28:11 +02:00
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( coin_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( h_contract_terms ) ,
GNUNET_PQ_query_param_auto_from_type ( merchant ) ,
GNUNET_PQ_query_param_end
} ;
struct TALER_EXCHANGEDB_Deposit deposit2 ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
& deposit2 . amount_with_fee ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " wallet_timestamp " ,
& deposit2 . timestamp ) ,
GNUNET_PQ_result_spec_timestamp ( " exchange_timestamp " ,
exchange_timestamp ) ,
GNUNET_PQ_result_spec_timestamp ( " refund_deadline " ,
& deposit2 . refund_deadline ) ,
GNUNET_PQ_result_spec_timestamp ( " wire_deadline " ,
& deposit2 . wire_deadline ) ,
2021-10-30 19:28:11 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_deposit " ,
deposit_fee ) ,
GNUNET_PQ_result_spec_auto_from_type ( " wire_salt " ,
& deposit2 . wire_salt ) ,
GNUNET_PQ_result_spec_string ( " receiver_wire_account " ,
& deposit2 . receiver_wire_account ) ,
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_DB_QueryStatus qs ;
2022-02-21 00:23:23 +01:00
struct TALER_MerchantWireHashP h_wire2 ;
2021-10-30 19:28:11 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG ,
" Getting deposits for coin %s \n " ,
TALER_B2S ( coin_pub ) ) ;
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" get_deposit " ,
params ,
rs ) ;
if ( 0 > = qs )
return qs ;
TALER_merchant_wire_signature_hash ( deposit2 . receiver_wire_account ,
& deposit2 . wire_salt ,
& h_wire2 ) ;
GNUNET_free ( deposit2 . receiver_wire_account ) ;
/* Now we check that the other information in @a deposit
also matches , and if not report inconsistencies . */
2021-12-14 16:04:32 +01:00
if ( ( GNUNET_TIME_timestamp_cmp ( refund_deadline ,
! = ,
deposit2 . refund_deadline ) ) | |
2021-10-30 19:28:11 +02:00
( 0 ! = GNUNET_memcmp ( h_wire ,
& h_wire2 ) ) )
2015-06-12 11:47:01 +02:00
{
2022-07-09 11:28:33 +02:00
/* Inconsistencies detected! Does not match! */
2021-10-30 19:28:11 +02:00
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ;
2015-01-28 22:18:53 +01:00
}
2021-10-30 19:28:11 +02:00
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ;
2015-01-28 22:18:53 +01:00
}
2022-03-27 10:32:28 +02:00
/**
* Aggregate all matching deposits for @ a h_payto and
* @ a merchant_pub , returning the total amounts .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param h_payto destination of the wire transfer
* @ param merchant_pub public key of the merchant
* @ param wtid wire transfer ID to set for the aggregate
* @ param [ out ] total set to the sum of the total deposits minus applicable deposit fees and refunds
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_aggregate (
void * cls ,
const struct TALER_PaytoHashP * h_payto ,
const struct TALER_MerchantPublicKeyP * merchant_pub ,
const struct TALER_WireTransferIdentifierRawP * wtid ,
struct TALER_Amount * total )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_TIME_Absolute now = { 0 } ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_absolute_time ( & now ) ,
GNUNET_PQ_query_param_auto_from_type ( merchant_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( h_payto ) ,
GNUNET_PQ_query_param_auto_from_type ( wtid ) ,
GNUNET_PQ_query_param_end
} ;
uint64_t sum_deposit_value ;
uint64_t sum_deposit_frac ;
uint64_t sum_refund_value ;
uint64_t sum_refund_frac ;
uint64_t sum_fee_value ;
uint64_t sum_fee_frac ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " sum_deposit_value " ,
& sum_deposit_value ) ,
GNUNET_PQ_result_spec_uint64 ( " sum_deposit_fraction " ,
& sum_deposit_frac ) ,
GNUNET_PQ_result_spec_uint64 ( " sum_refund_value " ,
& sum_refund_value ) ,
GNUNET_PQ_result_spec_uint64 ( " sum_refund_fraction " ,
& sum_refund_frac ) ,
GNUNET_PQ_result_spec_uint64 ( " sum_fee_value " ,
& sum_fee_value ) ,
GNUNET_PQ_result_spec_uint64 ( " sum_fee_fraction " ,
& sum_fee_frac ) ,
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_DB_QueryStatus qs ;
struct TALER_Amount sum_deposit ;
struct TALER_Amount sum_refund ;
struct TALER_Amount sum_fee ;
struct TALER_Amount delta ;
now = GNUNET_TIME_absolute_round_down ( GNUNET_TIME_absolute_get ( ) ,
pg - > aggregator_shift ) ;
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" aggregate " ,
params ,
rs ) ;
if ( qs < 0 )
{
2022-07-08 15:34:09 +02:00
GNUNET_break ( GNUNET_DB_STATUS_SOFT_ERROR = = qs ) ;
2022-03-27 10:32:28 +02:00
return qs ;
}
if ( GNUNET_DB_STATUS_SUCCESS_NO_RESULTS = = qs )
{
GNUNET_assert ( GNUNET_OK = =
TALER_amount_set_zero ( pg - > currency ,
total ) ) ;
return qs ;
}
GNUNET_assert ( GNUNET_OK = =
TALER_amount_set_zero ( pg - > currency ,
& sum_deposit ) ) ;
GNUNET_assert ( GNUNET_OK = =
TALER_amount_set_zero ( pg - > currency ,
& sum_refund ) ) ;
GNUNET_assert ( GNUNET_OK = =
TALER_amount_set_zero ( pg - > currency ,
& sum_fee ) ) ;
sum_deposit . value = sum_deposit_frac / TALER_AMOUNT_FRAC_BASE
+ sum_deposit_value ;
sum_deposit . fraction = sum_deposit_frac % TALER_AMOUNT_FRAC_BASE ;
sum_refund . value = sum_refund_frac / TALER_AMOUNT_FRAC_BASE
+ sum_refund_value ;
sum_refund . fraction = sum_refund_frac % TALER_AMOUNT_FRAC_BASE ;
sum_fee . value = sum_fee_frac / TALER_AMOUNT_FRAC_BASE
+ sum_fee_value ;
sum_fee . fraction = sum_fee_frac % TALER_AMOUNT_FRAC_BASE ; \
GNUNET_assert ( 0 < =
TALER_amount_subtract ( & delta ,
& sum_deposit ,
& sum_refund ) ) ;
GNUNET_assert ( 0 < =
TALER_amount_subtract ( total ,
& delta ,
& sum_fee ) ) ;
return qs ;
}
/**
* Create a new entry in the transient aggregation table .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param h_payto destination of the wire transfer
* @ param exchange_account_section exchange account to use
2022-08-11 23:50:11 +02:00
* @ param merchant_pub public key of the merchant receiving the transfer
2022-03-27 10:32:28 +02:00
* @ param wtid the raw wire transfer identifier to be used
2022-08-20 21:29:29 +02:00
* @ param kyc_requirement_row row in legitimization_requirements that need to be satisfied to continue , or 0 for none
2022-03-27 10:32:28 +02:00
* @ param total amount to be wired in the future
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_create_aggregation_transient (
void * cls ,
const struct TALER_PaytoHashP * h_payto ,
const char * exchange_account_section ,
2022-08-11 23:35:33 +02:00
const struct TALER_MerchantPublicKeyP * merchant_pub ,
2022-03-27 10:32:28 +02:00
const struct TALER_WireTransferIdentifierRawP * wtid ,
2022-08-20 21:29:29 +02:00
uint64_t kyc_requirement_row ,
2022-03-27 10:32:28 +02:00
const struct TALER_Amount * total )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
TALER_PQ_query_param_amount ( total ) ,
2022-08-11 23:35:33 +02:00
GNUNET_PQ_query_param_auto_from_type ( merchant_pub ) ,
2022-03-27 10:32:28 +02:00
GNUNET_PQ_query_param_auto_from_type ( h_payto ) ,
2022-08-20 21:29:29 +02:00
GNUNET_PQ_query_param_uint64 ( & kyc_requirement_row ) ,
2022-03-27 10:32:28 +02:00
GNUNET_PQ_query_param_string ( exchange_account_section ) ,
GNUNET_PQ_query_param_auto_from_type ( wtid ) ,
GNUNET_PQ_query_param_end
} ;
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" create_aggregation_transient " ,
params ) ;
}
/**
* Find existing entry in the transient aggregation table .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param h_payto destination of the wire transfer
2022-08-11 23:50:11 +02:00
* @ param merchant_pub public key of the merchant receiving the transfer
2022-03-27 10:32:28 +02:00
* @ param exchange_account_section exchange account to use
* @ param [ out ] wtid set to the raw wire transfer identifier to be used
* @ param [ out ] total existing amount to be wired in the future
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_select_aggregation_transient (
void * cls ,
const struct TALER_PaytoHashP * h_payto ,
2022-08-11 23:35:33 +02:00
const struct TALER_MerchantPublicKeyP * merchant_pub ,
2022-03-27 10:32:28 +02:00
const char * exchange_account_section ,
struct TALER_WireTransferIdentifierRawP * wtid ,
struct TALER_Amount * total )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( h_payto ) ,
2022-08-11 23:35:33 +02:00
GNUNET_PQ_query_param_auto_from_type ( merchant_pub ) ,
2022-03-27 10:32:28 +02:00
GNUNET_PQ_query_param_string ( exchange_account_section ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount " ,
total ) ,
GNUNET_PQ_result_spec_auto_from_type ( " wtid_raw " ,
wtid ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" select_aggregation_transient " ,
params ,
rs ) ;
}
2022-08-11 23:35:33 +02:00
/**
* Closure for # get_refunds_cb ( ) .
*/
struct FindAggregationTransientContext
{
/**
* Function to call on each result .
*/
TALER_EXCHANGEDB_TransientAggregationCallback cb ;
/**
* Closure for @ a cb .
*/
void * cb_cls ;
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
/**
* Set to # GNUNET_SYSERR on error .
*/
enum GNUNET_GenericReturnValue status ;
} ;
/**
* Function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
* @ param cls closure of type ` struct SelectRefundContext * `
* @ param result the postgres result
* @ param num_results the number of results in @ a result
*/
static void
get_transients_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct FindAggregationTransientContext * srctx = cls ;
struct PostgresClosure * pg = srctx - > pg ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
struct TALER_Amount amount ;
char * payto_uri ;
struct TALER_WireTransferIdentifierRawP wtid ;
struct TALER_MerchantPublicKeyP merchant_pub ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " merchant_pub " ,
& merchant_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " wtid_raw " ,
& wtid ) ,
GNUNET_PQ_result_spec_string ( " payto_uri " ,
& payto_uri ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount " ,
& amount ) ,
GNUNET_PQ_result_spec_end
} ;
bool cont ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
srctx - > status = GNUNET_SYSERR ;
return ;
}
cont = srctx - > cb ( srctx - > cb_cls ,
payto_uri ,
& wtid ,
& merchant_pub ,
& amount ) ;
GNUNET_free ( payto_uri ) ;
if ( ! cont )
break ;
}
}
/**
* Find existing entry in the transient aggregation table .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param h_payto destination of the wire transfer
* @ param cb function to call on each matching entry
* @ param cb_cls closure for @ a cb
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_find_aggregation_transient (
void * cls ,
const struct TALER_PaytoHashP * h_payto ,
TALER_EXCHANGEDB_TransientAggregationCallback cb ,
void * cb_cls )
{
struct PostgresClosure * pg = cls ;
enum GNUNET_DB_QueryStatus qs ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( h_payto ) ,
GNUNET_PQ_query_param_end
} ;
struct FindAggregationTransientContext srctx = {
. cb = cb ,
. cb_cls = cb_cls ,
. pg = pg ,
. status = GNUNET_OK
} ;
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
" find_transient_aggregations " ,
params ,
& get_transients_cb ,
& srctx ) ;
if ( GNUNET_SYSERR = = srctx . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2022-03-27 10:32:28 +02:00
/**
* Update existing entry in the transient aggregation table .
* @ a h_payto is only needed for query performance .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param h_payto destination of the wire transfer
* @ param wtid the raw wire transfer identifier to update
2022-08-20 21:29:29 +02:00
* @ param kyc_requirement_row row in legitimization_requirements that need to be satisfied to continue , or 0 for none
2022-03-27 10:32:28 +02:00
* @ param total new total amount to be wired in the future
* @ return transaction status
*/
static enum GNUNET_DB_QueryStatus
postgres_update_aggregation_transient (
void * cls ,
const struct TALER_PaytoHashP * h_payto ,
const struct TALER_WireTransferIdentifierRawP * wtid ,
2022-08-20 21:29:29 +02:00
uint64_t kyc_requirement_row ,
2022-03-27 10:32:28 +02:00
const struct TALER_Amount * total )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
TALER_PQ_query_param_amount ( total ) ,
GNUNET_PQ_query_param_auto_from_type ( h_payto ) ,
GNUNET_PQ_query_param_auto_from_type ( wtid ) ,
2022-08-20 21:29:29 +02:00
GNUNET_PQ_query_param_uint64 ( & kyc_requirement_row ) ,
2022-03-27 10:32:28 +02:00
GNUNET_PQ_query_param_end
} ;
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" update_aggregation_transient " ,
params ) ;
}
2016-01-27 16:42:24 +01:00
/**
2021-11-07 11:41:53 +01:00
* Obtain information about deposits that are ready to be executed . Such
2022-03-27 14:34:44 +02:00
* deposits must not be marked as " done " , the execution time must be
2021-11-07 11:41:53 +01:00
* in the past , and the KYC status must be ' ok ' .
2016-01-27 16:42:24 +01:00
*
* @ param cls the @ e cls of this struct with the plugin - specific state
2021-09-03 19:08:02 +02:00
* @ param start_shard_row minimum shard row to select
* @ param end_shard_row maximum shard row to select ( inclusive )
2022-03-27 13:48:25 +02:00
* @ param [ out ] merchant_pub set to the public key of a merchant with a ready deposit
* @ param [ out ] payto_uri set to the account of the merchant , to be freed by caller
2017-06-24 12:15:11 +02:00
* @ return transaction status code
2015-09-19 20:28:37 +02:00
*/
2017-06-24 12:15:11 +02:00
static enum GNUNET_DB_QueryStatus
2016-01-27 16:42:24 +01:00
postgres_get_ready_deposit ( void * cls ,
2021-10-31 15:32:20 +01:00
uint64_t start_shard_row ,
uint64_t end_shard_row ,
2022-03-27 13:48:25 +02:00
struct TALER_MerchantPublicKeyP * merchant_pub ,
char * * payto_uri )
2015-09-19 20:28:37 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2022-01-08 14:40:20 +01:00
struct GNUNET_TIME_Absolute now = { 0 } ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_absolute_time ( & now ) ,
2021-10-31 15:32:20 +01:00
GNUNET_PQ_query_param_uint64 ( & start_shard_row ) ,
GNUNET_PQ_query_param_uint64 ( & end_shard_row ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_end
2015-09-19 20:28:37 +02:00
} ;
2017-06-24 12:15:11 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " merchant_pub " ,
2022-03-27 13:48:25 +02:00
merchant_pub ) ,
2021-10-30 19:57:54 +02:00
GNUNET_PQ_result_spec_string ( " payto_uri " ,
2022-03-27 13:48:25 +02:00
payto_uri ) ,
2017-06-24 12:15:11 +02:00
GNUNET_PQ_result_spec_end
} ;
2015-09-19 20:28:37 +02:00
2022-03-26 09:00:19 +01:00
now = GNUNET_TIME_absolute_round_down ( GNUNET_TIME_absolute_get ( ) ,
pg - > aggregator_shift ) ;
2021-09-03 19:08:02 +02:00
GNUNET_assert ( start_shard_row < end_shard_row ) ;
2021-11-01 18:05:01 +01:00
GNUNET_assert ( end_shard_row < = INT32_MAX ) ;
2017-09-12 15:34:38 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_INFO ,
2019-08-17 21:35:21 +02:00
" Finding ready deposits by deadline %s (%llu) \n " ,
2021-12-14 16:04:32 +01:00
GNUNET_TIME_absolute2s ( now ) ,
2019-08-17 21:35:21 +02:00
( unsigned long long ) now . abs_value_us ) ;
2022-03-27 13:48:25 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" deposits_get_ready " ,
params ,
rs ) ;
2017-06-24 12:15:11 +02:00
}
2016-05-08 15:44:44 +02:00
/**
* Retrieve the record for a known coin .
*
* @ param cls the plugin closure
* @ param coin_pub the public key of the coin to search for
* @ param coin_info place holder for the returned coin information object
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2016-05-08 15:44:44 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2019-06-26 21:34:52 +02:00
postgres_get_known_coin ( void * cls ,
const struct TALER_CoinSpendPublicKeyP * coin_pub ,
struct TALER_CoinPublicInfo * coin_info )
2016-05-08 15:44:44 +02:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2016-05-08 15:44:44 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( coin_pub ) ,
GNUNET_PQ_query_param_end
} ;
2017-06-24 16:15:42 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2019-05-02 21:16:51 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
& coin_info - > denom_pub_hash ) ,
2022-02-18 02:07:38 +01:00
GNUNET_PQ_result_spec_allow_null (
2022-02-22 14:27:15 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " age_commitment_hash " ,
2022-02-18 02:07:38 +01:00
& coin_info - > h_age_commitment ) ,
2022-02-22 18:35:10 +01:00
& coin_info - > no_age_commitment ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_sig ( " denom_sig " ,
& coin_info - > denom_sig ) ,
2017-06-24 16:15:42 +02:00
GNUNET_PQ_result_spec_end
} ;
2017-09-26 12:30:24 +02:00
2018-08-10 22:30:38 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG ,
" Getting known coin data for coin %s \n " ,
TALER_B2S ( coin_pub ) ) ;
2016-05-08 15:44:44 +02:00
coin_info - > coin_pub = * coin_pub ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" get_known_coin " ,
params ,
rs ) ;
2016-05-08 15:44:44 +02:00
}
2020-01-17 12:52:24 +01:00
/**
* Retrieve the denomination of a known coin .
*
* @ param cls the plugin closure
* @ param coin_pub the public key of the coin to search for
2021-12-25 13:56:33 +01:00
* @ param [ out ] known_coin_id set to the ID of the coin in the known_coins table
2020-01-18 13:07:29 +01:00
* @ param [ out ] denom_hash where to store the hash of the coins denomination
2020-01-17 12:52:24 +01:00
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_get_coin_denomination (
void * cls ,
const struct TALER_CoinSpendPublicKeyP * coin_pub ,
2021-12-25 13:56:33 +01:00
uint64_t * known_coin_id ,
2022-02-21 00:23:23 +01:00
struct TALER_DenominationHashP * denom_hash )
2020-01-17 12:52:24 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-01-17 12:52:24 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( coin_pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
denom_hash ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_result_spec_uint64 ( " known_coin_id " ,
known_coin_id ) ,
2020-01-17 12:52:24 +01:00
GNUNET_PQ_result_spec_end
} ;
GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG ,
" Getting coin denomination of coin %s \n " ,
TALER_B2S ( coin_pub ) ) ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2020-01-17 12:52:24 +01:00
" get_coin_denomination " ,
params ,
rs ) ;
}
2018-10-28 11:38:45 +01:00
/**
* Count the number of known coins by denomination .
*
* @ param cls database connection plugin state
* @ param denom_pub_hash denomination to count by
* @ return number of coins if non - negative , otherwise an ` enum GNUNET_DB_QueryStatus `
*/
static long long
postgres_count_known_coins ( void * cls ,
2022-02-21 00:23:23 +01:00
const struct
TALER_DenominationHashP * denom_pub_hash )
2018-10-28 11:38:45 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2018-10-28 11:38:45 +01:00
uint64_t count ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( denom_pub_hash ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " count " ,
& count ) ,
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_DB_QueryStatus qs ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-06-26 20:43:08 +02:00
" count_known_coins " ,
params ,
rs ) ;
2018-10-28 11:38:45 +01:00
if ( 0 > qs )
return ( long long ) qs ;
return ( long long ) count ;
}
2017-06-24 16:15:42 +02:00
/**
* Make sure the given @ a coin is known to the database .
*
* @ param cls database connection plugin state
* @ param coin the coin that must be made known
2021-12-25 13:56:33 +01:00
* @ param [ out ] known_coin_id set to the unique row of the coin
* @ param [ out ] denom_hash set to the denomination hash of the existing
* coin ( for conflict error reporting )
2022-02-22 14:27:15 +01:00
* @ param [ out ] h_age_commitment set to the conflicting age commitment hash on conflict
2017-06-24 16:15:42 +02:00
* @ return database transaction status , non - negative on success
2017-09-26 12:30:24 +02:00
*/
2020-07-08 19:36:08 +02:00
static enum TALER_EXCHANGEDB_CoinKnownStatus
2018-08-19 16:01:57 +02:00
postgres_ensure_coin_known ( void * cls ,
2021-12-25 13:56:33 +01:00
const struct TALER_CoinPublicInfo * coin ,
uint64_t * known_coin_id ,
2022-02-21 00:23:23 +01:00
struct TALER_DenominationHashP * denom_hash ,
2022-02-22 14:27:15 +01:00
struct TALER_AgeCommitmentHash * h_age_commitment )
2017-06-24 16:15:42 +02:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2017-06-24 16:15:42 +02:00
enum GNUNET_DB_QueryStatus qs ;
2021-12-25 13:56:33 +01:00
bool existed ;
2022-02-16 22:01:05 +01:00
bool is_denom_pub_hash_null = false ;
bool is_age_hash_null = false ;
2020-12-25 08:51:56 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( & coin - > coin_pub ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_query_param_auto_from_type ( & coin - > denom_pub_hash ) ,
2022-02-17 12:23:06 +01:00
GNUNET_PQ_query_param_auto_from_type ( & coin - > h_age_commitment ) ,
2021-12-25 13:56:33 +01:00
TALER_PQ_query_param_denom_sig ( & coin - > denom_sig ) ,
2020-12-25 08:51:56 +01:00
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2021-12-25 13:56:33 +01:00
GNUNET_PQ_result_spec_bool ( " existed " ,
& existed ) ,
GNUNET_PQ_result_spec_uint64 ( " known_coin_id " ,
known_coin_id ) ,
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
denom_hash ) ,
2022-02-16 22:01:05 +01:00
& is_denom_pub_hash_null ) ,
GNUNET_PQ_result_spec_allow_null (
2022-02-22 14:27:15 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " age_commitment_hash " ,
h_age_commitment ) ,
2022-02-16 22:01:05 +01:00
& is_age_hash_null ) ,
2020-12-25 08:51:56 +01:00
GNUNET_PQ_result_spec_end
} ;
2019-08-26 03:09:38 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2021-12-25 13:56:33 +01:00
" insert_known_coin " ,
2020-12-25 08:51:56 +01:00
params ,
rs ) ;
2020-07-08 19:36:08 +02:00
switch ( qs )
2017-11-27 23:42:17 +01:00
{
2020-07-08 19:36:08 +02:00
case GNUNET_DB_STATUS_HARD_ERROR :
2021-12-08 15:18:40 +01:00
GNUNET_break ( 0 ) ;
2020-07-08 19:36:08 +02:00
return TALER_EXCHANGEDB_CKS_HARD_FAIL ;
2021-04-14 14:48:28 +02:00
case GNUNET_DB_STATUS_SOFT_ERROR :
return TALER_EXCHANGEDB_CKS_SOFT_FAIL ;
2020-07-08 19:36:08 +02:00
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
2021-12-25 13:56:33 +01:00
GNUNET_break ( 0 ) ; /* should be impossible */
2020-07-08 19:36:08 +02:00
return TALER_EXCHANGEDB_CKS_HARD_FAIL ;
2021-12-25 13:56:33 +01:00
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
if ( ! existed )
return TALER_EXCHANGEDB_CKS_ADDED ;
break ; /* continued below */
2017-06-24 16:15:42 +02:00
}
2022-02-16 22:01:05 +01:00
if ( ( ! is_denom_pub_hash_null ) & &
( 0 ! = GNUNET_memcmp ( & denom_hash - > hash ,
& coin - > denom_pub_hash . hash ) ) )
2021-12-25 13:56:33 +01:00
{
GNUNET_break_op ( 0 ) ;
2022-02-16 22:01:05 +01:00
return TALER_EXCHANGEDB_CKS_DENOM_CONFLICT ;
2021-12-25 13:56:33 +01:00
}
2022-02-16 22:01:05 +01:00
if ( ( ! is_age_hash_null ) & &
2022-02-22 14:27:15 +01:00
( 0 ! = GNUNET_memcmp ( h_age_commitment ,
2022-02-17 12:23:06 +01:00
& coin - > h_age_commitment ) ) )
2021-12-25 13:56:33 +01:00
{
2022-02-22 14:27:15 +01:00
GNUNET_break ( GNUNET_is_zero ( h_age_commitment ) ) ;
2021-12-25 13:56:33 +01:00
GNUNET_break_op ( 0 ) ;
2022-02-16 22:01:05 +01:00
return TALER_EXCHANGEDB_CKS_AGE_CONFLICT ;
2021-12-25 13:56:33 +01:00
}
2022-02-16 22:01:05 +01:00
2021-12-25 13:56:33 +01:00
return TALER_EXCHANGEDB_CKS_PRESENT ;
2021-09-03 19:08:02 +02:00
}
2015-01-28 22:18:53 +01:00
/**
2015-06-05 15:26:41 +02:00
* Insert information about deposited coin into the database .
2015-01-28 22:18:53 +01:00
*
2015-03-20 23:51:28 +01:00
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2020-05-07 20:22:02 +02:00
* @ param exchange_timestamp time the exchange received the deposit request
2015-01-28 22:18:53 +01:00
* @ param deposit deposit information to store
2017-06-18 15:13:13 +02:00
* @ return query result status
2015-01-28 22:18:53 +01:00
*/
2017-06-18 15:13:13 +02:00
static enum GNUNET_DB_QueryStatus
2015-03-20 23:51:28 +01:00
postgres_insert_deposit ( void * cls ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp exchange_timestamp ,
2016-03-01 15:35:04 +01:00
const struct TALER_EXCHANGEDB_Deposit * deposit )
2015-01-28 22:18:53 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2022-03-03 23:52:08 +01:00
struct TALER_PaytoHashP h_payto ;
2022-08-14 18:59:48 +02:00
enum GNUNET_DB_QueryStatus qs ;
2016-05-08 15:44:44 +02:00
2022-08-14 18:59:48 +02:00
qs = setup_wire_target ( pg ,
deposit - > receiver_wire_account ,
& h_payto ) ;
if ( qs < 0 )
2021-10-30 19:28:11 +02:00
return qs ;
2022-03-24 17:33:29 +01:00
if ( GNUNET_TIME_timestamp_cmp ( deposit - > wire_deadline ,
< ,
deposit - > refund_deadline ) )
{
GNUNET_break ( 0 ) ;
}
2021-10-30 19:28:11 +02:00
{
2021-12-25 13:56:33 +01:00
uint64_t shard = compute_shard ( & deposit - > merchant_pub ) ;
2021-10-30 19:28:11 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( & deposit - > coin . coin_pub ) ,
TALER_PQ_query_param_amount ( & deposit - > amount_with_fee ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & deposit - > timestamp ) ,
GNUNET_PQ_query_param_timestamp ( & deposit - > refund_deadline ) ,
GNUNET_PQ_query_param_timestamp ( & deposit - > wire_deadline ) ,
2021-10-30 19:28:11 +02:00
GNUNET_PQ_query_param_auto_from_type ( & deposit - > merchant_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( & deposit - > h_contract_terms ) ,
GNUNET_PQ_query_param_auto_from_type ( & deposit - > wire_salt ) ,
2022-03-03 23:52:08 +01:00
GNUNET_PQ_query_param_auto_from_type ( & h_payto ) ,
2021-10-30 19:28:11 +02:00
GNUNET_PQ_query_param_auto_from_type ( & deposit - > csig ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & exchange_timestamp ) ,
2021-10-31 15:32:20 +01:00
GNUNET_PQ_query_param_uint64 ( & shard ) ,
2021-10-30 19:28:11 +02:00
GNUNET_PQ_query_param_end
} ;
2021-11-01 18:05:01 +01:00
GNUNET_assert ( shard < = INT32_MAX ) ;
2021-12-14 16:04:32 +01:00
GNUNET_log (
GNUNET_ERROR_TYPE_INFO ,
" Inserting deposit to be executed at %s (%llu/%llu) \n " ,
GNUNET_TIME_timestamp2s ( deposit - > wire_deadline ) ,
( unsigned long long ) deposit - > wire_deadline . abs_time . abs_value_us ,
( unsigned long long ) deposit - > refund_deadline . abs_time . abs_value_us ) ;
2021-10-30 19:28:11 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" insert_deposit " ,
params ) ;
}
2015-01-28 14:57:55 +01:00
}
2016-05-05 22:57:55 +02:00
/**
* Insert information about refunded coin into the database .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param refund refund information to store
2017-06-18 21:47:05 +02:00
* @ return query result status
2016-05-05 22:57:55 +02:00
*/
2017-06-18 21:47:05 +02:00
static enum GNUNET_DB_QueryStatus
2016-05-05 22:57:55 +02:00
postgres_insert_refund ( void * cls ,
const struct TALER_EXCHANGEDB_Refund * refund )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2016-05-06 12:55:44 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( & refund - > coin . coin_pub ) ,
2020-01-16 23:49:34 +01:00
GNUNET_PQ_query_param_auto_from_type ( & refund - > details . merchant_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( & refund - > details . merchant_sig ) ,
GNUNET_PQ_query_param_auto_from_type ( & refund - > details . h_contract_terms ) ,
GNUNET_PQ_query_param_uint64 ( & refund - > details . rtransaction_id ) ,
TALER_PQ_query_param_amount ( & refund - > details . refund_amount ) ,
2016-05-06 12:55:44 +02:00
GNUNET_PQ_query_param_end
} ;
2017-05-25 02:06:03 +02:00
2016-05-06 12:55:44 +02:00
GNUNET_assert ( GNUNET_YES = =
2020-01-16 23:49:34 +01:00
TALER_amount_cmp_currency ( & refund - > details . refund_amount ,
& refund - > details . refund_fee ) ) ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" insert_refund " ,
params ) ;
2016-05-05 22:57:55 +02:00
}
2018-01-02 14:43:15 +01:00
/**
* Closure for # get_refunds_cb ( ) .
*/
struct SelectRefundContext
{
/**
* Function to call on each result .
*/
TALER_EXCHANGEDB_RefundCoinCallback cb ;
/**
* Closure for @ a cb .
*/
void * cb_cls ;
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2018-01-02 14:43:15 +01:00
/**
* Set to # GNUNET_SYSERR on error .
2018-01-15 15:18:00 +01:00
*/
2018-01-02 14:43:15 +01:00
int status ;
} ;
/**
* Function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
* @ param cls closure of type ` struct SelectRefundContext * `
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2018-01-02 14:43:15 +01:00
*/
static void
get_refunds_cb ( void * cls ,
2019-08-25 16:18:24 +02:00
PGresult * result ,
unsigned int num_results )
2018-01-02 14:43:15 +01:00
{
struct SelectRefundContext * srctx = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = srctx - > pg ;
2018-01-02 14:43:15 +01:00
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2018-01-02 14:43:15 +01:00
{
struct TALER_Amount amount_with_fee ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
& amount_with_fee ) ,
2018-01-02 14:43:15 +01:00
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
2019-08-17 21:35:21 +02:00
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
2018-01-02 14:43:15 +01:00
{
GNUNET_break ( 0 ) ;
srctx - > status = GNUNET_SYSERR ;
return ;
}
if ( GNUNET_OK ! =
2019-08-17 21:35:21 +02:00
srctx - > cb ( srctx - > cb_cls ,
2020-01-17 15:43:04 +01:00
& amount_with_fee ) )
2018-01-02 14:43:15 +01:00
return ;
}
}
/**
2020-01-17 15:43:04 +01:00
* Select refunds by @ a coin_pub , @ a merchant_pub and @ a h_contract .
2018-01-02 14:43:15 +01:00
*
* @ param cls closure of plugin
* @ param coin_pub coin to get refunds for
2020-01-17 15:43:04 +01:00
* @ param merchant_pub merchant to get refunds for
2020-01-18 13:23:10 +01:00
* @ param h_contract contract ( hash ) to get refunds for
2018-01-02 14:43:15 +01:00
* @ param cb function to call for each refund found
* @ param cb_cls closure for @ a cb
* @ return query result status
*/
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_refunds_by_coin (
void * cls ,
const struct TALER_CoinSpendPublicKeyP * coin_pub ,
const struct TALER_MerchantPublicKeyP * merchant_pub ,
2022-02-21 00:23:23 +01:00
const struct TALER_PrivateContractHashP * h_contract ,
2020-03-07 00:28:07 +01:00
TALER_EXCHANGEDB_RefundCoinCallback cb ,
void * cb_cls )
2018-01-02 14:43:15 +01:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2018-01-02 14:43:15 +01:00
enum GNUNET_DB_QueryStatus qs ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( coin_pub ) ,
2020-01-17 15:43:04 +01:00
GNUNET_PQ_query_param_auto_from_type ( merchant_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( h_contract ) ,
2018-01-02 14:43:15 +01:00
GNUNET_PQ_query_param_end
} ;
struct SelectRefundContext srctx = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2018-01-02 14:43:15 +01:00
. status = GNUNET_OK
} ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2020-01-17 15:43:04 +01:00
" get_refunds_by_coin_and_contract " ,
2018-01-02 14:43:15 +01:00
params ,
& get_refunds_cb ,
& srctx ) ;
if ( GNUNET_SYSERR = = srctx . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2015-01-29 20:00:21 +01:00
/**
2017-11-27 23:42:17 +01:00
* Lookup refresh melt commitment data under the given @ a rc .
2015-01-29 20:00:21 +01:00
*
2015-03-20 23:51:28 +01:00
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2017-11-27 23:42:17 +01:00
* @ param rc commitment hash to use to locate the operation
2020-02-29 16:42:10 +01:00
* @ param [ out ] melt where to store the result ; note that
* melt - > session . coin . denom_sig will be set to NULL
2019-10-11 23:28:05 +02:00
* and is not fetched by this routine ( as it is not needed by the client )
2021-12-25 13:56:33 +01:00
* @ param [ out ] melt_serial_id set to the row ID of @ a rc in the refresh_commitments table
2017-06-20 22:30:15 +02:00
* @ return transaction status
2015-01-29 20:00:21 +01:00
*/
2017-06-20 22:30:15 +02:00
static enum GNUNET_DB_QueryStatus
2017-11-27 23:42:17 +01:00
postgres_get_melt ( void * cls ,
const struct TALER_RefreshCommitmentP * rc ,
2021-12-25 13:56:33 +01:00
struct TALER_EXCHANGEDB_Melt * melt ,
uint64_t * melt_serial_id )
2015-01-29 20:00:21 +01:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2022-02-16 22:01:05 +01:00
bool h_age_commitment_is_null ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2017-11-27 23:42:17 +01:00
GNUNET_PQ_query_param_auto_from_type ( rc ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_end
2015-01-29 20:00:21 +01:00
} ;
2017-06-20 22:30:15 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2019-05-02 21:16:51 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
2020-02-29 16:42:10 +01:00
& melt - > session . coin .
2019-08-25 16:18:24 +02:00
denom_pub_hash ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refresh " ,
2020-02-29 16:42:10 +01:00
& melt - > melt_fee ) ,
2017-11-27 23:42:17 +01:00
GNUNET_PQ_result_spec_uint32 ( " noreveal_index " ,
2020-02-29 16:42:10 +01:00
& melt - > session . noreveal_index ) ,
2017-06-20 22:30:15 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " old_coin_pub " ,
2020-02-29 16:42:10 +01:00
& melt - > session . coin . coin_pub ) ,
2017-06-20 22:30:15 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " old_coin_sig " ,
2020-02-29 16:42:10 +01:00
& melt - > session . coin_sig ) ,
2022-02-16 22:01:05 +01:00
GNUNET_PQ_result_spec_allow_null (
2022-03-17 14:16:19 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " age_commitment_hash " ,
2022-02-22 14:27:15 +01:00
& melt - > session . coin . h_age_commitment ) ,
2022-02-16 22:01:05 +01:00
& h_age_commitment_is_null ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
2020-02-29 16:42:10 +01:00
& melt - > session . amount_with_fee ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_result_spec_uint64 ( " melt_serial_id " ,
melt_serial_id ) ,
2017-06-20 22:30:15 +02:00
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_DB_QueryStatus qs ;
2015-01-29 20:00:21 +01:00
2021-10-25 10:52:15 +02:00
memset ( & melt - > session . coin . denom_sig ,
0 ,
sizeof ( melt - > session . coin . denom_sig ) ) ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-08-25 16:18:24 +02:00
" get_melt " ,
params ,
rs ) ;
2022-02-16 22:01:05 +01:00
if ( h_age_commitment_is_null )
2022-02-22 14:27:15 +01:00
memset ( & melt - > session . coin . h_age_commitment ,
2022-02-16 22:01:05 +01:00
0 ,
2022-02-22 14:27:15 +01:00
sizeof ( melt - > session . coin . h_age_commitment ) ) ;
2022-02-16 22:01:05 +01:00
2020-02-29 16:42:10 +01:00
melt - > session . rc = * rc ;
2017-06-20 22:30:15 +02:00
return qs ;
2015-01-29 20:00:21 +01:00
}
2015-01-30 15:34:01 +01:00
/**
2017-11-27 23:42:17 +01:00
* Store in the database which coin ( s ) the wallet wanted to create
* in a given refresh operation and all of the other information
* we learned or created in the / refresh / reveal step .
2015-01-30 15:34:01 +01:00
*
2017-11-27 23:42:17 +01:00
* @ param cls the @ e cls of this struct with the plugin - specific state
2021-12-25 13:56:33 +01:00
* @ param melt_serial_id row ID of the commitment / melt operation in refresh_commitments
2020-01-18 13:23:10 +01:00
* @ param num_rrcs number of coins to generate , size of the @ a rrcs array
2017-11-27 23:42:17 +01:00
* @ param rrcs information about the new coins
* @ param num_tprivs number of entries in @ a tprivs , should be # TALER_CNC_KAPPA - 1
* @ param tprivs transfer private keys to store
* @ param tp public key to store
2017-06-22 11:49:40 +02:00
* @ return query status for the transaction
2015-01-30 15:34:01 +01:00
*/
2017-06-22 11:49:40 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_insert_refresh_reveal (
void * cls ,
2021-12-25 13:56:33 +01:00
uint64_t melt_serial_id ,
2020-03-07 00:28:07 +01:00
uint32_t num_rrcs ,
const struct TALER_EXCHANGEDB_RefreshRevealedCoin * rrcs ,
unsigned int num_tprivs ,
const struct TALER_TransferPrivateKeyP * tprivs ,
const struct TALER_TransferPublicKeyP * tp )
2015-01-30 15:34:01 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2017-11-27 23:42:17 +01:00
if ( TALER_CNC_KAPPA ! = num_tprivs + 1 )
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
2019-08-25 16:18:24 +02:00
for ( uint32_t i = 0 ; i < num_rrcs ; i + + )
2015-01-30 15:34:01 +01:00
{
2017-11-27 23:42:17 +01:00
const struct TALER_EXCHANGEDB_RefreshRevealedCoin * rrc = & rrcs [ i ] ;
struct GNUNET_PQ_QueryParam params [ ] = {
2021-12-25 13:56:33 +01:00
GNUNET_PQ_query_param_uint64 ( & melt_serial_id ) ,
2017-11-27 23:42:17 +01:00
GNUNET_PQ_query_param_uint32 ( & i ) ,
2019-06-26 15:34:14 +02:00
GNUNET_PQ_query_param_auto_from_type ( & rrc - > orig_coin_link_sig ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_query_param_auto_from_type ( & rrc - > h_denom_pub ) ,
2022-02-07 13:14:25 +01:00
TALER_PQ_query_param_blinded_planchet ( & rrc - > blinded_planchet ) ,
2022-02-10 23:39:00 +01:00
TALER_PQ_query_param_exchange_withdraw_values ( & rrc - > exchange_vals ) ,
2021-12-25 17:22:54 +01:00
GNUNET_PQ_query_param_auto_from_type ( & rrc - > coin_envelope_hash ) ,
2021-10-31 17:56:56 +01:00
TALER_PQ_query_param_blinded_denom_sig ( & rrc - > coin_sig ) ,
2017-11-27 23:42:17 +01:00
GNUNET_PQ_query_param_end
} ;
enum GNUNET_DB_QueryStatus qs ;
2015-06-11 14:46:03 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2017-11-27 23:42:17 +01:00
" insert_refresh_revealed_coin " ,
params ) ;
2021-12-25 13:56:33 +01:00
if ( 0 > qs )
2017-11-27 23:42:17 +01:00
return qs ;
}
{
struct GNUNET_PQ_QueryParam params [ ] = {
2021-12-25 13:56:33 +01:00
GNUNET_PQ_query_param_uint64 ( & melt_serial_id ) ,
2017-11-27 23:42:17 +01:00
GNUNET_PQ_query_param_auto_from_type ( tp ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_query_param_fixed_size (
tprivs ,
2021-12-25 15:39:01 +01:00
num_tprivs * sizeof ( struct TALER_TransferPrivateKeyP ) ) ,
2017-11-27 23:42:17 +01:00
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2017-11-27 23:42:17 +01:00
" insert_refresh_transfer_keys " ,
params ) ;
2015-01-30 15:34:01 +01:00
}
2015-06-11 14:46:03 +02:00
}
/**
2017-11-27 23:42:17 +01:00
* Context where we aggregate data from the database .
* Closure for # add_revealed_coins ( ) .
2015-06-11 14:46:03 +02:00
*/
2017-11-27 23:42:17 +01:00
struct GetRevealContext
2015-06-11 14:46:03 +02:00
{
2017-11-27 23:42:17 +01:00
/**
* Array of revealed coins we obtained from the DB .
*/
struct TALER_EXCHANGEDB_RefreshRevealedCoin * rrcs ;
2015-01-30 15:34:01 +01:00
2017-11-27 23:42:17 +01:00
/**
* Length of the @ a rrcs array .
*/
unsigned int rrcs_len ;
2015-01-30 15:34:01 +01:00
2017-11-27 23:42:17 +01:00
/**
* Set to an error code if we ran into trouble .
*/
2017-12-09 23:46:05 +01:00
enum GNUNET_DB_QueryStatus qs ;
2017-11-27 23:42:17 +01:00
} ;
2015-06-11 14:40:07 +02:00
/**
2017-11-27 23:42:17 +01:00
* Function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
2015-06-11 14:40:07 +02:00
*
2017-11-27 23:42:17 +01:00
* @ param cls closure of type ` struct GetRevealContext `
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2015-06-11 14:40:07 +02:00
*/
static void
2017-11-27 23:42:17 +01:00
add_revealed_coins ( void * cls ,
PGresult * result ,
unsigned int num_results )
2015-06-11 14:40:07 +02:00
{
2017-11-27 23:42:17 +01:00
struct GetRevealContext * grctx = cls ;
2015-01-29 20:18:04 +01:00
2017-11-27 23:42:17 +01:00
if ( 0 = = num_results )
return ;
grctx - > rrcs = GNUNET_new_array ( num_results ,
struct TALER_EXCHANGEDB_RefreshRevealedCoin ) ;
grctx - > rrcs_len = num_results ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
2015-01-29 20:18:04 +01:00
{
2017-11-27 23:42:17 +01:00
uint32_t off ;
2021-12-25 13:56:33 +01:00
struct GNUNET_PQ_ResultSpec rso [ ] = {
2020-03-05 23:49:47 +01:00
GNUNET_PQ_result_spec_uint32 ( " freshcoin_index " ,
2017-11-27 23:42:17 +01:00
& off ) ,
2017-06-20 22:30:15 +02:00
GNUNET_PQ_result_spec_end
} ;
2015-01-29 20:18:04 +01:00
2017-11-27 23:42:17 +01:00
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
2021-12-25 13:56:33 +01:00
rso ,
2017-11-27 23:42:17 +01:00
i ) )
2015-06-11 14:40:07 +02:00
{
2017-11-27 23:42:17 +01:00
GNUNET_break ( 0 ) ;
2017-12-09 23:46:05 +01:00
grctx - > qs = GNUNET_DB_STATUS_HARD_ERROR ;
2017-11-27 23:42:17 +01:00
return ;
}
2021-12-25 13:56:33 +01:00
if ( off > = num_results )
2017-11-27 23:42:17 +01:00
{
GNUNET_break ( 0 ) ;
2017-12-09 23:46:05 +01:00
grctx - > qs = GNUNET_DB_STATUS_HARD_ERROR ;
2017-11-27 23:42:17 +01:00
return ;
2015-06-11 14:40:07 +02:00
}
2021-12-25 13:56:33 +01:00
{
struct TALER_EXCHANGEDB_RefreshRevealedCoin * rrc = & grctx - > rrcs [ off ] ;
struct GNUNET_PQ_ResultSpec rsi [ ] = {
2022-02-28 16:13:24 +01:00
/* NOTE: freshcoin_index selected and discarded here... */
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
2021-12-25 13:56:33 +01:00
& rrc - > h_denom_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " link_sig " ,
& rrc - > orig_coin_link_sig ) ,
2021-12-25 15:39:01 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " h_coin_ev " ,
& rrc - > coin_envelope_hash ) ,
2022-02-07 13:14:25 +01:00
TALER_PQ_result_spec_blinded_planchet ( " coin_ev " ,
& rrc - > blinded_planchet ) ,
2022-02-10 23:39:00 +01:00
TALER_PQ_result_spec_exchange_withdraw_values ( " ewv " ,
& rrc - > exchange_vals ) ,
2021-12-25 13:56:33 +01:00
TALER_PQ_result_spec_blinded_denom_sig ( " ev_sig " ,
& rrc - > coin_sig ) ,
GNUNET_PQ_result_spec_end
} ;
2022-02-07 13:14:25 +01:00
if ( TALER_DENOMINATION_INVALID ! = rrc - > blinded_planchet . cipher )
2021-12-25 13:56:33 +01:00
{
/* duplicate offset, not allowed */
GNUNET_break ( 0 ) ;
grctx - > qs = GNUNET_DB_STATUS_HARD_ERROR ;
return ;
}
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rsi ,
i ) )
{
GNUNET_break ( 0 ) ;
grctx - > qs = GNUNET_DB_STATUS_HARD_ERROR ;
return ;
}
}
2015-01-29 20:18:04 +01:00
}
}
/**
2017-11-27 23:42:17 +01:00
* Lookup in the database the coins that we want to
* create in the given refresh operation .
2015-01-29 20:18:04 +01:00
*
2015-03-20 23:51:28 +01:00
* @ param cls the ` struct PostgresClosure ` with the plugin - specific state
2017-11-27 23:42:17 +01:00
* @ param rc identify commitment and thus refresh operation
* @ param cb function to call with the results
* @ param cb_cls closure for @ a cb
2017-06-20 22:30:15 +02:00
* @ return transaction status
2015-01-29 20:18:04 +01:00
*/
2017-06-20 22:30:15 +02:00
static enum GNUNET_DB_QueryStatus
2017-11-27 23:42:17 +01:00
postgres_get_refresh_reveal ( void * cls ,
const struct TALER_RefreshCommitmentP * rc ,
TALER_EXCHANGEDB_RefreshCallback cb ,
void * cb_cls )
2015-01-29 20:18:04 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2017-11-27 23:42:17 +01:00
struct GetRevealContext grctx ;
enum GNUNET_DB_QueryStatus qs ;
2016-05-16 11:55:47 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
2017-11-27 23:42:17 +01:00
GNUNET_PQ_query_param_auto_from_type ( rc ) ,
2016-05-16 11:55:47 +02:00
GNUNET_PQ_query_param_end
} ;
2017-09-26 12:30:24 +02:00
2017-11-27 23:42:17 +01:00
memset ( & grctx ,
0 ,
sizeof ( grctx ) ) ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2017-11-27 23:42:17 +01:00
" get_refresh_revealed_coins " ,
params ,
& add_revealed_coins ,
& grctx ) ;
switch ( qs )
{
case GNUNET_DB_STATUS_HARD_ERROR :
case GNUNET_DB_STATUS_SOFT_ERROR :
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
goto cleanup ;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
2022-01-08 14:40:20 +01:00
default : /* can have more than one result */
2017-11-27 23:42:17 +01:00
break ;
}
2017-12-09 23:46:05 +01:00
switch ( grctx . qs )
{
case GNUNET_DB_STATUS_HARD_ERROR :
case GNUNET_DB_STATUS_SOFT_ERROR :
goto cleanup ;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
2022-01-08 14:40:20 +01:00
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT : /* should be impossible */
2017-12-09 23:46:05 +01:00
break ;
}
2015-01-29 20:18:04 +01:00
2017-11-27 23:42:17 +01:00
/* Pass result back to application */
cb ( cb_cls ,
grctx . rrcs_len ,
2021-12-25 13:56:33 +01:00
grctx . rrcs ) ;
2019-10-05 15:42:08 +02:00
cleanup :
2017-11-27 23:42:17 +01:00
for ( unsigned int i = 0 ; i < grctx . rrcs_len ; i + + )
{
struct TALER_EXCHANGEDB_RefreshRevealedCoin * rrc = & grctx . rrcs [ i ] ;
2016-11-17 16:37:40 +01:00
2021-10-31 17:56:56 +01:00
TALER_blinded_denom_sig_free ( & rrc - > coin_sig ) ;
2022-02-07 13:14:25 +01:00
TALER_blinded_planchet_free ( & rrc - > blinded_planchet ) ;
2017-11-27 23:42:17 +01:00
}
2020-07-05 16:58:43 +02:00
GNUNET_free ( grctx . rrcs ) ;
2017-11-27 23:42:17 +01:00
return qs ;
2015-01-31 20:53:19 +01:00
}
2016-01-17 18:19:09 +01:00
/**
2017-06-19 20:12:00 +02:00
* Closure for # handle_wt_result .
2016-01-17 18:19:09 +01:00
*/
2017-06-19 20:12:00 +02:00
struct WireTransferResultContext
2016-01-17 18:19:09 +01:00
{
2017-06-19 20:12:00 +02:00
/**
* Function to call on each result .
*/
2020-03-05 22:38:19 +01:00
TALER_EXCHANGEDB_AggregationDataCallback cb ;
2016-01-21 12:09:17 +01:00
2017-06-19 20:12:00 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2017-06-19 20:12:00 +02:00
/**
* Set to # GNUNET_SYSERR on serious errors .
*/
int status ;
} ;
/**
* Function to be called with the results of a SELECT statement
* that has returned @ a num_results results . Helper function
* for # postgres_lookup_wire_transfer ( ) .
*
* @ param cls closure of type ` struct WireTransferResultContext * `
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2017-06-19 20:12:00 +02:00
*/
static void
handle_wt_result ( void * cls ,
2019-07-21 20:15:11 +02:00
PGresult * result ,
unsigned int num_results )
2017-06-19 20:12:00 +02:00
{
struct WireTransferResultContext * ctx = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = ctx - > pg ;
2017-09-26 12:30:24 +02:00
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2016-01-21 12:09:17 +01:00
{
2017-03-18 17:47:44 +01:00
uint64_t rowid ;
2022-02-21 00:23:23 +01:00
struct TALER_PrivateContractHashP h_contract_terms ;
2016-01-21 12:09:17 +01:00
struct TALER_CoinSpendPublicKeyP coin_pub ;
2022-02-28 20:37:19 +01:00
struct TALER_PaytoHashP h_payto ;
2016-01-21 12:09:17 +01:00
struct TALER_MerchantPublicKeyP merchant_pub ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp exec_time ;
2016-05-27 15:34:24 +02:00
struct TALER_Amount amount_with_fee ;
struct TALER_Amount deposit_fee ;
2019-07-27 20:43:52 +02:00
struct TALER_DenominationPublicKey denom_pub ;
2021-10-30 20:49:23 +02:00
char * payto_uri ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2017-03-18 17:47:44 +01:00
GNUNET_PQ_result_spec_uint64 ( " aggregation_serial_id " , & rowid ) ,
2019-08-25 16:18:24 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " h_contract_terms " ,
& h_contract_terms ) ,
2021-10-30 20:49:23 +02:00
GNUNET_PQ_result_spec_string ( " payto_uri " ,
& payto_uri ) ,
2022-03-03 23:52:08 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " wire_target_h_payto " ,
2022-02-28 20:37:19 +01:00
& h_payto ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " coin_pub " ,
& coin_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " merchant_pub " ,
& merchant_pub ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " execution_date " ,
& exec_time ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
& amount_with_fee ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_deposit " ,
& deposit_fee ) ,
2017-03-04 16:49:33 +01:00
GNUNET_PQ_result_spec_end
2016-01-21 12:09:17 +01:00
} ;
2017-03-18 17:47:44 +01:00
2016-09-26 14:50:49 +02:00
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
2016-01-21 12:09:17 +01:00
{
GNUNET_break ( 0 ) ;
2017-06-19 20:12:00 +02:00
ctx - > status = GNUNET_SYSERR ;
return ;
2016-01-21 12:09:17 +01:00
}
2017-06-19 20:12:00 +02:00
ctx - > cb ( ctx - > cb_cls ,
2019-07-27 20:43:52 +02:00
rowid ,
& merchant_pub ,
2021-10-30 20:49:23 +02:00
payto_uri ,
2022-02-28 20:37:19 +01:00
& h_payto ,
2019-07-27 20:43:52 +02:00
exec_time ,
& h_contract_terms ,
& denom_pub ,
& coin_pub ,
& amount_with_fee ,
& deposit_fee ) ;
2017-03-05 18:18:23 +01:00
GNUNET_PQ_cleanup_result ( rs ) ;
2016-01-21 12:09:17 +01:00
}
2017-06-19 20:12:00 +02:00
}
/**
* Lookup the list of Taler transactions that were aggregated
* into a wire transfer by the respective @ a wtid .
*
* @ param cls closure
* @ param wtid the raw wire transfer identifier we used
* @ param cb function to call on each transaction found
* @ param cb_cls closure for @ a cb
* @ return query status of the transaction
*/
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_lookup_wire_transfer (
void * cls ,
const struct TALER_WireTransferIdentifierRawP * wtid ,
TALER_EXCHANGEDB_AggregationDataCallback cb ,
void * cb_cls )
2017-06-19 20:12:00 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2017-06-19 20:12:00 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( wtid ) ,
GNUNET_PQ_query_param_end
} ;
struct WireTransferResultContext ctx ;
enum GNUNET_DB_QueryStatus qs ;
2017-09-26 12:30:24 +02:00
2017-06-19 20:12:00 +02:00
ctx . cb = cb ;
ctx . cb_cls = cb_cls ;
2019-08-17 21:35:21 +02:00
ctx . pg = pg ;
2017-06-19 20:12:00 +02:00
ctx . status = GNUNET_OK ;
/* check if the melt record exists and get it */
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-07-27 20:43:52 +02:00
" lookup_transactions " ,
params ,
& handle_wt_result ,
& ctx ) ;
2017-06-19 20:12:00 +02:00
if ( GNUNET_OK ! = ctx . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
2016-01-17 18:19:09 +01:00
}
2015-12-09 15:36:34 +01:00
/**
* Try to find the wire transfer details for a deposit operation .
* If we did not execute the deposit yet , return when it is supposed
* to be executed .
2016-01-17 18:19:09 +01:00
*
2015-12-09 15:36:34 +01:00
* @ param cls closure
2017-05-29 01:15:41 +02:00
* @ param h_contract_terms hash of the proposal data
2015-12-09 15:36:34 +01:00
* @ param h_wire hash of merchant wire details
* @ param coin_pub public key of deposited coin
* @ param merchant_pub merchant public key
2021-10-17 13:22:15 +02:00
* @ param [ out ] pending set to true if the transaction is still pending
* @ param [ out ] wtid wire transfer identifier , only set if @ a pending is false
2022-02-12 11:12:33 +01:00
* @ param [ out ] exec_time when was the transaction done , or
2021-10-17 13:22:15 +02:00
* when we expect it to be done ( if @ a pending is false )
2022-02-12 11:12:33 +01:00
* @ param [ out ] amount_with_fee set to the total deposited amount
* @ param [ out ] deposit_fee set to how much the exchange did charge for the deposit
2021-10-17 13:22:15 +02:00
* @ param [ out ] kyc set to the kyc status of the receiver ( if @ a pending )
2017-06-19 20:46:24 +02:00
* @ return transaction status code
2021-10-17 13:22:15 +02:00
*/
2017-06-19 20:46:24 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_lookup_transfer_by_deposit (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_PrivateContractHashP * h_contract_terms ,
const struct TALER_MerchantWireHashP * h_wire ,
2020-03-07 00:28:07 +01:00
const struct TALER_CoinSpendPublicKeyP * coin_pub ,
const struct TALER_MerchantPublicKeyP * merchant_pub ,
2021-10-17 13:22:15 +02:00
bool * pending ,
struct TALER_WireTransferIdentifierRawP * wtid ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp * exec_time ,
2021-10-17 13:22:15 +02:00
struct TALER_Amount * amount_with_fee ,
struct TALER_Amount * deposit_fee ,
struct TALER_EXCHANGEDB_KycStatus * kyc )
2015-12-09 15:36:34 +01:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2017-06-19 20:46:24 +02:00
enum GNUNET_DB_QueryStatus qs ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( coin_pub ) ,
2017-05-29 01:15:41 +02:00
GNUNET_PQ_query_param_auto_from_type ( h_contract_terms ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_auto_from_type ( merchant_pub ) ,
GNUNET_PQ_query_param_end
2016-01-21 12:09:17 +01:00
} ;
2021-10-30 20:49:23 +02:00
char * payto_uri ;
2022-02-07 12:33:35 +01:00
struct TALER_WireSaltP wire_salt ;
2017-06-19 20:46:24 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2021-01-10 12:56:13 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " wtid_raw " ,
2021-10-17 13:22:15 +02:00
wtid ) ,
2021-10-30 20:49:23 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " wire_salt " ,
& wire_salt ) ,
GNUNET_PQ_result_spec_string ( " payto_uri " ,
& payto_uri ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " execution_date " ,
exec_time ) ,
2021-01-10 12:56:13 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
2021-10-17 13:22:15 +02:00
amount_with_fee ) ,
2021-01-10 12:56:13 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_deposit " ,
2021-10-17 13:22:15 +02:00
deposit_fee ) ,
2017-06-19 20:46:24 +02:00
GNUNET_PQ_result_spec_end
} ;
2017-09-26 12:30:24 +02:00
2022-08-11 23:35:33 +02:00
memset ( kyc ,
0 ,
sizeof ( * kyc ) ) ;
2021-10-17 13:22:15 +02:00
/* check if the aggregation record exists and get it */
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-08-25 16:18:24 +02:00
" lookup_deposit_wtid " ,
params ,
rs ) ;
2017-06-19 20:46:24 +02:00
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT = = qs )
2016-01-21 12:09:17 +01:00
{
2022-02-21 00:23:23 +01:00
struct TALER_MerchantWireHashP wh ;
2021-10-30 20:49:23 +02:00
TALER_merchant_wire_signature_hash ( payto_uri ,
& wire_salt ,
& wh ) ;
GNUNET_PQ_cleanup_result ( rs ) ;
if ( 0 = =
GNUNET_memcmp ( & wh ,
h_wire ) )
{
* pending = false ;
kyc - > ok = true ;
return qs ;
}
2021-10-31 15:32:20 +01:00
qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ;
2016-01-21 12:09:17 +01:00
}
2017-06-19 20:46:24 +02:00
if ( 0 > qs )
return qs ;
2021-10-17 13:22:15 +02:00
* pending = true ;
memset ( wtid ,
0 ,
sizeof ( * wtid ) ) ;
2017-06-19 20:46:24 +02:00
GNUNET_assert ( GNUNET_DB_STATUS_SUCCESS_NO_RESULTS = = qs ) ;
GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG ,
2019-08-17 21:35:21 +02:00
" lookup_deposit_wtid returned 0 matching rows \n " ) ;
2017-06-19 20:46:24 +02:00
{
2016-01-21 12:09:17 +01:00
/* Check if transaction exists in deposits, so that we just
2021-11-07 11:41:53 +01:00
do not have a WTID yet . In that case , return without wtid
( by setting ' pending ' true ) . */
2017-06-19 20:46:24 +02:00
struct GNUNET_PQ_ResultSpec rs2 [ ] = {
2021-10-31 12:49:51 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " wire_salt " ,
& wire_salt ) ,
GNUNET_PQ_result_spec_string ( " payto_uri " ,
& payto_uri ) ,
2022-08-11 23:35:33 +02:00
GNUNET_PQ_result_spec_allow_null (
2022-08-20 21:29:29 +02:00
GNUNET_PQ_result_spec_uint64 ( " legitimization_requirement_serial_id " ,
& kyc - > requirement_row ) ,
NULL ) ,
2021-10-17 13:22:15 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
amount_with_fee ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_deposit " ,
deposit_fee ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " wire_deadline " ,
exec_time ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_result_spec_end
2016-01-21 12:09:17 +01:00
} ;
2017-06-19 20:46:24 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2021-11-07 11:41:53 +01:00
" get_deposit_without_wtid " ,
2021-10-17 13:22:15 +02:00
params ,
2019-08-17 21:35:21 +02:00
rs2 ) ;
2021-10-31 12:49:51 +01:00
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT = = qs )
{
2022-02-21 00:23:23 +01:00
struct TALER_MerchantWireHashP wh ;
2021-10-31 12:49:51 +01:00
2022-08-20 21:29:29 +02:00
if ( 0 = = kyc - > requirement_row )
kyc - > ok = true ; /* technically: unknown */
2021-10-31 12:49:51 +01:00
TALER_merchant_wire_signature_hash ( payto_uri ,
& wire_salt ,
& wh ) ;
GNUNET_PQ_cleanup_result ( rs ) ;
if ( 0 ! =
GNUNET_memcmp ( & wh ,
h_wire ) )
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ;
}
2017-06-19 20:46:24 +02:00
return qs ;
2016-01-21 12:09:17 +01:00
}
2015-12-09 15:36:34 +01:00
}
2017-03-04 16:49:33 +01:00
/**
* Obtain wire fee from database .
*
* @ param cls closure
* @ param type type of wire transfer the fee applies for
* @ param date for which date do we want the fee ?
* @ param [ out ] start_date when does the fee go into effect
* @ param [ out ] end_date when does the fee end being valid
2022-03-05 14:36:49 +01:00
* @ param [ out ] fees how high are the wire fees
2017-03-04 16:49:33 +01:00
* @ param [ out ] master_sig signature over the above by the exchange master key
2017-06-19 20:12:00 +02:00
* @ return status of the transaction
2017-03-04 16:49:33 +01:00
*/
2017-06-19 20:12:00 +02:00
static enum GNUNET_DB_QueryStatus
2017-03-04 16:49:33 +01:00
postgres_get_wire_fee ( void * cls ,
const char * type ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp date ,
struct GNUNET_TIME_Timestamp * start_date ,
struct GNUNET_TIME_Timestamp * end_date ,
2022-03-05 14:36:49 +01:00
struct TALER_WireFeeSet * fees ,
2017-03-04 16:49:33 +01:00
struct TALER_MasterSignatureP * master_sig )
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2017-03-04 16:49:33 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( type ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & date ) ,
2017-03-04 16:49:33 +01:00
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2022-03-05 14:36:49 +01:00
GNUNET_PQ_result_spec_timestamp ( " start_date " ,
start_date ) ,
GNUNET_PQ_result_spec_timestamp ( " end_date " ,
end_date ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " wire_fee " ,
& fees - > wire ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " closing_fee " ,
& fees - > closing ) ,
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
master_sig ) ,
2017-03-04 16:49:33 +01:00
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" get_wire_fee " ,
params ,
rs ) ;
2017-03-04 16:49:33 +01:00
}
2022-03-05 17:14:32 +01:00
/**
* Obtain global fees from database .
*
* @ param cls closure
* @ param date for which date do we want the fee ?
* @ param [ out ] start_date when does the fee go into effect
* @ param [ out ] end_date when does the fee end being valid
* @ param [ out ] fees how high are the wire fees
* @ param [ out ] purse_timeout set to how long we keep unmerged purses
* @ param [ out ] history_expiration set to how long we keep account histories
* @ param [ out ] purse_account_limit set to the number of free purses per account
* @ param [ out ] master_sig signature over the above by the exchange master key
* @ return status of the transaction
*/
static enum GNUNET_DB_QueryStatus
postgres_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 PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_timestamp ( & date ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_timestamp ( " start_date " ,
start_date ) ,
GNUNET_PQ_result_spec_timestamp ( " end_date " ,
end_date ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " history_fee " ,
& fees - > history ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " account_fee " ,
& fees - > account ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " purse_fee " ,
& fees - > purse ) ,
GNUNET_PQ_result_spec_relative_time ( " purse_timeout " ,
purse_timeout ) ,
GNUNET_PQ_result_spec_relative_time ( " history_expiration " ,
history_expiration ) ,
GNUNET_PQ_result_spec_uint32 ( " purse_account_limit " ,
purse_account_limit ) ,
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
master_sig ) ,
GNUNET_PQ_result_spec_end
} ;
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" get_global_fee " ,
params ,
rs ) ;
}
2022-03-20 09:44:42 +01:00
/**
* Closure for # global_fees_cb ( ) .
*/
struct GlobalFeeContext
{
/**
* Function to call for each global fee block .
*/
TALER_EXCHANGEDB_GlobalFeeCallback cb ;
/**
* Closure to give to @ e rec .
*/
void * cb_cls ;
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
/**
* Set to # GNUNET_SYSERR on error .
*/
enum GNUNET_GenericReturnValue status ;
} ;
/**
* Function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
* @ param cls closure
* @ param result the postgres result
* @ param num_results the number of results in @ a result
*/
static void
global_fees_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct GlobalFeeContext * gctx = cls ;
struct PostgresClosure * pg = gctx - > pg ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
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 ;
struct TALER_MasterSignatureP master_sig ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_timestamp ( " start_date " ,
& start_date ) ,
GNUNET_PQ_result_spec_timestamp ( " end_date " ,
& end_date ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " history_fee " ,
& fees . history ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " account_fee " ,
& fees . account ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " purse_fee " ,
& fees . purse ) ,
GNUNET_PQ_result_spec_relative_time ( " purse_timeout " ,
& purse_timeout ) ,
GNUNET_PQ_result_spec_relative_time ( " history_expiration " ,
& history_expiration ) ,
GNUNET_PQ_result_spec_uint32 ( " purse_account_limit " ,
& purse_account_limit ) ,
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
& master_sig ) ,
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
gctx - > status = GNUNET_SYSERR ;
break ;
}
gctx - > cb ( gctx - > cb_cls ,
& fees ,
purse_timeout ,
history_expiration ,
purse_account_limit ,
start_date ,
end_date ,
& master_sig ) ;
GNUNET_PQ_cleanup_result ( rs ) ;
}
}
/**
* Obtain global fees from database .
*
* @ param cls closure
* @ param cb function to call on each fee entry
* @ param cb_cls closure for @ a cb
* @ return status of the transaction
*/
static enum GNUNET_DB_QueryStatus
postgres_get_global_fees ( void * cls ,
TALER_EXCHANGEDB_GlobalFeeCallback cb ,
void * cb_cls )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_TIME_Timestamp date
2022-04-23 20:50:27 +02:00
= GNUNET_TIME_absolute_to_timestamp (
GNUNET_TIME_absolute_subtract (
GNUNET_TIME_absolute_get ( ) ,
GNUNET_TIME_UNIT_YEARS ) ) ;
2022-03-20 09:44:42 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_timestamp ( & date ) ,
GNUNET_PQ_query_param_end
} ;
struct GlobalFeeContext gctx = {
. cb = cb ,
. cb_cls = cb_cls ,
. pg = pg ,
. status = GNUNET_OK
} ;
return GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
" get_global_fees " ,
params ,
& global_fees_cb ,
& gctx ) ;
}
2017-03-04 16:49:33 +01:00
/**
* Insert wire transfer fee into database .
*
* @ param cls closure
* @ param type type of wire transfer this fee applies for
* @ param start_date when does the fee go into effect
* @ param end_date when does the fee end being valid
2022-03-05 14:36:49 +01:00
* @ param fees how high are the wire fees
2017-03-04 16:49:33 +01:00
* @ param master_sig signature over the above by the exchange master key
2017-06-24 12:15:11 +02:00
* @ return transaction status code
2017-03-04 16:49:33 +01:00
*/
2017-06-24 12:15:11 +02:00
static enum GNUNET_DB_QueryStatus
2017-03-04 16:49:33 +01:00
postgres_insert_wire_fee ( void * cls ,
const char * type ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp start_date ,
struct GNUNET_TIME_Timestamp end_date ,
2022-03-05 14:36:49 +01:00
const struct TALER_WireFeeSet * fees ,
2017-03-04 16:49:33 +01:00
const struct TALER_MasterSignatureP * master_sig )
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2017-03-04 16:49:33 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( type ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & start_date ) ,
GNUNET_PQ_query_param_timestamp ( & end_date ) ,
2022-03-05 14:36:49 +01:00
TALER_PQ_query_param_amount ( & fees - > wire ) ,
TALER_PQ_query_param_amount ( & fees - > closing ) ,
2017-03-04 16:49:33 +01:00
GNUNET_PQ_query_param_auto_from_type ( master_sig ) ,
GNUNET_PQ_query_param_end
} ;
2022-03-05 14:36:49 +01:00
struct TALER_WireFeeSet wx ;
2017-03-04 16:49:33 +01:00
struct TALER_MasterSignatureP sig ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp sd ;
struct GNUNET_TIME_Timestamp ed ;
2017-06-24 12:15:11 +02:00
enum GNUNET_DB_QueryStatus qs ;
2017-03-04 16:49:33 +01:00
2019-08-17 21:35:21 +02:00
qs = postgres_get_wire_fee ( pg ,
type ,
start_date ,
& sd ,
& ed ,
2022-03-05 14:36:49 +01:00
& wx ,
2019-08-17 21:35:21 +02:00
& sig ) ;
2017-06-24 12:15:11 +02:00
if ( qs < 0 )
return qs ;
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT = = qs )
2017-03-04 16:49:33 +01:00
{
2019-04-08 20:43:23 +02:00
if ( 0 ! = GNUNET_memcmp ( & sig ,
master_sig ) )
2017-03-04 16:49:33 +01:00
{
GNUNET_break ( 0 ) ;
2017-06-24 12:15:11 +02:00
return GNUNET_DB_STATUS_HARD_ERROR ;
2017-03-04 16:49:33 +01:00
}
2022-03-05 14:36:49 +01:00
if ( 0 ! =
TALER_wire_fee_set_cmp ( fees ,
& wx ) )
2019-08-25 16:18:24 +02:00
{
2018-01-04 00:41:19 +01:00
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
2021-12-14 16:04:32 +01:00
if ( ( GNUNET_TIME_timestamp_cmp ( sd ,
! = ,
start_date ) ) | |
( GNUNET_TIME_timestamp_cmp ( ed ,
! = ,
end_date ) ) )
2017-03-04 16:49:33 +01:00
{
GNUNET_break ( 0 ) ;
2017-06-24 12:15:11 +02:00
return GNUNET_DB_STATUS_HARD_ERROR ;
2017-03-04 16:49:33 +01:00
}
/* equal record already exists */
2017-06-24 12:15:11 +02:00
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ;
2017-03-04 16:49:33 +01:00
}
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" insert_wire_fee " ,
params ) ;
2017-03-04 16:49:33 +01:00
}
2022-03-05 17:14:32 +01:00
/**
* Insert global fee data into database .
*
* @ param cls closure
2022-06-25 20:38:31 +02:00
* @ param start_date when does the fees go into effect
* @ param end_date when does the fees end being valid
2022-03-05 17:14:32 +01:00
* @ param fees how high is are the global fees
* @ param purse_timeout when do purses time out
* @ param history_expiration how long are account histories preserved
2022-06-25 20:38:31 +02:00
* @ param purse_account_limit how many purses are free per account
* @ param master_sig signature over the above by the exchange master key
2022-03-05 17:14:32 +01:00
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_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 PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_timestamp ( & start_date ) ,
GNUNET_PQ_query_param_timestamp ( & end_date ) ,
TALER_PQ_query_param_amount ( & fees - > history ) ,
TALER_PQ_query_param_amount ( & fees - > account ) ,
TALER_PQ_query_param_amount ( & fees - > purse ) ,
GNUNET_PQ_query_param_relative_time ( & purse_timeout ) ,
GNUNET_PQ_query_param_relative_time ( & history_expiration ) ,
GNUNET_PQ_query_param_uint32 ( & purse_account_limit ) ,
GNUNET_PQ_query_param_auto_from_type ( master_sig ) ,
GNUNET_PQ_query_param_end
} ;
struct TALER_GlobalFeeSet wx ;
struct TALER_MasterSignatureP sig ;
struct GNUNET_TIME_Timestamp sd ;
struct GNUNET_TIME_Timestamp ed ;
enum GNUNET_DB_QueryStatus qs ;
struct GNUNET_TIME_Relative pt ;
struct GNUNET_TIME_Relative he ;
uint32_t pal ;
qs = postgres_get_global_fee ( pg ,
start_date ,
& sd ,
& ed ,
& wx ,
& pt ,
& he ,
& pal ,
& sig ) ;
if ( qs < 0 )
return qs ;
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT = = qs )
{
if ( 0 ! = GNUNET_memcmp ( & sig ,
master_sig ) )
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
if ( 0 ! =
TALER_global_fee_set_cmp ( fees ,
& wx ) )
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
if ( ( GNUNET_TIME_timestamp_cmp ( sd ,
! = ,
start_date ) ) | |
( GNUNET_TIME_timestamp_cmp ( ed ,
! = ,
end_date ) ) )
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
if ( ( GNUNET_TIME_relative_cmp ( purse_timeout ,
! = ,
pt ) ) | |
( GNUNET_TIME_relative_cmp ( history_expiration ,
! = ,
he ) ) )
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
if ( purse_account_limit ! = pal )
{
GNUNET_break ( 0 ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
/* equal record already exists */
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ;
}
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" insert_global_fee " ,
params ) ;
}
2017-04-19 18:44:14 +02:00
/**
* Insert reserve close operation into database .
*
* @ param cls closure
* @ param reserve_pub which reserve is this about ?
* @ param execution_date when did we perform the transfer ?
* @ param receiver_account to which account do we transfer ?
2017-05-08 12:44:40 +02:00
* @ param wtid wire transfer details
2017-04-19 18:44:14 +02:00
* @ param amount_with_fee amount we charged to the reserve
* @ param closing_fee how high is the closing fee
2022-10-30 17:36:57 +01:00
* @ param close_request_row identifies explicit close request , 0 for none
2017-06-24 00:41:41 +02:00
* @ return transaction status code
2017-04-19 18:44:14 +02:00
*/
2017-06-24 00:41:41 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_insert_reserve_closed (
void * cls ,
const struct TALER_ReservePublicKeyP * reserve_pub ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp execution_date ,
2020-03-07 00:28:07 +01:00
const char * receiver_account ,
const struct TALER_WireTransferIdentifierRawP * wtid ,
const struct TALER_Amount * amount_with_fee ,
2022-10-30 17:36:57 +01:00
const struct TALER_Amount * closing_fee ,
uint64_t close_request_row )
2017-04-19 18:44:14 +02:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2017-04-20 21:38:02 +02:00
struct TALER_EXCHANGEDB_Reserve reserve ;
2017-06-11 02:12:56 +02:00
enum GNUNET_DB_QueryStatus qs ;
2022-03-03 23:52:08 +01:00
struct TALER_PaytoHashP h_payto ;
2017-05-05 13:41:32 +02:00
2022-08-14 18:59:48 +02:00
TALER_payto_hash ( receiver_account ,
& h_payto ) ;
2021-10-30 13:52:03 +02:00
{
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( reserve_pub ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & execution_date ) ,
2021-10-30 13:52:03 +02:00
GNUNET_PQ_query_param_auto_from_type ( wtid ) ,
2022-03-03 23:52:08 +01:00
GNUNET_PQ_query_param_auto_from_type ( & h_payto ) ,
2021-10-30 13:52:03 +02:00
TALER_PQ_query_param_amount ( amount_with_fee ) ,
TALER_PQ_query_param_amount ( closing_fee ) ,
2022-10-30 17:36:57 +01:00
GNUNET_PQ_query_param_uint64 ( & close_request_row ) ,
2021-10-30 13:52:03 +02:00
GNUNET_PQ_query_param_end
} ;
qs = GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" reserves_close_insert " ,
params ) ;
}
2017-06-24 00:41:41 +02:00
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ! = qs )
return qs ;
2017-04-20 21:38:02 +02:00
/* update reserve balance */
reserve . pub = * reserve_pub ;
2017-06-11 02:12:56 +02:00
if ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ! =
2022-08-14 18:04:09 +02:00
( qs = postgres_reserves_get ( cls ,
2020-03-05 23:02:38 +01:00
& reserve ) ) )
2017-04-20 21:38:02 +02:00
{
2017-05-25 19:38:34 +02:00
/* Existence should have been checked before we got here... */
2017-06-24 00:41:41 +02:00
GNUNET_break ( GNUNET_DB_STATUS_SOFT_ERROR = = qs ) ;
if ( GNUNET_DB_STATUS_SUCCESS_NO_RESULTS = = qs )
qs = GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
2017-04-20 21:38:02 +02:00
}
{
2021-10-30 13:52:03 +02:00
enum TALER_AmountArithmeticResult ret ;
ret = TALER_amount_subtract ( & reserve . balance ,
& reserve . balance ,
amount_with_fee ) ;
if ( ret < 0 )
{
/* The reserve history was checked to make sure there is enough of a balance
left before we tried this ; however , concurrent operations may have changed
the situation by now . We should re - try the transaction . */
GNUNET_log ( GNUNET_ERROR_TYPE_ERROR ,
" Closing of reserve `%s' refused due to balance mismatch. Retrying. \n " ,
TALER_B2S ( reserve_pub ) ) ;
return GNUNET_DB_STATUS_HARD_ERROR ;
}
GNUNET_break ( TALER_AAR_RESULT_ZERO = = ret ) ;
2017-04-20 21:38:02 +02:00
}
2017-06-24 00:41:41 +02:00
return reserves_update ( cls ,
2019-07-21 20:15:11 +02:00
& reserve ) ;
2017-04-19 18:44:14 +02:00
}
2016-01-27 16:46:51 +01:00
/**
* Function called to insert wire transfer commit data into the DB .
*
* @ param cls closure
2019-06-08 19:55:18 +02:00
* @ param type type of the wire transfer ( i . e . " iban " )
2016-01-27 16:46:51 +01:00
* @ param buf buffer with wire transfer preparation data
* @ param buf_size number of bytes in @ a buf
2017-06-24 00:41:41 +02:00
* @ return query status code
2016-01-27 16:46:51 +01:00
*/
2017-06-24 00:41:41 +02:00
static enum GNUNET_DB_QueryStatus
2016-01-27 16:46:51 +01:00
postgres_wire_prepare_data_insert ( void * cls ,
const char * type ,
const char * buf ,
size_t buf_size )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2016-04-03 21:41:26 +02:00
GNUNET_PQ_query_param_string ( type ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_fixed_size ( buf , buf_size ) ,
GNUNET_PQ_query_param_end
2016-01-27 18:28:52 +01:00
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" wire_prepare_data_insert " ,
params ) ;
2016-01-27 16:46:51 +01:00
}
/**
* Function called to mark wire transfer commit data as finished .
*
* @ param cls closure
2016-01-27 18:28:52 +01:00
* @ param rowid which entry to mark as finished
2017-06-24 12:15:11 +02:00
* @ return transaction status code
2016-01-27 16:46:51 +01:00
*/
2017-06-24 12:15:11 +02:00
static enum GNUNET_DB_QueryStatus
2020-11-14 22:27:50 +01:00
postgres_wire_prepare_data_mark_finished (
void * cls ,
uint64_t rowid )
2016-01-27 16:46:51 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2016-11-17 14:31:44 +01:00
GNUNET_PQ_query_param_uint64 ( & rowid ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_end
2016-01-27 18:28:52 +01:00
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" wire_prepare_data_mark_done " ,
params ) ;
2016-01-27 16:46:51 +01:00
}
2020-11-14 22:27:50 +01:00
/**
* Function called to mark wire transfer commit data as failed .
*
* @ param cls closure
* @ param rowid which entry to mark as failed
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_wire_prepare_data_mark_failed (
void * cls ,
uint64_t rowid )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-14 22:27:50 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & rowid ) ,
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2020-11-14 22:27:50 +01:00
" wire_prepare_data_mark_failed " ,
params ) ;
}
2021-09-05 15:25:46 +02:00
/**
* Closure for # prewire_cb ( ) .
*/
struct PrewireContext
{
/**
* Function to call on each result .
*/
TALER_EXCHANGEDB_WirePreparationIterator cb ;
/**
* Closure for @ a cb .
*/
void * cb_cls ;
/**
* # GNUNET_OK if everything went fine .
*/
enum GNUNET_GenericReturnValue status ;
} ;
/**
* Invoke the callback for each result .
*
* @ param cls a ` struct MissingWireContext * `
* @ param result SQL result
* @ param num_results number of rows in @ a result
*/
static void
prewire_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct PrewireContext * pc = cls ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
uint64_t prewire_uuid ;
2021-12-25 13:56:33 +01:00
char * wire_method ;
2021-09-05 15:25:46 +02:00
void * buf = NULL ;
size_t buf_size ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " prewire_uuid " ,
& prewire_uuid ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_result_spec_string ( " wire_method " ,
& wire_method ) ,
2021-09-05 15:25:46 +02:00
GNUNET_PQ_result_spec_variable_size ( " buf " ,
& buf ,
& buf_size ) ,
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
pc - > status = GNUNET_SYSERR ;
return ;
}
pc - > cb ( pc - > cb_cls ,
prewire_uuid ,
2021-12-25 13:56:33 +01:00
wire_method ,
2021-09-05 15:25:46 +02:00
buf ,
buf_size ) ;
GNUNET_PQ_cleanup_result ( rs ) ;
}
}
2016-01-27 16:46:51 +01:00
/**
2016-01-27 18:28:52 +01:00
* Function called to get an unfinished wire transfer
2016-01-27 16:46:51 +01:00
* preparation data . Fetches at most one item .
*
* @ param cls closure
2021-09-05 15:25:46 +02:00
* @ param start_row offset to query table at
* @ param limit maximum number of results to return
2016-01-27 16:46:51 +01:00
* @ param cb function to call for ONE unfinished item
* @ param cb_cls closure for @ a cb
2017-06-24 12:15:11 +02:00
* @ return transaction status code
2016-01-27 16:46:51 +01:00
*/
2017-06-24 12:15:11 +02:00
static enum GNUNET_DB_QueryStatus
2016-01-27 18:28:52 +01:00
postgres_wire_prepare_data_get ( void * cls ,
2021-09-05 15:25:46 +02:00
uint64_t start_row ,
uint64_t limit ,
2016-10-09 00:57:31 +02:00
TALER_EXCHANGEDB_WirePreparationIterator cb ,
2016-01-27 18:28:52 +01:00
void * cb_cls )
2016-01-27 16:46:51 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2016-02-06 17:39:18 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2021-09-05 15:25:46 +02:00
GNUNET_PQ_query_param_uint64 ( & start_row ) ,
GNUNET_PQ_query_param_uint64 ( & limit ) ,
2016-02-06 17:39:18 +01:00
GNUNET_PQ_query_param_end
2016-01-27 18:28:52 +01:00
} ;
2021-09-05 15:25:46 +02:00
struct PrewireContext pc = {
. cb = cb ,
. cb_cls = cb_cls ,
. status = GNUNET_OK
2017-06-24 12:15:11 +02:00
} ;
2021-09-05 15:25:46 +02:00
enum GNUNET_DB_QueryStatus qs ;
2016-01-27 18:28:52 +01:00
2021-09-05 15:25:46 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
" wire_prepare_data_get " ,
params ,
& prewire_cb ,
& pc ) ;
if ( GNUNET_OK ! = pc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
2017-06-24 12:15:11 +02:00
return qs ;
2016-01-27 16:46:51 +01:00
}
2017-03-18 03:44:59 +01:00
/**
2021-09-03 19:08:02 +02:00
* Starts a READ COMMITTED transaction where we transiently violate the foreign
2017-03-18 03:44:59 +01:00
* constraints on the " wire_out " table as we insert aggregations
* and only add the wire transfer out at the end .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ return # GNUNET_OK on success
*/
2021-09-03 19:08:02 +02:00
static enum GNUNET_GenericReturnValue
2021-08-23 00:00:32 +02:00
postgres_start_deferred_wire_out ( void * cls )
2017-03-18 03:44:59 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2019-10-11 23:28:05 +02:00
struct GNUNET_PQ_ExecuteStatement es [ ] = {
2022-03-03 19:39:19 +01:00
GNUNET_PQ_make_execute (
" START TRANSACTION ISOLATION LEVEL READ COMMITTED; " ) ,
2022-03-03 17:48:00 +01:00
GNUNET_PQ_make_execute ( " SET CONSTRAINTS ALL DEFERRED; " ) ,
2019-10-11 23:28:05 +02:00
GNUNET_PQ_EXECUTE_STATEMENT_END
} ;
2017-03-18 03:44:59 +01:00
2021-08-23 00:00:32 +02:00
if ( GNUNET_SYSERR = =
2022-11-08 17:40:47 +01:00
TEH_PG_preflight ( pg ) )
2021-08-23 00:00:32 +02:00
return GNUNET_SYSERR ;
2019-10-11 23:28:05 +02:00
if ( GNUNET_OK ! =
2021-08-23 00:00:32 +02:00
GNUNET_PQ_exec_statements ( pg - > conn ,
2019-10-11 23:28:05 +02:00
es ) )
2017-03-18 03:44:59 +01:00
{
2019-08-25 16:18:24 +02:00
TALER_LOG_ERROR (
2019-10-11 23:28:05 +02:00
" Failed to defer wire_out_ref constraint on transaction \n " ) ;
2017-03-18 03:44:59 +01:00
GNUNET_break ( 0 ) ;
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2017-03-18 03:44:59 +01:00
return GNUNET_SYSERR ;
}
2021-09-03 19:08:02 +02:00
pg - > transaction_name = " deferred wire out " ;
2022-05-31 10:13:58 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_INFO ,
" Starting READ COMMITTED DEFERRED transaction `%s' \n " ,
pg - > transaction_name ) ;
2017-03-18 03:44:59 +01:00
return GNUNET_OK ;
}
2017-03-18 02:40:27 +01:00
/**
* Store information about an outgoing wire transfer that was executed .
*
* @ param cls closure
* @ param date time of the wire transfer
* @ param wtid subject of the wire transfer
2022-03-03 23:52:08 +01:00
* @ param h_payto identifies the receiver account of the wire transfer
2018-04-02 21:12:18 +02:00
* @ param exchange_account_section configuration section of the exchange specifying the
* exchange ' s bank account being used
2017-03-18 02:40:27 +01:00
* @ param amount amount that was transmitted
2017-06-24 12:15:11 +02:00
* @ return transaction status code
2017-03-18 02:40:27 +01:00
*/
2017-06-24 12:15:11 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_store_wire_transfer_out (
void * cls ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp date ,
2020-03-07 00:28:07 +01:00
const struct TALER_WireTransferIdentifierRawP * wtid ,
2022-03-03 23:52:08 +01:00
const struct TALER_PaytoHashP * h_payto ,
2020-03-07 00:28:07 +01:00
const char * exchange_account_section ,
const struct TALER_Amount * amount )
2017-03-18 02:40:27 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2017-03-18 02:40:27 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & date ) ,
2017-03-18 02:40:27 +01:00
GNUNET_PQ_query_param_auto_from_type ( wtid ) ,
2022-03-03 23:52:08 +01:00
GNUNET_PQ_query_param_auto_from_type ( h_payto ) ,
2018-04-02 21:12:18 +02:00
GNUNET_PQ_query_param_string ( exchange_account_section ) ,
2017-03-18 02:40:27 +01:00
TALER_PQ_query_param_amount ( amount ) ,
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" insert_wire_out " ,
params ) ;
2017-03-18 02:40:27 +01:00
}
2016-05-31 09:13:03 +02:00
/**
* Function called to perform " garbage collection " on the
* database , expiring records we no longer require .
*
* @ param cls closure
* @ return # GNUNET_OK on success ,
* # GNUNET_SYSERR on DB errors
*/
2021-11-01 13:34:14 +01:00
static enum GNUNET_GenericReturnValue
2016-05-31 09:13:03 +02:00
postgres_gc ( void * cls )
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ( ) ;
2017-07-14 17:43:07 +02:00
struct GNUNET_TIME_Absolute long_ago ;
2021-12-25 13:56:33 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_absolute_time ( & long_ago ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_query_param_absolute_time ( & now ) ,
2017-07-14 17:43:07 +02:00
GNUNET_PQ_query_param_end
} ;
2019-10-11 23:28:05 +02:00
struct GNUNET_PQ_Context * conn ;
2021-12-14 16:04:32 +01:00
enum GNUNET_GenericReturnValue ret ;
2017-07-14 17:43:07 +02:00
/* Keep wire fees for 10 years, that should always
be enough _and_ they are tiny so it does not
matter to make this tight */
2021-12-14 16:04:32 +01:00
long_ago = GNUNET_TIME_absolute_subtract (
now ,
GNUNET_TIME_relative_multiply (
GNUNET_TIME_UNIT_YEARS ,
10 ) ) ;
2016-05-31 09:34:45 +02:00
{
2022-07-25 20:18:08 +02:00
struct GNUNET_PQ_ExecuteStatement es [ ] = {
GNUNET_PQ_make_try_execute ( " SET search_path TO exchange; " ) ,
GNUNET_PQ_EXECUTE_STATEMENT_END
} ;
2019-10-11 23:28:05 +02:00
struct GNUNET_PQ_PreparedStatement ps [ ] = {
/* Used in #postgres_gc() */
2021-12-25 13:56:33 +01:00
GNUNET_PQ_make_prepare ( " run_gc " ,
" CALL "
" exchange_do_gc "
2022-10-12 14:48:49 +02:00
" ($1,$2); " ) ,
2019-10-11 23:28:05 +02:00
GNUNET_PQ_PREPARED_STATEMENT_END
} ;
2020-02-09 16:34:40 +01:00
conn = GNUNET_PQ_connect_with_cfg ( pg - > cfg ,
" exchangedb-postgres " ,
NULL ,
2022-07-25 20:18:08 +02:00
es ,
2020-02-09 16:34:40 +01:00
ps ) ;
2016-05-31 09:34:45 +02:00
}
2019-10-11 23:28:05 +02:00
if ( NULL = = conn )
return GNUNET_SYSERR ;
ret = GNUNET_OK ;
2021-12-25 13:56:33 +01:00
if ( 0 > GNUNET_PQ_eval_prepared_non_select ( conn ,
" run_gc " ,
params ) )
2019-10-11 23:28:05 +02:00
ret = GNUNET_SYSERR ;
GNUNET_PQ_disconnect ( conn ) ;
2017-06-24 16:15:42 +02:00
return ret ;
2016-05-31 09:13:03 +02:00
}
2016-10-09 01:17:37 +02:00
/**
2017-06-24 16:15:42 +02:00
* Closure for # deposit_serial_helper_cb ( ) .
2016-10-09 01:17:37 +02:00
*/
2017-06-24 16:15:42 +02:00
struct DepositSerialContext
2016-10-09 01:17:37 +02:00
{
2016-10-17 01:48:59 +02:00
2017-06-24 16:15:42 +02:00
/**
* Callback to call .
*/
TALER_EXCHANGEDB_DepositCallback cb ;
2017-09-26 12:30:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2017-09-26 12:30:24 +02:00
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2019-08-25 16:18:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
2017-09-26 12:30:24 +02:00
*/
2022-06-12 17:23:31 +02:00
enum GNUNET_GenericReturnValue status ;
2017-06-24 16:15:42 +02:00
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
* @ param cls closure of type ` struct DepositSerialContext `
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2017-06-24 16:15:42 +02:00
*/
static void
deposit_serial_helper_cb ( void * cls ,
2019-08-17 21:35:21 +02:00
PGresult * result ,
unsigned int num_results )
2017-06-24 16:15:42 +02:00
{
struct DepositSerialContext * dsc = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = dsc - > pg ;
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2016-10-17 01:48:59 +02:00
{
2016-10-17 16:39:56 +02:00
struct TALER_EXCHANGEDB_Deposit deposit ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp exchange_timestamp ;
2017-03-19 01:55:37 +01:00
struct TALER_DenominationPublicKey denom_pub ;
2021-12-05 17:16:00 +01:00
bool done ;
2016-11-17 14:59:44 +01:00
uint64_t rowid ;
2016-10-17 16:39:56 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
2016-10-17 16:39:56 +02:00
& deposit . amount_with_fee ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " wallet_timestamp " ,
& deposit . timestamp ) ,
GNUNET_PQ_result_spec_timestamp ( " exchange_timestamp " ,
& exchange_timestamp ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " merchant_pub " ,
& deposit . merchant_pub ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " coin_pub " ,
2019-08-25 16:18:24 +02:00
& deposit . coin . coin_pub ) ,
2022-02-28 16:13:24 +01:00
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ( " age_commitment_hash " ,
& deposit . coin . h_age_commitment ) ,
& deposit . coin . no_age_commitment ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " coin_sig " ,
2019-08-25 16:18:24 +02:00
& deposit . csig ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " refund_deadline " ,
& deposit . refund_deadline ) ,
GNUNET_PQ_result_spec_timestamp ( " wire_deadline " ,
& deposit . wire_deadline ) ,
2017-05-29 01:15:41 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " h_contract_terms " ,
2019-08-25 16:18:24 +02:00
& deposit . h_contract_terms ) ,
2021-10-30 19:28:11 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " wire_salt " ,
& deposit . wire_salt ) ,
GNUNET_PQ_result_spec_string ( " receiver_wire_account " ,
& deposit . receiver_wire_account ) ,
2021-12-05 17:16:00 +01:00
GNUNET_PQ_result_spec_bool ( " done " ,
& done ) ,
2016-11-17 14:59:44 +01:00
GNUNET_PQ_result_spec_uint64 ( " deposit_serial_id " ,
& rowid ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_end
} ;
2022-06-12 17:23:31 +02:00
enum GNUNET_GenericReturnValue ret ;
2017-09-26 12:30:24 +02:00
2022-02-28 16:13:24 +01:00
memset ( & deposit ,
0 ,
sizeof ( deposit ) ) ;
2016-10-17 16:39:56 +02:00
if ( GNUNET_OK ! =
2016-11-17 15:12:01 +01:00
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
2016-10-17 16:39:56 +02:00
{
GNUNET_break ( 0 ) ;
2017-06-24 16:15:42 +02:00
dsc - > status = GNUNET_SYSERR ;
return ;
2016-10-17 16:39:56 +02:00
}
2017-06-24 16:15:42 +02:00
ret = dsc - > cb ( dsc - > cb_cls ,
2019-08-17 21:35:21 +02:00
rowid ,
2020-05-07 20:22:02 +02:00
exchange_timestamp ,
2021-10-30 19:28:11 +02:00
& deposit ,
2019-08-17 21:35:21 +02:00
& denom_pub ,
2021-12-05 17:16:00 +01:00
done ) ;
2017-03-05 18:18:23 +01:00
GNUNET_PQ_cleanup_result ( rs ) ;
2017-04-04 15:38:58 +02:00
if ( GNUNET_OK ! = ret )
break ;
2016-10-17 01:48:59 +02:00
}
2016-10-09 01:17:37 +02:00
}
/**
2017-06-24 16:15:42 +02:00
* Select deposits above @ a serial_id in monotonically increasing
2016-10-09 01:17:37 +02:00
* order .
*
* @ param cls closure
* @ param serial_id highest serial ID to exclude ( select strictly larger )
* @ param cb function to call on each result
* @ param cb_cls closure for @ a cb
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2016-10-09 01:17:37 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_deposits_above_serial_id (
void * cls ,
uint64_t serial_id ,
TALER_EXCHANGEDB_DepositCallback cb ,
void * cb_cls )
2016-10-09 01:17:37 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2016-10-17 16:39:56 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2017-06-24 16:15:42 +02:00
struct DepositSerialContext dsc = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2017-06-24 16:15:42 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2016-10-17 16:39:56 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" audit_get_deposits_incr " ,
params ,
& deposit_serial_helper_cb ,
& dsc ) ;
2017-06-24 16:15:42 +02:00
if ( GNUNET_OK ! = dsc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2016-10-17 16:39:56 +02:00
2022-06-12 17:23:31 +02:00
/**
* Closure for # purse_deposit_serial_helper_cb ( ) .
*/
2022-11-02 12:17:05 +01:00
struct HistoryRequestSerialContext
2022-06-12 17:23:31 +02:00
{
/**
* Callback to call .
*/
2022-11-02 12:17:05 +01:00
TALER_EXCHANGEDB_HistoryRequestCallback cb ;
2022-06-12 17:23:31 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
*/
enum GNUNET_GenericReturnValue status ;
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
2022-11-02 12:17:05 +01:00
* @ param cls closure of type ` struct HistoryRequestSerialContext `
2022-06-12 17:23:31 +02:00
* @ param result the postgres result
* @ param num_results the number of results in @ a result
*/
static void
2022-11-02 12:17:05 +01:00
history_request_serial_helper_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
2022-06-12 17:23:31 +02:00
{
2022-11-02 12:17:05 +01:00
struct HistoryRequestSerialContext * dsc = cls ;
2022-06-12 17:23:31 +02:00
struct PostgresClosure * pg = dsc - > pg ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
uint64_t rowid ;
2022-11-02 12:17:05 +01:00
struct TALER_Amount history_fee ;
struct GNUNET_TIME_Timestamp ts ;
2022-06-19 14:04:41 +02:00
struct TALER_ReservePublicKeyP reserve_pub ;
2022-11-02 12:17:05 +01:00
struct TALER_ReserveSignatureP reserve_sig ;
2022-06-12 17:23:31 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2022-11-02 12:17:05 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " history_fee " ,
& history_fee ) ,
GNUNET_PQ_result_spec_auto_from_type ( " reserve_pub " ,
& reserve_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " reserve_sig " ,
& reserve_sig ) ,
GNUNET_PQ_result_spec_uint64 ( " history_request_serial_id " ,
2022-06-12 17:23:31 +02:00
& rowid ) ,
2022-11-02 12:17:05 +01:00
GNUNET_PQ_result_spec_timestamp ( " request_timestamp " ,
& ts ) ,
2022-06-12 17:23:31 +02:00
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_GenericReturnValue ret ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
dsc - > status = GNUNET_SYSERR ;
return ;
}
ret = dsc - > cb ( dsc - > cb_cls ,
rowid ,
2022-11-02 12:17:05 +01:00
& history_fee ,
ts ,
& reserve_pub ,
& reserve_sig ) ;
2022-06-12 17:23:31 +02:00
GNUNET_PQ_cleanup_result ( rs ) ;
if ( GNUNET_OK ! = ret )
break ;
}
}
/**
2022-11-02 12:17:05 +01:00
* Select history requests above @ a serial_id in monotonically increasing
2022-06-12 17:23:31 +02:00
* order .
*
* @ param cls closure
* @ param serial_id highest serial ID to exclude ( select strictly larger )
* @ param cb function to call on each result
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2022-11-02 12:17:05 +01:00
postgres_select_history_requests_above_serial_id (
2022-06-12 17:23:31 +02:00
void * cls ,
uint64_t serial_id ,
2022-11-02 12:17:05 +01:00
TALER_EXCHANGEDB_HistoryRequestCallback cb ,
2022-06-12 17:23:31 +02:00
void * cb_cls )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2022-11-02 12:17:05 +01:00
struct HistoryRequestSerialContext dsc = {
2022-06-12 17:23:31 +02:00
. cb = cb ,
. cb_cls = cb_cls ,
. pg = pg ,
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2022-11-02 12:17:05 +01:00
" audit_get_history_requests_incr " ,
2022-06-12 17:23:31 +02:00
params ,
2022-11-02 12:17:05 +01:00
& history_request_serial_helper_cb ,
2022-06-12 17:23:31 +02:00
& dsc ) ;
if ( GNUNET_OK ! = dsc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2022-06-15 22:31:44 +02:00
/**
2022-11-02 12:17:05 +01:00
* Closure for # purse_decision_serial_helper_cb ( ) .
2022-06-15 22:31:44 +02:00
*/
2022-11-02 12:17:05 +01:00
struct PurseDecisionSerialContext
2022-06-15 22:31:44 +02:00
{
/**
* Callback to call .
*/
2022-11-02 12:17:05 +01:00
TALER_EXCHANGEDB_PurseDecisionCallback cb ;
2022-06-15 22:31:44 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
*/
enum GNUNET_GenericReturnValue status ;
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
2022-11-02 12:17:05 +01:00
* @ param cls closure of type ` struct PurseRefundSerialContext `
2022-06-15 22:31:44 +02:00
* @ param result the postgres result
* @ param num_results the number of results in @ a result
*/
static void
2022-11-02 12:17:05 +01:00
purse_decision_serial_helper_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
2022-06-15 22:31:44 +02:00
{
2022-11-02 12:17:05 +01:00
struct PurseDecisionSerialContext * dsc = cls ;
2022-06-15 22:31:44 +02:00
struct PostgresClosure * pg = dsc - > pg ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
struct TALER_PurseContractPublicKeyP purse_pub ;
2022-11-02 12:17:05 +01:00
struct TALER_ReservePublicKeyP reserve_pub ;
bool no_reserve = true ;
2022-06-15 22:31:44 +02:00
uint64_t rowid ;
2022-11-02 12:17:05 +01:00
struct TALER_Amount val ;
2022-06-15 22:31:44 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " purse_pub " ,
& purse_pub ) ,
2022-11-02 12:17:05 +01:00
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ( " reserve_pub " ,
& reserve_pub ) ,
& no_reserve ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
& val ) ,
GNUNET_PQ_result_spec_uint64 ( " purse_deposit_serial_id " ,
2022-06-15 22:31:44 +02:00
& rowid ) ,
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_GenericReturnValue ret ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
dsc - > status = GNUNET_SYSERR ;
return ;
}
ret = dsc - > cb ( dsc - > cb_cls ,
rowid ,
& purse_pub ,
2022-11-02 12:17:05 +01:00
no_reserve ? NULL : & reserve_pub ,
& val ) ;
2022-06-15 22:31:44 +02:00
GNUNET_PQ_cleanup_result ( rs ) ;
if ( GNUNET_OK ! = ret )
break ;
}
}
2022-06-15 20:49:39 +02:00
/**
2022-11-02 12:17:05 +01:00
* Select purse decisions above @ a serial_id in monotonically increasing
2022-06-15 20:49:39 +02:00
* order .
*
* @ param cls closure
* @ param serial_id highest serial ID to exclude ( select strictly larger )
2022-11-02 12:17:05 +01:00
* @ param refunded which refund status to select for
2022-06-15 20:49:39 +02:00
* @ param cb function to call on each result
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2022-11-02 12:17:05 +01:00
postgres_select_purse_decisions_above_serial_id (
2022-06-15 20:49:39 +02:00
void * cls ,
uint64_t serial_id ,
2022-11-02 12:17:05 +01:00
bool refunded ,
TALER_EXCHANGEDB_PurseDecisionCallback cb ,
2022-06-15 20:49:39 +02:00
void * cb_cls )
{
2022-06-15 22:31:44 +02:00
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
2022-11-02 12:17:05 +01:00
GNUNET_PQ_query_param_bool ( refunded ) ,
2022-06-15 22:31:44 +02:00
GNUNET_PQ_query_param_end
} ;
2022-11-02 12:17:05 +01:00
struct PurseDecisionSerialContext dsc = {
2022-06-15 22:31:44 +02:00
. cb = cb ,
. cb_cls = cb_cls ,
. pg = pg ,
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2022-11-02 12:17:05 +01:00
" audit_get_purse_decisions_incr " ,
2022-06-15 22:31:44 +02:00
params ,
2022-11-02 12:17:05 +01:00
& purse_decision_serial_helper_cb ,
2022-06-15 22:31:44 +02:00
& dsc ) ;
if ( GNUNET_OK ! = dsc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
/**
2022-11-02 12:17:05 +01:00
* Closure for # purse_refund_coin_helper_cb ( ) .
2022-06-15 22:31:44 +02:00
*/
2022-11-02 12:17:05 +01:00
struct PurseRefundCoinContext
2022-06-15 22:31:44 +02:00
{
/**
* Callback to call .
*/
2022-11-02 12:17:05 +01:00
TALER_EXCHANGEDB_PurseRefundCoinCallback cb ;
2022-06-15 22:31:44 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
*/
enum GNUNET_GenericReturnValue status ;
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
2022-11-02 12:17:05 +01:00
* @ param cls closure of type ` struct PurseRefundCoinContext `
2022-06-15 22:31:44 +02:00
* @ param result the postgres result
* @ param num_results the number of results in @ a result
*/
static void
2022-11-02 12:17:05 +01:00
purse_refund_coin_helper_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
2022-06-15 22:31:44 +02:00
{
2022-11-02 12:17:05 +01:00
struct PurseRefundCoinContext * dsc = cls ;
2022-06-15 22:31:44 +02:00
struct PostgresClosure * pg = dsc - > pg ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
2022-11-02 12:17:05 +01:00
struct TALER_Amount amount_with_fee ;
struct TALER_CoinSpendPublicKeyP coin_pub ;
struct TALER_DenominationPublicKey denom_pub ;
2022-06-15 22:31:44 +02:00
uint64_t rowid ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2022-11-02 12:17:05 +01:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
2022-06-15 22:31:44 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
2022-11-02 12:17:05 +01:00
& amount_with_fee ) ,
GNUNET_PQ_result_spec_auto_from_type ( " coin_pub " ,
& coin_pub ) ,
GNUNET_PQ_result_spec_uint64 ( " purse_deposit_serial_id " ,
2022-06-15 22:31:44 +02:00
& rowid ) ,
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_GenericReturnValue ret ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
dsc - > status = GNUNET_SYSERR ;
return ;
}
ret = dsc - > cb ( dsc - > cb_cls ,
rowid ,
2022-11-02 12:17:05 +01:00
& amount_with_fee ,
& coin_pub ,
& denom_pub ) ;
2022-06-15 22:31:44 +02:00
GNUNET_PQ_cleanup_result ( rs ) ;
if ( GNUNET_OK ! = ret )
break ;
}
2022-06-15 20:49:39 +02:00
}
/**
2022-11-02 12:17:05 +01:00
* Select coin affected by purse refund .
2022-06-15 20:49:39 +02:00
*
* @ param cls closure
2022-11-02 12:17:05 +01:00
* @ param purse_pub purse that was refunded
2022-06-15 20:49:39 +02:00
* @ param cb function to call on each result
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2022-11-02 12:17:05 +01:00
postgres_select_purse_deposits_by_purse (
2022-06-15 20:49:39 +02:00
void * cls ,
2022-11-02 12:17:05 +01:00
const struct TALER_PurseContractPublicKeyP * purse_pub ,
TALER_EXCHANGEDB_PurseRefundCoinCallback cb ,
2022-06-15 20:49:39 +02:00
void * cb_cls )
{
2022-06-15 22:31:44 +02:00
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
2022-11-02 12:17:05 +01:00
GNUNET_PQ_query_param_auto_from_type ( purse_pub ) ,
2022-06-15 22:31:44 +02:00
GNUNET_PQ_query_param_end
} ;
2022-11-02 12:17:05 +01:00
struct PurseRefundCoinContext dsc = {
2022-06-15 22:31:44 +02:00
. cb = cb ,
. cb_cls = cb_cls ,
. pg = pg ,
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2022-11-02 12:17:05 +01:00
" audit_get_purse_deposits_by_purse " ,
2022-06-15 22:31:44 +02:00
params ,
2022-11-02 12:17:05 +01:00
& purse_refund_coin_helper_cb ,
2022-06-15 22:31:44 +02:00
& dsc ) ;
if ( GNUNET_OK ! = dsc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
/**
2022-11-02 12:17:05 +01:00
* Closure for # refreshs_serial_helper_cb ( ) .
2022-06-15 22:31:44 +02:00
*/
2022-11-02 12:17:05 +01:00
struct RefreshsSerialContext
2022-06-15 22:31:44 +02:00
{
/**
* Callback to call .
*/
2022-11-02 12:17:05 +01:00
TALER_EXCHANGEDB_RefreshesCallback cb ;
2022-06-15 22:31:44 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
*/
enum GNUNET_GenericReturnValue status ;
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
2022-11-02 12:17:05 +01:00
* @ param cls closure of type ` struct RefreshsSerialContext `
2022-06-15 22:31:44 +02:00
* @ param result the postgres result
* @ param num_results the number of results in @ a result
*/
static void
2022-11-02 12:17:05 +01:00
refreshs_serial_helper_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
2022-06-15 22:31:44 +02:00
{
2022-11-02 12:17:05 +01:00
struct RefreshsSerialContext * rsc = cls ;
struct PostgresClosure * pg = rsc - > pg ;
2022-06-15 22:31:44 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
2022-11-02 12:17:05 +01:00
struct TALER_DenominationPublicKey denom_pub ;
struct TALER_CoinSpendPublicKeyP coin_pub ;
struct TALER_CoinSpendSignatureP coin_sig ;
struct TALER_AgeCommitmentHash h_age_commitment ;
bool ac_isnull ;
struct TALER_Amount amount_with_fee ;
uint32_t noreveal_index ;
2022-06-15 22:31:44 +02:00
uint64_t rowid ;
2022-11-02 12:17:05 +01:00
struct TALER_RefreshCommitmentP rc ;
2022-06-15 22:31:44 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2022-11-02 12:17:05 +01:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ( " age_commitment_hash " ,
& h_age_commitment ) ,
& ac_isnull ) ,
GNUNET_PQ_result_spec_auto_from_type ( " old_coin_pub " ,
& coin_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " old_coin_sig " ,
& coin_sig ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
& amount_with_fee ) ,
GNUNET_PQ_result_spec_uint32 ( " noreveal_index " ,
& noreveal_index ) ,
GNUNET_PQ_result_spec_uint64 ( " melt_serial_id " ,
2022-06-15 22:31:44 +02:00
& rowid ) ,
2022-11-02 12:17:05 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " rc " ,
& rc ) ,
2022-06-15 22:31:44 +02:00
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_GenericReturnValue ret ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
2022-11-02 12:17:05 +01:00
rsc - > status = GNUNET_SYSERR ;
2022-06-15 22:31:44 +02:00
return ;
}
2022-11-02 12:17:05 +01:00
ret = rsc - > cb ( rsc - > cb_cls ,
2019-08-17 21:35:21 +02:00
rowid ,
& denom_pub ,
2022-02-16 22:01:05 +01:00
ac_isnull ? NULL : & h_age_commitment ,
2019-08-17 21:35:21 +02:00
& coin_pub ,
& coin_sig ,
& amount_with_fee ,
noreveal_index ,
& rc ) ;
2017-03-05 18:18:23 +01:00
GNUNET_PQ_cleanup_result ( rs ) ;
2017-04-04 15:38:58 +02:00
if ( GNUNET_OK ! = ret )
break ;
2016-10-17 16:39:56 +02:00
}
2016-10-09 01:17:37 +02:00
}
/**
2017-06-24 16:15:42 +02:00
* Select refresh sessions above @ a serial_id in monotonically increasing
2016-10-09 01:17:37 +02:00
* order .
*
* @ param cls closure
* @ param serial_id highest serial ID to exclude ( select strictly larger )
* @ param cb function to call on each result
* @ param cb_cls closure for @ a cb
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2016-10-09 01:17:37 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_refreshes_above_serial_id (
void * cls ,
uint64_t serial_id ,
TALER_EXCHANGEDB_RefreshesCallback cb ,
void * cb_cls )
2016-10-09 01:17:37 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2016-10-17 16:39:56 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2017-06-24 16:15:42 +02:00
struct RefreshsSerialContext rsc = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2017-06-24 16:15:42 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2017-04-04 15:38:58 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" audit_get_refresh_commitments_incr " ,
params ,
& refreshs_serial_helper_cb ,
& rsc ) ;
2017-06-24 16:15:42 +02:00
if ( GNUNET_OK ! = rsc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2016-10-17 16:39:56 +02:00
2017-06-24 16:15:42 +02:00
/**
* Closure for # refunds_serial_helper_cb ( ) .
*/
struct RefundsSerialContext
{
/**
* Callback to call .
*/
TALER_EXCHANGEDB_RefundCallback cb ;
2017-09-26 12:30:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2017-09-26 12:30:24 +02:00
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2017-06-24 16:15:42 +02:00
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
2017-09-26 12:30:24 +02:00
*/
2022-03-20 02:38:48 +01:00
enum GNUNET_GenericReturnValue status ;
2017-06-24 16:15:42 +02:00
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
* @ param cls closure of type ` struct RefundsSerialContext `
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2017-06-24 16:15:42 +02:00
*/
static void
refunds_serial_helper_cb ( void * cls ,
2019-08-17 21:35:21 +02:00
PGresult * result ,
unsigned int num_results )
2017-06-24 16:15:42 +02:00
{
struct RefundsSerialContext * rsc = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = rsc - > pg ;
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2016-10-17 16:39:56 +02:00
{
struct TALER_EXCHANGEDB_Refund refund ;
2017-03-19 01:55:37 +01:00
struct TALER_DenominationPublicKey denom_pub ;
2016-11-17 14:59:44 +01:00
uint64_t rowid ;
2022-06-13 15:31:52 +02:00
bool full_refund ;
2016-10-17 16:39:56 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " merchant_pub " ,
2020-01-16 23:49:34 +01:00
& refund . details . merchant_pub ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " merchant_sig " ,
2020-01-16 23:49:34 +01:00
& refund . details . merchant_sig ) ,
2017-05-29 01:15:41 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " h_contract_terms " ,
2020-01-16 23:49:34 +01:00
& refund . details . h_contract_terms ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_uint64 ( " rtransaction_id " ,
2020-01-16 23:49:34 +01:00
& refund . details . rtransaction_id ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " coin_pub " ,
2019-08-25 16:18:24 +02:00
& refund . coin . coin_pub ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
2020-01-16 23:49:34 +01:00
& refund . details . refund_amount ) ,
2016-11-17 14:59:44 +01:00
GNUNET_PQ_result_spec_uint64 ( " refund_serial_id " ,
& rowid ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_end
} ;
2022-03-26 10:46:37 +01:00
enum GNUNET_GenericReturnValue ret ;
2017-09-26 12:30:24 +02:00
2016-10-17 16:39:56 +02:00
if ( GNUNET_OK ! =
2016-11-17 15:12:01 +01:00
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
2016-10-17 16:39:56 +02:00
{
GNUNET_break ( 0 ) ;
2017-06-24 16:15:42 +02:00
rsc - > status = GNUNET_SYSERR ;
return ;
2016-10-17 16:39:56 +02:00
}
2022-06-13 15:31:52 +02:00
{
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & rowid ) ,
GNUNET_PQ_query_param_end
} ;
struct TALER_Amount amount_with_fee ;
uint64_t s_f ;
uint64_t s_v ;
struct GNUNET_PQ_ResultSpec rs2 [ ] = {
GNUNET_PQ_result_spec_uint64 ( " s_v " ,
& s_v ) ,
GNUNET_PQ_result_spec_uint64 ( " s_f " ,
& s_f ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
& amount_with_fee ) ,
GNUNET_PQ_result_spec_end
} ;
enum GNUNET_DB_QueryStatus qs ;
qs = GNUNET_PQ_eval_prepared_singleton_select (
pg - > conn ,
" test_refund_full " ,
params ,
rs2 ) ;
if ( qs < = 0 )
{
GNUNET_break ( 0 ) ;
rsc - > status = GNUNET_SYSERR ;
return ;
}
/* normalize */
s_v + = s_f / TALER_AMOUNT_FRAC_BASE ;
s_f % = TALER_AMOUNT_FRAC_BASE ;
full_refund = ( s_v > = amount_with_fee . value ) & &
( s_f > = amount_with_fee . fraction ) ;
}
2017-06-24 16:15:42 +02:00
ret = rsc - > cb ( rsc - > cb_cls ,
2019-08-17 21:35:21 +02:00
rowid ,
& denom_pub ,
& refund . coin . coin_pub ,
2020-01-16 23:49:34 +01:00
& refund . details . merchant_pub ,
& refund . details . merchant_sig ,
& refund . details . h_contract_terms ,
refund . details . rtransaction_id ,
2022-06-13 15:31:52 +02:00
full_refund ,
2020-01-16 23:49:34 +01:00
& refund . details . refund_amount ) ;
2017-03-05 18:18:23 +01:00
GNUNET_PQ_cleanup_result ( rs ) ;
2017-04-04 15:38:58 +02:00
if ( GNUNET_OK ! = ret )
break ;
2016-10-17 16:39:56 +02:00
}
2016-10-09 01:17:37 +02:00
}
/**
2017-06-24 16:15:42 +02:00
* Select refunds above @ a serial_id in monotonically increasing
* order .
2016-10-09 01:17:37 +02:00
*
* @ param cls closure
* @ param serial_id highest serial ID to exclude ( select strictly larger )
* @ param cb function to call on each result
* @ param cb_cls closure for @ a cb
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2016-10-09 01:17:37 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_refunds_above_serial_id (
void * cls ,
uint64_t serial_id ,
TALER_EXCHANGEDB_RefundCallback cb ,
void * cb_cls )
2016-10-09 01:17:37 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2016-10-17 16:39:56 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2017-06-24 16:15:42 +02:00
struct RefundsSerialContext rsc = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2017-06-24 16:15:42 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2016-10-17 16:39:56 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" audit_get_refunds_incr " ,
params ,
& refunds_serial_helper_cb ,
& rsc ) ;
2017-06-24 16:15:42 +02:00
if ( GNUNET_OK ! = rsc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
/**
* Closure for # reserves_in_serial_helper_cb ( ) .
*/
struct ReservesInSerialContext
{
/**
* Callback to call .
*/
TALER_EXCHANGEDB_ReserveInCallback cb ;
2017-09-26 12:30:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2017-09-26 12:30:24 +02:00
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2019-08-25 16:18:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
2017-09-26 12:30:24 +02:00
*/
2022-03-20 02:38:48 +01:00
enum GNUNET_GenericReturnValue status ;
2017-06-24 16:15:42 +02:00
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
* @ param cls closure of type ` struct ReservesInSerialContext `
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2017-06-24 16:15:42 +02:00
*/
static void
reserves_in_serial_helper_cb ( void * cls ,
2019-08-17 21:35:21 +02:00
PGresult * result ,
unsigned int num_results )
2017-06-24 16:15:42 +02:00
{
struct ReservesInSerialContext * risc = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = risc - > pg ;
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2016-10-17 16:39:56 +02:00
{
struct TALER_ReservePublicKeyP reserve_pub ;
struct TALER_Amount credit ;
2018-04-02 14:24:45 +02:00
char * sender_account_details ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp execution_date ;
2016-11-17 14:59:44 +01:00
uint64_t rowid ;
2020-01-11 15:19:56 +01:00
uint64_t wire_reference ;
2016-10-17 16:39:56 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2016-10-20 23:28:36 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " reserve_pub " ,
2016-10-17 16:39:56 +02:00
& reserve_pub ) ,
2020-01-11 15:19:56 +01:00
GNUNET_PQ_result_spec_uint64 ( " wire_reference " ,
& wire_reference ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " credit " ,
2016-10-17 16:39:56 +02:00
& credit ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " execution_date " ,
& execution_date ) ,
2018-04-02 14:24:45 +02:00
GNUNET_PQ_result_spec_string ( " sender_account_details " ,
& sender_account_details ) ,
2016-11-17 14:59:44 +01:00
GNUNET_PQ_result_spec_uint64 ( " reserve_in_serial_id " ,
& rowid ) ,
2016-10-24 12:40:28 +02:00
GNUNET_PQ_result_spec_end
2016-10-17 16:39:56 +02:00
} ;
2022-03-20 02:38:48 +01:00
enum GNUNET_GenericReturnValue ret ;
2016-10-17 16:39:56 +02:00
if ( GNUNET_OK ! =
2016-11-17 15:12:01 +01:00
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
2016-10-17 16:39:56 +02:00
{
GNUNET_break ( 0 ) ;
2017-06-24 16:15:42 +02:00
risc - > status = GNUNET_SYSERR ;
return ;
2016-10-17 16:39:56 +02:00
}
2017-06-24 16:15:42 +02:00
ret = risc - > cb ( risc - > cb_cls ,
2019-08-17 21:35:21 +02:00
rowid ,
& reserve_pub ,
& credit ,
sender_account_details ,
wire_reference ,
execution_date ) ;
2017-03-05 18:18:23 +01:00
GNUNET_PQ_cleanup_result ( rs ) ;
2017-04-04 15:38:58 +02:00
if ( GNUNET_OK ! = ret )
break ;
2016-10-17 16:39:56 +02:00
}
2016-10-09 01:17:37 +02:00
}
/**
2017-06-24 16:15:42 +02:00
* Select inbound wire transfers into reserves_in above @ a serial_id
2016-10-09 01:17:37 +02:00
* in monotonically increasing order .
*
* @ param cls closure
* @ param serial_id highest serial ID to exclude ( select strictly larger )
* @ param cb function to call on each result
* @ param cb_cls closure for @ a cb
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2016-10-09 01:17:37 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_reserves_in_above_serial_id (
void * cls ,
uint64_t serial_id ,
TALER_EXCHANGEDB_ReserveInCallback cb ,
void * cb_cls )
2016-10-09 01:17:37 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2016-10-17 16:39:56 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2017-06-24 16:15:42 +02:00
struct ReservesInSerialContext risc = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2017-06-24 16:15:42 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2017-09-26 12:30:24 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" audit_reserves_in_get_transactions_incr " ,
params ,
& reserves_in_serial_helper_cb ,
& risc ) ;
2017-06-24 16:15:42 +02:00
if ( GNUNET_OK ! = risc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2016-10-17 16:39:56 +02:00
2017-06-24 16:15:42 +02:00
2018-04-02 21:12:18 +02:00
/**
* Select inbound wire transfers into reserves_in above @ a serial_id
* in monotonically increasing order by account .
*
* @ param cls closure
* @ param account_name name of the account to select by
* @ param serial_id highest serial ID to exclude ( select strictly larger )
* @ param cb function to call on each result
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_reserves_in_above_serial_id_by_account (
void * cls ,
const char * account_name ,
uint64_t serial_id ,
TALER_EXCHANGEDB_ReserveInCallback cb ,
void * cb_cls )
2018-04-02 21:12:18 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2018-04-02 21:12:18 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_string ( account_name ) ,
GNUNET_PQ_query_param_end
} ;
struct ReservesInSerialContext risc = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2018-04-02 21:12:18 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" audit_reserves_in_get_transactions_incr_by_account " ,
params ,
& reserves_in_serial_helper_cb ,
& risc ) ;
2018-04-02 21:12:18 +02:00
if ( GNUNET_OK ! = risc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2017-06-24 16:15:42 +02:00
/**
* Closure for # reserves_out_serial_helper_cb ( ) .
*/
struct ReservesOutSerialContext
{
/**
* Callback to call .
*/
TALER_EXCHANGEDB_WithdrawCallback cb ;
2017-09-26 12:30:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2017-09-26 12:30:24 +02:00
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2019-08-25 16:18:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
2017-09-26 12:30:24 +02:00
*/
2022-03-20 02:38:48 +01:00
enum GNUNET_GenericReturnValue status ;
2017-06-24 16:15:42 +02:00
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
* @ param cls closure of type ` struct ReservesOutSerialContext `
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2017-06-24 16:15:42 +02:00
*/
static void
reserves_out_serial_helper_cb ( void * cls ,
2019-08-17 21:35:21 +02:00
PGresult * result ,
unsigned int num_results )
2017-06-24 16:15:42 +02:00
{
struct ReservesOutSerialContext * rosc = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = rosc - > pg ;
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2016-10-17 16:39:56 +02:00
{
2022-02-21 00:23:23 +01:00
struct TALER_BlindedCoinHashP h_blind_ev ;
2016-10-17 16:39:56 +02:00
struct TALER_DenominationPublicKey denom_pub ;
struct TALER_ReservePublicKeyP reserve_pub ;
struct TALER_ReserveSignatureP reserve_sig ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp execution_date ;
2016-10-17 16:39:56 +02:00
struct TALER_Amount amount_with_fee ;
2016-11-17 14:59:44 +01:00
uint64_t rowid ;
2016-10-17 16:39:56 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " h_blind_ev " ,
& h_blind_ev ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " reserve_pub " ,
& reserve_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " reserve_sig " ,
& reserve_sig ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " execution_date " ,
& execution_date ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
2016-10-17 16:39:56 +02:00
& amount_with_fee ) ,
2016-11-17 14:59:44 +01:00
GNUNET_PQ_result_spec_uint64 ( " reserve_out_serial_id " ,
& rowid ) ,
2016-10-17 16:39:56 +02:00
GNUNET_PQ_result_spec_end
} ;
2022-03-20 02:38:48 +01:00
enum GNUNET_GenericReturnValue ret ;
2017-09-26 12:30:24 +02:00
2016-10-17 16:39:56 +02:00
if ( GNUNET_OK ! =
2016-11-17 15:12:01 +01:00
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
2016-10-17 16:39:56 +02:00
{
GNUNET_break ( 0 ) ;
2017-06-24 16:15:42 +02:00
rosc - > status = GNUNET_SYSERR ;
return ;
2016-10-17 16:39:56 +02:00
}
2017-06-24 16:15:42 +02:00
ret = rosc - > cb ( rosc - > cb_cls ,
2019-08-17 21:35:21 +02:00
rowid ,
& h_blind_ev ,
& denom_pub ,
& reserve_pub ,
& reserve_sig ,
execution_date ,
& amount_with_fee ) ;
2017-03-05 18:18:23 +01:00
GNUNET_PQ_cleanup_result ( rs ) ;
2017-04-04 15:38:58 +02:00
if ( GNUNET_OK ! = ret )
break ;
2016-10-17 16:39:56 +02:00
}
2016-10-09 01:17:37 +02:00
}
/**
2017-06-24 16:15:42 +02:00
* Select withdraw operations from reserves_out above @ a serial_id
* in monotonically increasing order .
2016-10-09 01:17:37 +02:00
*
* @ param cls closure
* @ param serial_id highest serial ID to exclude ( select strictly larger )
2017-06-24 16:15:42 +02:00
* @ param cb function to call on each result
2016-10-09 01:17:37 +02:00
* @ param cb_cls closure for @ a cb
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2016-10-09 01:17:37 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_withdrawals_above_serial_id (
void * cls ,
uint64_t serial_id ,
TALER_EXCHANGEDB_WithdrawCallback cb ,
void * cb_cls )
2016-10-09 01:17:37 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2016-10-17 17:24:38 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2017-06-24 16:15:42 +02:00
struct ReservesOutSerialContext rosc = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2017-06-24 16:15:42 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" audit_get_reserves_out_incr " ,
params ,
& reserves_out_serial_helper_cb ,
& rosc ) ;
2017-06-24 16:15:42 +02:00
if ( GNUNET_OK ! = rosc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
/**
* Closure for # wire_out_serial_helper_cb ( ) .
*/
struct WireOutSerialContext
{
2017-04-04 15:38:58 +02:00
2017-06-24 16:15:42 +02:00
/**
* Callback to call .
*/
TALER_EXCHANGEDB_WireTransferOutCallback cb ;
2017-09-26 12:30:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2017-09-26 12:30:24 +02:00
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2017-06-24 16:15:42 +02:00
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
2017-09-26 12:30:24 +02:00
*/
2017-06-24 16:15:42 +02:00
int status ;
} ;
2016-10-17 17:24:38 +02:00
2017-06-24 16:15:42 +02:00
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
* @ param cls closure of type ` struct WireOutSerialContext `
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2017-06-24 16:15:42 +02:00
*/
static void
wire_out_serial_helper_cb ( void * cls ,
2019-08-17 21:35:21 +02:00
PGresult * result ,
unsigned int num_results )
2017-06-24 16:15:42 +02:00
{
struct WireOutSerialContext * wosc = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = wosc - > pg ;
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2016-10-17 17:24:38 +02:00
{
2017-03-18 02:40:27 +01:00
uint64_t rowid ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp date ;
2017-03-18 02:40:27 +01:00
struct TALER_WireTransferIdentifierRawP wtid ;
2021-10-30 20:49:23 +02:00
char * payto_uri ;
2017-03-18 02:40:27 +01:00
struct TALER_Amount amount ;
2016-10-17 17:24:38 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2017-03-18 02:40:27 +01:00
GNUNET_PQ_result_spec_uint64 ( " wireout_uuid " ,
& rowid ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " execution_date " ,
& date ) ,
2017-03-18 02:40:27 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " wtid_raw " ,
& wtid ) ,
2021-10-30 20:49:23 +02:00
GNUNET_PQ_result_spec_string ( " payto_uri " ,
& payto_uri ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount " ,
2017-03-18 02:40:27 +01:00
& amount ) ,
2016-10-17 17:24:38 +02:00
GNUNET_PQ_result_spec_end
} ;
2017-06-24 16:15:42 +02:00
int ret ;
2016-10-17 17:24:38 +02:00
if ( GNUNET_OK ! =
2016-11-17 14:59:44 +01:00
GNUNET_PQ_extract_result ( result ,
rs ,
2016-11-17 15:12:01 +01:00
i ) )
2016-10-17 17:24:38 +02:00
{
GNUNET_break ( 0 ) ;
2017-06-24 16:15:42 +02:00
wosc - > status = GNUNET_SYSERR ;
return ;
2016-10-17 17:24:38 +02:00
}
2017-06-24 16:15:42 +02:00
ret = wosc - > cb ( wosc - > cb_cls ,
2019-08-17 21:35:21 +02:00
rowid ,
date ,
& wtid ,
2021-10-30 20:49:23 +02:00
payto_uri ,
2019-08-17 21:35:21 +02:00
& amount ) ;
2017-04-04 15:38:58 +02:00
GNUNET_PQ_cleanup_result ( rs ) ;
if ( GNUNET_OK ! = ret )
break ;
}
}
/**
2017-06-24 16:15:42 +02:00
* Function called to select all wire transfers the exchange
* executed .
2017-04-04 15:38:58 +02:00
*
* @ param cls closure
2017-06-24 16:15:42 +02:00
* @ param serial_id highest serial ID to exclude ( select strictly larger )
2017-04-04 15:38:58 +02:00
* @ param cb function to call for ONE unfinished item
* @ param cb_cls closure for @ a cb
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2017-04-04 15:38:58 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_wire_out_above_serial_id (
void * cls ,
uint64_t serial_id ,
TALER_EXCHANGEDB_WireTransferOutCallback cb ,
void * cb_cls )
2017-04-04 15:38:58 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2017-04-04 15:38:58 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2017-06-24 16:15:42 +02:00
struct WireOutSerialContext wosc = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2017-06-24 16:15:42 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2017-04-04 15:38:58 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" audit_get_wire_incr " ,
params ,
& wire_out_serial_helper_cb ,
& wosc ) ;
2017-06-24 16:15:42 +02:00
if ( GNUNET_OK ! = wosc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2018-04-02 21:12:18 +02:00
/**
* Function called to select all wire transfers the exchange
* executed by account .
*
* @ param cls closure
* @ param account_name account to select
* @ param serial_id highest serial ID to exclude ( select strictly larger )
* @ param cb function to call for ONE unfinished item
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_wire_out_above_serial_id_by_account (
void * cls ,
const char * account_name ,
uint64_t serial_id ,
TALER_EXCHANGEDB_WireTransferOutCallback cb ,
void * cb_cls )
2018-04-02 21:12:18 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2018-04-02 21:12:18 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_string ( account_name ) ,
GNUNET_PQ_query_param_end
} ;
struct WireOutSerialContext wosc = {
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2018-04-02 21:12:18 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" audit_get_wire_incr_by_account " ,
params ,
& wire_out_serial_helper_cb ,
& wosc ) ;
2018-04-02 21:12:18 +02:00
if ( GNUNET_OK ! = wosc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2017-06-24 16:15:42 +02:00
/**
2020-01-18 23:49:37 +01:00
* Closure for # recoup_serial_helper_cb ( ) .
2017-06-24 16:15:42 +02:00
*/
2020-01-18 23:49:37 +01:00
struct RecoupSerialContext
2017-06-24 16:15:42 +02:00
{
/**
* Callback to call .
*/
2020-01-18 23:49:37 +01:00
TALER_EXCHANGEDB_RecoupCallback cb ;
2017-09-26 12:30:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2017-09-26 12:30:24 +02:00
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2019-08-25 16:18:24 +02:00
2017-06-24 16:15:42 +02:00
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
2017-09-26 12:30:24 +02:00
*/
2021-09-03 19:08:02 +02:00
enum GNUNET_GenericReturnValue status ;
2017-06-24 16:15:42 +02:00
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
2020-01-18 23:49:37 +01:00
* @ param cls closure of type ` struct RecoupSerialContext `
2017-06-24 16:15:42 +02:00
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2017-06-24 16:15:42 +02:00
*/
static void
2020-01-18 23:49:37 +01:00
recoup_serial_helper_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
2017-06-24 16:15:42 +02:00
{
2020-01-18 23:49:37 +01:00
struct RecoupSerialContext * psc = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = psc - > pg ;
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2017-04-04 15:38:58 +02:00
{
uint64_t rowid ;
struct TALER_ReservePublicKeyP reserve_pub ;
2017-04-04 16:27:27 +02:00
struct TALER_CoinPublicInfo coin ;
2017-04-04 15:38:58 +02:00
struct TALER_CoinSpendSignatureP coin_sig ;
2021-11-05 22:22:47 +01:00
union TALER_DenominationBlindingKeyP coin_blind ;
2017-04-04 15:38:58 +02:00
struct TALER_Amount amount ;
2020-03-26 20:54:41 +01:00
struct TALER_DenominationPublicKey denom_pub ;
2022-02-21 00:23:23 +01:00
struct TALER_BlindedCoinHashP h_blind_ev ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp timestamp ;
2017-04-04 15:38:58 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2020-01-18 23:49:37 +01:00
GNUNET_PQ_result_spec_uint64 ( " recoup_uuid " ,
2017-04-04 15:38:58 +02:00
& rowid ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_result_spec_timestamp ( " recoup_timestamp " ,
2021-12-14 16:04:32 +01:00
& timestamp ) ,
2017-04-04 15:38:58 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " reserve_pub " ,
& reserve_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " coin_pub " ,
2017-04-04 16:27:27 +02:00
& coin . coin_pub ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
2017-04-04 15:38:58 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " coin_sig " ,
& coin_sig ) ,
GNUNET_PQ_result_spec_auto_from_type ( " coin_blind " ,
& coin_blind ) ,
GNUNET_PQ_result_spec_auto_from_type ( " h_blind_ev " ,
& h_blind_ev ) ,
2019-05-02 21:16:51 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
& coin . denom_pub_hash ) ,
2022-03-17 14:16:19 +01:00
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ( " age_commitment_hash " ,
& coin . h_age_commitment ) ,
& coin . no_age_commitment ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_sig ( " denom_sig " ,
& coin . denom_sig ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount " ,
2017-04-04 15:38:58 +02:00
& amount ) ,
GNUNET_PQ_result_spec_end
} ;
2017-06-24 16:15:42 +02:00
int ret ;
2017-04-04 15:38:58 +02:00
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
2017-06-24 16:15:42 +02:00
psc - > status = GNUNET_SYSERR ;
return ;
2017-04-04 15:38:58 +02:00
}
2017-06-24 16:15:42 +02:00
ret = psc - > cb ( psc - > cb_cls ,
2019-07-21 20:15:11 +02:00
rowid ,
timestamp ,
& amount ,
& reserve_pub ,
& coin ,
2019-05-02 21:16:51 +02:00
& denom_pub ,
2019-07-21 20:15:11 +02:00
& coin_sig ,
& coin_blind ) ;
2017-03-05 18:18:23 +01:00
GNUNET_PQ_cleanup_result ( rs ) ;
2017-04-04 15:38:58 +02:00
if ( GNUNET_OK ! = ret )
break ;
2016-10-17 17:24:38 +02:00
}
2016-10-09 01:17:37 +02:00
}
2017-04-19 21:28:47 +02:00
/**
2020-01-18 23:49:37 +01:00
* Function called to select recoup requests the exchange
2017-06-24 16:15:42 +02:00
* received , ordered by serial ID ( monotonically increasing ) .
2017-04-19 21:28:47 +02:00
*
* @ param cls closure
* @ param serial_id lowest serial ID to include ( select larger or equal )
* @ param cb function to call for ONE unfinished item
* @ param cb_cls closure for @ a cb
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2017-04-19 21:28:47 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_recoup_above_serial_id (
void * cls ,
uint64_t serial_id ,
TALER_EXCHANGEDB_RecoupCallback cb ,
void * cb_cls )
2017-04-19 21:28:47 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2017-04-19 21:28:47 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2020-01-18 23:49:37 +01:00
struct RecoupSerialContext psc = {
2017-06-24 16:15:42 +02:00
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2017-06-24 16:15:42 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2017-09-26 12:30:24 +02:00
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2020-01-18 23:49:37 +01:00
" recoup_get_incr " ,
2019-08-25 16:18:24 +02:00
params ,
2020-01-18 23:49:37 +01:00
& recoup_serial_helper_cb ,
2019-08-25 16:18:24 +02:00
& psc ) ;
2017-06-24 16:15:42 +02:00
if ( GNUNET_OK ! = psc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2017-04-19 21:28:47 +02:00
2017-06-24 16:15:42 +02:00
2019-07-21 20:15:11 +02:00
/**
2020-01-18 23:49:37 +01:00
* Closure for # recoup_refresh_serial_helper_cb ( ) .
2019-07-21 20:15:11 +02:00
*/
2020-01-18 23:49:37 +01:00
struct RecoupRefreshSerialContext
2019-07-21 20:15:11 +02:00
{
/**
* Callback to call .
*/
2020-01-18 23:49:37 +01:00
TALER_EXCHANGEDB_RecoupRefreshCallback cb ;
2019-07-21 20:15:11 +02:00
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2019-08-25 16:18:24 +02:00
2019-07-21 20:15:11 +02:00
/**
* Status code , set to # GNUNET_SYSERR on hard errors .
*/
2022-03-23 12:25:22 +01:00
enum GNUNET_GenericReturnValue status ;
2019-07-21 20:15:11 +02:00
} ;
/**
* Helper function to be called with the results of a SELECT statement
* that has returned @ a num_results results .
*
2020-01-18 23:49:37 +01:00
* @ param cls closure of type ` struct RecoupRefreshSerialContext `
2019-07-21 20:15:11 +02:00
* @ param result the postgres result
2020-01-17 22:17:48 +01:00
* @ param num_results the number of results in @ a result
2019-07-21 20:15:11 +02:00
*/
static void
2020-01-18 23:49:37 +01:00
recoup_refresh_serial_helper_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
2019-07-21 20:15:11 +02:00
{
2020-01-18 23:49:37 +01:00
struct RecoupRefreshSerialContext * psc = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = psc - > pg ;
2019-08-25 16:18:24 +02:00
for ( unsigned int i = 0 ; i < num_results ; i + + )
2019-07-21 20:15:11 +02:00
{
uint64_t rowid ;
struct TALER_CoinSpendPublicKeyP old_coin_pub ;
struct TALER_CoinPublicInfo coin ;
struct TALER_CoinSpendSignatureP coin_sig ;
2021-11-05 22:22:47 +01:00
union TALER_DenominationBlindingKeyP coin_blind ;
2019-07-21 20:15:11 +02:00
struct TALER_DenominationPublicKey denom_pub ;
2022-02-21 00:23:23 +01:00
struct TALER_DenominationHashP old_denom_pub_hash ;
2019-07-21 20:15:11 +02:00
struct TALER_Amount amount ;
2022-02-21 00:23:23 +01:00
struct TALER_BlindedCoinHashP h_blind_ev ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp timestamp ;
2019-07-21 20:15:11 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
2020-03-26 20:06:23 +01:00
GNUNET_PQ_result_spec_uint64 ( " recoup_refresh_uuid " ,
2019-07-21 20:15:11 +02:00
& rowid ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_result_spec_timestamp ( " recoup_timestamp " ,
2021-12-14 16:04:32 +01:00
& timestamp ) ,
2019-07-21 20:15:11 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " old_coin_pub " ,
& old_coin_pub ) ,
2020-03-26 20:54:41 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " old_denom_pub_hash " ,
& old_denom_pub_hash ) ,
2019-07-21 20:15:11 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " coin_pub " ,
& coin . coin_pub ) ,
GNUNET_PQ_result_spec_auto_from_type ( " coin_sig " ,
& coin_sig ) ,
GNUNET_PQ_result_spec_auto_from_type ( " coin_blind " ,
& coin_blind ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_pub ( " denom_pub " ,
& denom_pub ) ,
2019-07-21 20:15:11 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " h_blind_ev " ,
& h_blind_ev ) ,
GNUNET_PQ_result_spec_auto_from_type ( " denom_pub_hash " ,
& coin . denom_pub_hash ) ,
2022-03-17 14:16:19 +01:00
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ( " age_commitment_hash " ,
& coin . h_age_commitment ) ,
& coin . no_age_commitment ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_result_spec_denom_sig ( " denom_sig " ,
& coin . denom_sig ) ,
2019-08-17 21:35:21 +02:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount " ,
2019-07-21 20:15:11 +02:00
& amount ) ,
GNUNET_PQ_result_spec_end
} ;
2022-03-17 14:45:12 +01:00
enum GNUNET_GenericReturnValue ret ;
2019-07-21 20:15:11 +02:00
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
psc - > status = GNUNET_SYSERR ;
return ;
}
ret = psc - > cb ( psc - > cb_cls ,
rowid ,
timestamp ,
& amount ,
& old_coin_pub ,
2020-03-26 20:54:41 +01:00
& old_denom_pub_hash ,
2019-07-21 20:15:11 +02:00
& coin ,
& denom_pub ,
& coin_sig ,
& coin_blind ) ;
GNUNET_PQ_cleanup_result ( rs ) ;
if ( GNUNET_OK ! = ret )
break ;
}
}
/**
2020-01-18 23:49:37 +01:00
* Function called to select recoup requests the exchange received for
2019-07-21 20:15:11 +02:00
* refreshed coins , ordered by serial ID ( monotonically increasing ) .
*
* @ param cls closure
* @ param serial_id lowest serial ID to include ( select larger or equal )
* @ param cb function to call for ONE unfinished item
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_select_recoup_refresh_above_serial_id (
void * cls ,
uint64_t serial_id ,
TALER_EXCHANGEDB_RecoupRefreshCallback cb ,
void * cb_cls )
2019-07-21 20:15:11 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2019-07-21 20:15:11 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_uint64 ( & serial_id ) ,
GNUNET_PQ_query_param_end
} ;
2020-01-18 23:49:37 +01:00
struct RecoupRefreshSerialContext psc = {
2019-07-21 20:15:11 +02:00
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2019-07-21 20:15:11 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2020-01-18 23:49:37 +01:00
" recoup_refresh_get_incr " ,
2019-07-21 20:15:11 +02:00
params ,
2020-01-18 23:49:37 +01:00
& recoup_refresh_serial_helper_cb ,
2019-07-21 20:15:11 +02:00
& psc ) ;
if ( GNUNET_OK ! = psc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2017-04-01 23:43:55 +02:00
/**
* Obtain information about which reserve a coin was generated
* from given the hash of the blinded coin .
*
* @ param cls closure
2022-02-17 15:10:14 +01:00
* @ param bch hash that uniquely identifies the withdraw request
2017-04-01 23:43:55 +02:00
* @ param [ out ] reserve_pub set to information about the reserve ( on success only )
2021-12-25 13:56:33 +01:00
* @ param [ out ] reserve_out_serial_id set to row of the @ a h_blind_ev in reserves_out
2017-06-19 17:53:42 +02:00
* @ return transaction status code
2017-04-01 23:43:55 +02:00
*/
2017-06-19 17:53:42 +02:00
static enum GNUNET_DB_QueryStatus
2022-02-17 15:10:14 +01:00
postgres_get_reserve_by_h_blind (
2022-02-15 17:07:13 +01:00
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_BlindedCoinHashP * bch ,
2022-02-15 17:07:13 +01:00
struct TALER_ReservePublicKeyP * reserve_pub ,
uint64_t * reserve_out_serial_id )
2017-04-01 23:43:55 +02:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2017-04-01 23:43:55 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
2022-02-17 15:10:14 +01:00
GNUNET_PQ_query_param_auto_from_type ( bch ) ,
2017-04-01 23:43:55 +02:00
GNUNET_PQ_query_param_end
} ;
2017-06-19 17:53:42 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " reserve_pub " ,
2019-08-17 21:35:21 +02:00
reserve_pub ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_result_spec_uint64 ( " reserve_out_serial_id " ,
reserve_out_serial_id ) ,
2017-06-19 17:53:42 +02:00
GNUNET_PQ_result_spec_end
} ;
2017-04-01 23:43:55 +02:00
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2022-02-17 15:10:14 +01:00
" reserve_by_h_blind " ,
2019-07-23 20:27:41 +02:00
params ,
rs ) ;
}
/**
* Obtain information about which old coin a coin was refreshed
* given the hash of the blinded ( fresh ) coin .
*
* @ param cls closure
* @ param h_blind_ev hash of the blinded coin
2020-01-18 13:23:10 +01:00
* @ param [ out ] old_coin_pub set to information about the old coin ( on success only )
2022-02-12 11:12:33 +01:00
* @ param [ out ] rrc_serial set to serial number of the entry in the database
2019-07-23 20:27:41 +02:00
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2021-12-25 13:56:33 +01:00
postgres_get_old_coin_by_h_blind (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_BlindedCoinHashP * h_blind_ev ,
2021-12-25 13:56:33 +01:00
struct TALER_CoinSpendPublicKeyP * old_coin_pub ,
uint64_t * rrc_serial )
2019-07-23 20:27:41 +02:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2019-07-23 20:27:41 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( h_blind_ev ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " old_coin_pub " ,
old_coin_pub ) ,
2021-12-25 13:56:33 +01:00
GNUNET_PQ_result_spec_uint64 ( " rrc_serial " ,
rrc_serial ) ,
2019-07-23 20:27:41 +02:00
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-07-23 20:27:41 +02:00
" old_coin_by_h_blind " ,
params ,
rs ) ;
2017-04-01 23:43:55 +02:00
}
2017-04-08 22:01:13 +02:00
/**
* Store information that a denomination key was revoked
* in the database .
*
* @ param cls closure
* @ param denom_pub_hash hash of the revoked denomination key
* @ param master_sig signature affirming the revocation
2017-06-23 13:16:12 +02:00
* @ return transaction status code
2017-04-08 22:01:13 +02:00
*/
2017-06-23 13:16:12 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_insert_denomination_revocation (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_DenominationHashP * denom_pub_hash ,
2020-03-07 00:28:07 +01:00
const struct TALER_MasterSignatureP * master_sig )
2017-04-08 22:01:13 +02:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2017-04-08 22:01:13 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( denom_pub_hash ) ,
GNUNET_PQ_query_param_auto_from_type ( master_sig ) ,
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" denomination_revocation_insert " ,
params ) ;
2017-04-08 22:01:13 +02:00
}
/**
* Obtain information about a denomination key ' s revocation from
* the database .
*
* @ param cls closure
* @ param denom_pub_hash hash of the revoked denomination key
* @ param [ out ] master_sig signature affirming the revocation
2017-04-16 17:21:26 +02:00
* @ param [ out ] rowid row where the information is stored
2017-06-24 16:15:42 +02:00
* @ return transaction status code
2017-04-08 22:01:13 +02:00
*/
2017-06-24 16:15:42 +02:00
static enum GNUNET_DB_QueryStatus
2020-03-07 00:28:07 +01:00
postgres_get_denomination_revocation (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_DenominationHashP * denom_pub_hash ,
2020-03-07 00:28:07 +01:00
struct TALER_MasterSignatureP * master_sig ,
uint64_t * rowid )
2017-04-08 22:01:13 +02:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2017-04-08 22:01:13 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( denom_pub_hash ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2022-03-04 00:30:43 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
master_sig ) ,
GNUNET_PQ_result_spec_uint64 ( " denom_revocations_serial_id " ,
rowid ) ,
2017-04-08 22:01:13 +02:00
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2019-08-17 21:35:21 +02:00
" denomination_revocation_get " ,
params ,
rs ) ;
2017-04-08 22:01:13 +02:00
}
2017-10-16 17:25:13 +02:00
/**
* Closure for # missing_wire_cb ( ) .
*/
struct MissingWireContext
{
/**
* Function to call per result .
*/
TALER_EXCHANGEDB_WireMissingCallback cb ;
/**
* Closure for @ e cb .
*/
void * cb_cls ;
2019-08-17 21:35:21 +02:00
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
2019-08-25 16:18:24 +02:00
2017-10-16 17:25:13 +02:00
/**
* Set to # GNUNET_SYSERR on error .
*/
2022-03-23 12:25:22 +01:00
enum GNUNET_GenericReturnValue status ;
2017-10-16 17:25:13 +02:00
} ;
/**
* Invoke the callback for each result .
*
* @ param cls a ` struct MissingWireContext * `
* @ param result SQL result
* @ param num_results number of rows in @ a result
*/
static void
missing_wire_cb ( void * cls ,
2019-08-17 21:35:21 +02:00
PGresult * result ,
unsigned int num_results )
2017-10-16 17:25:13 +02:00
{
struct MissingWireContext * mwc = cls ;
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = mwc - > pg ;
2017-10-16 17:25:13 +02:00
while ( 0 < num_results )
{
uint64_t rowid ;
struct TALER_CoinSpendPublicKeyP coin_pub ;
struct TALER_Amount amount ;
2021-10-30 20:49:23 +02:00
char * payto_uri ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp deadline ;
2021-12-05 17:16:00 +01:00
bool done ;
2017-10-16 17:25:13 +02:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " deposit_serial_id " ,
2019-08-17 21:35:21 +02:00
& rowid ) ,
2017-10-16 17:25:13 +02:00
GNUNET_PQ_result_spec_auto_from_type ( " coin_pub " ,
2019-08-17 21:35:21 +02:00
& coin_pub ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
& amount ) ,
2021-10-30 20:49:23 +02:00
GNUNET_PQ_result_spec_string ( " payto_uri " ,
& payto_uri ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " wire_deadline " ,
& deadline ) ,
2021-12-05 17:16:00 +01:00
GNUNET_PQ_result_spec_bool ( " done " ,
& done ) ,
2017-10-16 17:25:13 +02:00
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
2019-08-25 16:18:24 +02:00
GNUNET_PQ_extract_result ( result ,
rs ,
- - num_results ) )
2017-10-16 17:25:13 +02:00
{
GNUNET_break ( 0 ) ;
mwc - > status = GNUNET_SYSERR ;
return ;
}
mwc - > cb ( mwc - > cb_cls ,
2019-08-17 21:35:21 +02:00
rowid ,
& coin_pub ,
& amount ,
2021-10-30 20:49:23 +02:00
payto_uri ,
2019-08-17 21:35:21 +02:00
deadline ,
done ) ;
2017-10-16 17:25:13 +02:00
GNUNET_PQ_cleanup_result ( rs ) ;
}
}
/**
* Select all of those deposits in the database for which we do
* not have a wire transfer ( or a refund ) and which should have
* been deposited between @ a start_date and @ a end_date .
*
* @ param cls closure
* @ param start_date lower bound on the requested wire execution date
* @ param end_date upper bound on the requested wire execution date
* @ param cb function to call on all such deposits
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_select_deposits_missing_wire ( void * cls ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp start_date ,
struct GNUNET_TIME_Timestamp end_date ,
2019-08-17 21:35:21 +02:00
TALER_EXCHANGEDB_WireMissingCallback cb ,
void * cb_cls )
2017-10-16 17:25:13 +02:00
{
2019-08-17 21:35:21 +02:00
struct PostgresClosure * pg = cls ;
2017-10-16 17:25:13 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & start_date ) ,
GNUNET_PQ_query_param_timestamp ( & end_date ) ,
2017-10-16 17:25:13 +02:00
GNUNET_PQ_query_param_end
} ;
2019-08-25 16:18:24 +02:00
struct MissingWireContext mwc = {
2017-10-16 17:25:13 +02:00
. cb = cb ,
. cb_cls = cb_cls ,
2019-08-17 21:35:21 +02:00
. pg = pg ,
2017-10-16 17:25:13 +02:00
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2019-08-25 16:18:24 +02:00
" deposits_get_overdue " ,
params ,
& missing_wire_cb ,
& mwc ) ;
2017-10-16 17:25:13 +02:00
if ( GNUNET_OK ! = mwc . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2020-11-29 16:21:10 +01:00
/**
* Check the last date an auditor was modified .
*
* @ param cls closure
* @ param auditor_pub key to look up information for
* @ param [ out ] last_date last modification date to auditor status
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_lookup_auditor_timestamp (
void * cls ,
const struct TALER_AuditorPublicKeyP * auditor_pub ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp * last_date )
2020-11-29 16:21:10 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-29 16:21:10 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( auditor_pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " last_change " ,
last_date ) ,
2020-11-29 16:21:10 +01:00
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2020-11-29 16:21:10 +01:00
" lookup_auditor_timestamp " ,
params ,
rs ) ;
}
/**
* Lookup current state of an auditor .
*
* @ param cls closure
* @ param auditor_pub key to look up information for
2020-11-30 14:16:42 +01:00
* @ param [ out ] auditor_url set to the base URL of the auditor ' s REST API ; memory to be
2020-11-29 16:21:10 +01:00
* released by the caller !
* @ param [ out ] enabled set if the auditor is currently in use
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2021-08-23 00:00:32 +02:00
postgres_lookup_auditor_status (
void * cls ,
const struct TALER_AuditorPublicKeyP * auditor_pub ,
char * * auditor_url ,
bool * enabled )
2020-11-29 16:21:10 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-29 16:21:10 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( auditor_pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_string ( " auditor_url " ,
auditor_url ) ,
2021-12-05 17:16:00 +01:00
GNUNET_PQ_result_spec_bool ( " is_active " ,
enabled ) ,
2020-11-29 16:21:10 +01:00
GNUNET_PQ_result_spec_end
} ;
2021-12-05 17:16:00 +01:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" lookup_auditor_status " ,
params ,
rs ) ;
2020-11-29 16:21:10 +01:00
}
/**
* Insert information about an auditor that will audit this exchange .
*
* @ param cls closure
* @ param auditor_pub key of the auditor
* @ param auditor_url base URL of the auditor ' s REST service
* @ param auditor_name name of the auditor ( for humans )
* @ param start_date date when the auditor was added by the offline system
* ( only to be used for replay detection )
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_insert_auditor ( void * cls ,
const struct TALER_AuditorPublicKeyP * auditor_pub ,
const char * auditor_url ,
const char * auditor_name ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp start_date )
2020-11-29 16:21:10 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-29 16:21:10 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( auditor_pub ) ,
GNUNET_PQ_query_param_string ( auditor_name ) ,
2020-12-12 22:42:04 +01:00
GNUNET_PQ_query_param_string ( auditor_url ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & start_date ) ,
2020-11-29 16:21:10 +01:00
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2020-11-29 16:21:10 +01:00
" insert_auditor " ,
params ) ;
}
/**
* Check the last date an exchange wire account was modified .
*
* @ param cls closure
* @ param payto_uri key to look up information for
* @ param [ out ] last_date last modification date to auditor status
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_lookup_wire_timestamp ( void * cls ,
const char * payto_uri ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp * last_date )
2020-11-29 16:21:10 +01:00
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-29 16:21:10 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( payto_uri ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " last_change " ,
last_date ) ,
2020-11-29 16:21:10 +01:00
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2020-11-29 16:21:10 +01:00
" lookup_wire_timestamp " ,
params ,
rs ) ;
}
/**
* Insert information about an wire account used by this exchange .
*
* @ param cls closure
* @ param payto_uri wire account of the exchange
* @ param start_date date when the account was added by the offline system
* ( only to be used for replay detection )
* @ param master_sig public signature affirming the existence of the account ,
* must be of purpose # TALER_SIGNATURE_MASTER_WIRE_DETAILS
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_insert_wire ( void * cls ,
const char * payto_uri ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp start_date ,
2020-11-29 16:21:10 +01:00
const struct TALER_MasterSignatureP * master_sig )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-29 16:21:10 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( payto_uri ) ,
GNUNET_PQ_query_param_auto_from_type ( master_sig ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & start_date ) ,
2020-11-29 16:21:10 +01:00
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2020-11-29 16:21:10 +01:00
" insert_wire " ,
params ) ;
}
/**
* Update information about a wire account of the exchange .
*
* @ param cls closure
* @ param payto_uri account the update is about
* @ param change_date date when the account status was last changed
* ( only to be used for replay detection )
* @ param enabled true to enable , false to disable ( the actual change )
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_update_wire ( void * cls ,
const char * payto_uri ,
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp change_date ,
2020-11-29 16:21:10 +01:00
bool enabled )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-29 16:21:10 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( payto_uri ) ,
2021-12-05 17:16:00 +01:00
GNUNET_PQ_query_param_bool ( enabled ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & change_date ) ,
2020-11-29 16:21:10 +01:00
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2020-11-29 16:21:10 +01:00
" update_wire " ,
params ) ;
}
2020-12-09 12:31:10 +01:00
/**
* Closure for # get_wire_accounts_cb ( ) .
*/
struct GetWireAccountsContext
{
/**
* Function to call per result .
*/
TALER_EXCHANGEDB_WireAccountCallback cb ;
/**
* Closure for @ e cb .
*/
void * cb_cls ;
/**
* Flag set to # GNUNET_OK as long as everything is fine .
*/
2022-03-23 12:25:22 +01:00
enum GNUNET_GenericReturnValue status ;
2020-12-09 12:31:10 +01:00
} ;
/**
* Invoke the callback for each result .
*
* @ param cls a ` struct MissingWireContext * `
* @ param result SQL result
* @ param num_results number of rows in @ a result
*/
static void
get_wire_accounts_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct GetWireAccountsContext * ctx = cls ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
char * payto_uri ;
struct TALER_MasterSignatureP master_sig ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_string ( " payto_uri " ,
& payto_uri ) ,
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
& master_sig ) ,
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
ctx - > status = GNUNET_SYSERR ;
return ;
}
ctx - > cb ( ctx - > cb_cls ,
payto_uri ,
& master_sig ) ;
GNUNET_PQ_cleanup_result ( rs ) ;
}
}
/**
* Obtain information about the enabled wire accounts of the exchange .
*
* @ param cls closure
* @ param cb function to call on each account
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_get_wire_accounts ( void * cls ,
TALER_EXCHANGEDB_WireAccountCallback cb ,
void * cb_cls )
{
struct PostgresClosure * pg = cls ;
struct GetWireAccountsContext ctx = {
. cb = cb ,
. cb_cls = cb_cls ,
. status = GNUNET_OK
} ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_end
} ;
enum GNUNET_DB_QueryStatus qs ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2020-12-09 12:31:10 +01:00
" get_wire_accounts " ,
params ,
& get_wire_accounts_cb ,
& ctx ) ;
if ( GNUNET_OK ! = ctx . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
/**
* Closure for # get_wire_fees_cb ( ) .
*/
struct GetWireFeesContext
{
/**
* Function to call per result .
*/
TALER_EXCHANGEDB_WireFeeCallback cb ;
/**
* Closure for @ e cb .
*/
void * cb_cls ;
/**
* Plugin context .
*/
struct PostgresClosure * pg ;
/**
* Flag set to # GNUNET_OK as long as everything is fine .
*/
2022-03-23 12:25:22 +01:00
enum GNUNET_GenericReturnValue status ;
2020-12-09 12:31:10 +01:00
} ;
/**
* Invoke the callback for each result .
*
2022-08-05 13:32:27 +02:00
* @ param cls a ` struct GetWireFeesContext * `
2020-12-09 12:31:10 +01:00
* @ param result SQL result
* @ param num_results number of rows in @ a result
*/
static void
get_wire_fees_cb ( void * cls ,
PGresult * result ,
unsigned int num_results )
{
struct GetWireFeesContext * ctx = cls ;
struct PostgresClosure * pg = ctx - > pg ;
for ( unsigned int i = 0 ; i < num_results ; i + + )
{
struct TALER_MasterSignatureP master_sig ;
2022-03-05 14:36:49 +01:00
struct TALER_WireFeeSet fees ;
2021-12-14 16:04:32 +01:00
struct GNUNET_TIME_Timestamp start_date ;
struct GNUNET_TIME_Timestamp end_date ;
2020-12-09 12:31:10 +01:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
TALER_PQ_RESULT_SPEC_AMOUNT ( " wire_fee " ,
2022-03-05 14:36:49 +01:00
& fees . wire ) ,
2020-12-09 12:31:10 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " closing_fee " ,
2022-03-05 14:36:49 +01:00
& fees . closing ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " start_date " ,
& start_date ) ,
GNUNET_PQ_result_spec_timestamp ( " end_date " ,
& end_date ) ,
2020-12-09 12:31:10 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
& master_sig ) ,
GNUNET_PQ_result_spec_end
} ;
if ( GNUNET_OK ! =
GNUNET_PQ_extract_result ( result ,
rs ,
i ) )
{
GNUNET_break ( 0 ) ;
ctx - > status = GNUNET_SYSERR ;
return ;
}
ctx - > cb ( ctx - > cb_cls ,
2022-03-05 14:36:49 +01:00
& fees ,
2020-12-09 12:31:10 +01:00
start_date ,
end_date ,
& master_sig ) ;
GNUNET_PQ_cleanup_result ( rs ) ;
}
}
/**
* Obtain information about the fee structure of the exchange for
* a given @ a wire_method
*
* @ param cls closure
* @ param wire_method which wire method to obtain fees for
* @ param cb function to call on each account
* @ param cb_cls closure for @ a cb
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_get_wire_fees ( void * cls ,
const char * wire_method ,
TALER_EXCHANGEDB_WireFeeCallback cb ,
void * cb_cls )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( wire_method ) ,
GNUNET_PQ_query_param_end
} ;
struct GetWireFeesContext ctx = {
. cb = cb ,
. cb_cls = cb_cls ,
. pg = pg ,
. status = GNUNET_OK
} ;
enum GNUNET_DB_QueryStatus qs ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_multi_select ( pg - > conn ,
2020-12-09 12:31:10 +01:00
" get_wire_fees " ,
params ,
& get_wire_fees_cb ,
& ctx ) ;
if ( GNUNET_OK ! = ctx . status )
return GNUNET_DB_STATUS_HARD_ERROR ;
return qs ;
}
2020-11-29 16:21:10 +01:00
/**
* Store information about a revoked online signing key .
*
* @ param cls closure
* @ param exchange_pub exchange online signing key that was revoked
* @ param master_sig signature affirming the revocation
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_insert_signkey_revocation (
void * cls ,
const struct TALER_ExchangePublicKeyP * exchange_pub ,
const struct TALER_MasterSignatureP * master_sig )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-29 17:27:53 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( exchange_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( master_sig ) ,
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2020-11-29 17:27:53 +01:00
" insert_signkey_revocation " ,
params ) ;
2020-11-29 16:21:10 +01:00
}
2020-12-26 15:55:34 +01:00
/**
* Obtain information about a revoked online signing key .
*
* @ param cls closure
* @ param exchange_pub exchange online signing key
* @ param [ out ] master_sig set to signature affirming the revocation ( if revoked )
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_lookup_signkey_revocation (
void * cls ,
const struct TALER_ExchangePublicKeyP * exchange_pub ,
struct TALER_MasterSignatureP * master_sig )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( exchange_pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2020-12-26 16:50:41 +01:00
GNUNET_PQ_result_spec_auto_from_type ( " master_sig " ,
master_sig ) ,
2020-12-26 15:55:34 +01:00
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2020-12-26 15:55:34 +01:00
" lookup_signkey_revocation " ,
params ,
rs ) ;
}
2020-11-29 16:21:10 +01:00
/**
2020-12-10 11:49:20 +01:00
* Lookup information about current denomination key .
2020-11-29 16:21:10 +01:00
*
* @ param cls closure
* @ param h_denom_pub hash of the denomination public key
* @ param [ out ] meta set to various meta data about the key
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2020-12-10 11:49:20 +01:00
postgres_lookup_denomination_key (
2020-11-29 16:21:10 +01:00
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_DenominationHashP * h_denom_pub ,
2020-11-29 17:27:53 +01:00
struct TALER_EXCHANGEDB_DenominationKeyMetaData * meta )
2020-11-29 16:21:10 +01:00
{
2020-11-29 17:27:53 +01:00
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( h_denom_pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " valid_from " ,
& meta - > start ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_withdraw " ,
& meta - > expire_withdraw ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_deposit " ,
& meta - > expire_deposit ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_legal " ,
& meta - > expire_legal ) ,
2020-11-29 17:27:53 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " coin " ,
& meta - > value ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_withdraw " ,
2022-02-17 15:10:14 +01:00
& meta - > fees . withdraw ) ,
2020-11-29 17:27:53 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_deposit " ,
2022-02-17 15:10:14 +01:00
& meta - > fees . deposit ) ,
2020-11-29 17:27:53 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refresh " ,
2022-02-17 15:10:14 +01:00
& meta - > fees . refresh ) ,
2020-11-29 17:27:53 +01:00
TALER_PQ_RESULT_SPEC_AMOUNT ( " fee_refund " ,
2022-02-17 15:10:14 +01:00
& meta - > fees . refund ) ,
2022-02-16 22:01:05 +01:00
GNUNET_PQ_result_spec_uint32 ( " age_mask " ,
2022-03-02 10:59:42 +01:00
& meta - > age_mask . bits ) ,
2020-11-29 17:27:53 +01:00
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2020-12-10 11:49:20 +01:00
" lookup_denomination_key " ,
2020-11-29 17:27:53 +01:00
params ,
rs ) ;
2020-11-29 16:21:10 +01:00
}
/**
2020-12-20 17:10:09 +01:00
* Activate denomination key , turning it into a " current " or " valid "
* denomination key by adding the master signature .
2020-11-29 16:21:10 +01:00
*
* @ param cls closure
* @ param h_denom_pub hash of the denomination public key
2020-12-20 17:10:09 +01:00
* @ param denom_pub the actual denomination key
2020-12-10 11:49:20 +01:00
* @ param meta meta data about the denomination
* @ param master_sig master signature to add
2020-11-29 16:21:10 +01:00
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
2020-12-10 11:49:20 +01:00
postgres_add_denomination_key (
2020-11-29 16:21:10 +01:00
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_DenominationHashP * h_denom_pub ,
2020-12-10 11:49:20 +01:00
const struct TALER_DenominationPublicKey * denom_pub ,
const struct TALER_EXCHANGEDB_DenominationKeyMetaData * meta ,
const struct TALER_MasterSignatureP * master_sig )
2020-11-29 16:21:10 +01:00
{
2020-11-29 17:27:53 +01:00
struct PostgresClosure * pg = cls ;
2020-12-10 11:49:20 +01:00
struct GNUNET_PQ_QueryParam iparams [ ] = {
2020-12-12 22:42:04 +01:00
GNUNET_PQ_query_param_auto_from_type ( h_denom_pub ) ,
2021-10-25 10:52:15 +02:00
TALER_PQ_query_param_denom_pub ( denom_pub ) ,
2020-12-10 11:49:20 +01:00
GNUNET_PQ_query_param_auto_from_type ( master_sig ) ,
2021-12-14 16:04:32 +01:00
GNUNET_PQ_query_param_timestamp ( & meta - > start ) ,
GNUNET_PQ_query_param_timestamp ( & meta - > expire_withdraw ) ,
GNUNET_PQ_query_param_timestamp ( & meta - > expire_deposit ) ,
GNUNET_PQ_query_param_timestamp ( & meta - > expire_legal ) ,
2020-12-10 11:49:20 +01:00
TALER_PQ_query_param_amount ( & meta - > value ) ,
2022-02-17 15:10:14 +01:00
TALER_PQ_query_param_amount ( & meta - > fees . withdraw ) ,
TALER_PQ_query_param_amount ( & meta - > fees . deposit ) ,
TALER_PQ_query_param_amount ( & meta - > fees . refresh ) ,
TALER_PQ_query_param_amount ( & meta - > fees . refund ) ,
2022-03-02 10:59:42 +01:00
GNUNET_PQ_query_param_uint32 ( & meta - > age_mask . bits ) ,
2020-11-29 17:27:53 +01:00
GNUNET_PQ_query_param_end
} ;
2020-12-10 11:49:20 +01:00
/* Sanity check: ensure fees match coin currency */
GNUNET_assert ( GNUNET_YES = =
2022-02-17 15:10:14 +01:00
TALER_denom_fee_check_currency ( meta - > value . currency ,
& meta - > fees ) ) ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2020-12-10 11:49:20 +01:00
" denomination_insert " ,
iparams ) ;
2020-11-29 16:21:10 +01:00
}
2020-12-10 11:49:20 +01:00
/**
* Lookup signing key meta data .
*
* @ param cls closure
* @ param exchange_pub the exchange online signing public key
* @ param [ out ] meta meta data about @ a exchange_pub
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_lookup_signing_key (
void * cls ,
const struct TALER_ExchangePublicKeyP * exchange_pub ,
struct TALER_EXCHANGEDB_SignkeyMetaData * meta )
{
struct PostgresClosure * pg = cls ;
2020-11-29 18:02:00 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
2020-12-10 11:49:20 +01:00
GNUNET_PQ_query_param_auto_from_type ( exchange_pub ) ,
2020-11-29 18:02:00 +01:00
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
2021-12-14 16:04:32 +01:00
GNUNET_PQ_result_spec_timestamp ( " valid_from " ,
& meta - > start ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_sign " ,
& meta - > expire_sign ) ,
GNUNET_PQ_result_spec_timestamp ( " expire_legal " ,
& meta - > expire_legal ) ,
2020-11-29 18:02:00 +01:00
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2020-12-10 11:49:20 +01:00
" lookup_signing_key " ,
params ,
rs ) ;
2020-11-29 16:21:10 +01:00
}
/**
* Insert information about an auditor auditing a denomination key .
*
* @ param cls closure
* @ param h_denom_pub the audited denomination
* @ param auditor_pub the auditor ' s key
* @ param auditor_sig signature affirming the auditor ' s audit activity
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_insert_auditor_denom_sig (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_DenominationHashP * h_denom_pub ,
2020-11-29 16:21:10 +01:00
const struct TALER_AuditorPublicKeyP * auditor_pub ,
const struct TALER_AuditorSignatureP * auditor_sig )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-11-29 17:27:53 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( auditor_pub ) ,
2020-12-17 13:04:37 +01:00
GNUNET_PQ_query_param_auto_from_type ( h_denom_pub ) ,
2020-11-29 17:27:53 +01:00
GNUNET_PQ_query_param_auto_from_type ( auditor_sig ) ,
GNUNET_PQ_query_param_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2020-11-29 17:27:53 +01:00
" insert_auditor_denom_sig " ,
params ) ;
2020-11-29 16:21:10 +01:00
}
2020-12-22 18:27:34 +01:00
/**
* Select information about an auditor auditing a denomination key .
*
* @ param cls closure
* @ param h_denom_pub the audited denomination
* @ param auditor_pub the auditor ' s key
* @ param [ out ] auditor_sig set to signature affirming the auditor ' s audit activity
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_select_auditor_denom_sig (
void * cls ,
2022-02-21 00:23:23 +01:00
const struct TALER_DenominationHashP * h_denom_pub ,
2020-12-22 18:27:34 +01:00
const struct TALER_AuditorPublicKeyP * auditor_pub ,
struct TALER_AuditorSignatureP * auditor_sig )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2020-12-22 18:27:34 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( auditor_pub ) ,
GNUNET_PQ_query_param_auto_from_type ( h_denom_pub ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " auditor_sig " ,
auditor_sig ) ,
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2020-12-22 18:27:34 +01:00
" select_auditor_denom_sig " ,
params ,
rs ) ;
}
2020-11-29 18:02:00 +01:00
/**
2022-11-10 16:37:28 +01:00
* Function called to grab a work shard on an operation @ a op . Runs in its
* own transaction .
2020-11-29 18:02:00 +01:00
*
2022-11-10 16:37:28 +01:00
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param job_name name of the operation to grab a word shard for
* @ param delay minimum age of a shard to grab
* @ param shard_size desired shard size
* @ param [ out ] start_row inclusive start row of the shard ( returned )
* @ param [ out ] end_row exclusive end row of the shard ( returned )
* @ return transaction status code
2020-11-29 18:02:00 +01:00
*/
2022-11-10 16:37:28 +01:00
static enum GNUNET_DB_QueryStatus
postgres_begin_shard ( void * cls ,
const char * job_name ,
struct GNUNET_TIME_Relative delay ,
uint64_t shard_size ,
uint64_t * start_row ,
uint64_t * end_row )
2020-11-29 18:02:00 +01:00
{
2022-11-10 16:37:28 +01:00
struct PostgresClosure * pg = cls ;
2020-11-29 18:02:00 +01:00
2022-11-10 16:37:28 +01:00
for ( unsigned int retries = 0 ; retries < 10 ; retries + + )
2020-11-29 18:02:00 +01:00
{
if ( GNUNET_OK ! =
2022-11-10 16:37:28 +01:00
TEH_PG_start ( pg ,
2022-11-14 05:08:11 +01:00
" begin_shard " ) )
2020-11-29 18:02:00 +01:00
{
GNUNET_break ( 0 ) ;
2022-11-10 16:37:28 +01:00
return GNUNET_DB_STATUS_HARD_ERROR ;
2020-11-29 18:02:00 +01:00
}
2022-11-10 16:37:28 +01:00
{
struct GNUNET_TIME_Absolute past ;
enum GNUNET_DB_QueryStatus qs ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( job_name ) ,
GNUNET_PQ_query_param_absolute_time ( & past ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " start_row " ,
start_row ) ,
GNUNET_PQ_result_spec_uint64 ( " end_row " ,
end_row ) ,
GNUNET_PQ_result_spec_end
} ;
2021-06-20 16:41:04 +02:00
2022-05-24 10:45:01 +02:00
past = GNUNET_TIME_absolute_get ( ) ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2021-06-20 16:41:04 +02:00
" get_open_shard " ,
params ,
rs ) ;
switch ( qs )
{
case GNUNET_DB_STATUS_HARD_ERROR :
GNUNET_break ( 0 ) ;
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
return qs ;
case GNUNET_DB_STATUS_SOFT_ERROR :
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
continue ;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
{
enum GNUNET_DB_QueryStatus qs ;
2022-05-24 12:00:20 +02:00
struct GNUNET_TIME_Absolute now ;
2021-06-20 16:41:04 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( job_name ) ,
2022-05-24 12:00:20 +02:00
GNUNET_PQ_query_param_absolute_time ( & now ) ,
2021-06-20 16:41:04 +02:00
GNUNET_PQ_query_param_uint64 ( start_row ) ,
GNUNET_PQ_query_param_uint64 ( end_row ) ,
GNUNET_PQ_query_param_end
} ;
2022-05-24 12:00:20 +02:00
now = GNUNET_TIME_relative_to_absolute ( delay ) ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2021-06-20 16:41:04 +02:00
" reclaim_shard " ,
params ) ;
switch ( qs )
{
case GNUNET_DB_STATUS_HARD_ERROR :
GNUNET_break ( 0 ) ;
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
return qs ;
case GNUNET_DB_STATUS_SOFT_ERROR :
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
continue ;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
goto commit ;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
GNUNET_break ( 0 ) ; /* logic error, should be impossible */
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
return GNUNET_DB_STATUS_HARD_ERROR ;
}
}
break ; /* actually unreachable */
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
break ; /* continued below */
}
} /* get_open_shard */
/* No open shard, find last 'end_row' */
{
enum GNUNET_DB_QueryStatus qs ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( job_name ) ,
GNUNET_PQ_query_param_end
} ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_uint64 ( " end_row " ,
start_row ) ,
GNUNET_PQ_result_spec_end
} ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
2021-06-20 16:41:04 +02:00
" get_last_shard " ,
params ,
rs ) ;
switch ( qs )
{
case GNUNET_DB_STATUS_HARD_ERROR :
GNUNET_break ( 0 ) ;
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
return qs ;
case GNUNET_DB_STATUS_SOFT_ERROR :
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
continue ;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
break ;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
* start_row = 0 ; /* base-case: no shards yet */
break ; /* continued below */
}
* end_row = * start_row + shard_size ;
} /* get_last_shard */
/* Claim fresh shard */
{
enum GNUNET_DB_QueryStatus qs ;
2022-05-24 12:00:20 +02:00
struct GNUNET_TIME_Absolute now ;
2021-06-20 16:41:04 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( job_name ) ,
2022-05-24 12:00:20 +02:00
GNUNET_PQ_query_param_absolute_time ( & now ) ,
2021-06-20 16:41:04 +02:00
GNUNET_PQ_query_param_uint64 ( start_row ) ,
GNUNET_PQ_query_param_uint64 ( end_row ) ,
GNUNET_PQ_query_param_end
} ;
2022-05-24 12:00:20 +02:00
now = GNUNET_TIME_relative_to_absolute ( delay ) ;
2021-06-21 00:17:16 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_INFO ,
2022-05-24 10:45:01 +02:00
" Trying to claim shard (%llu-%llu] \n " ,
2021-06-21 00:17:16 +02:00
( unsigned long long ) * start_row ,
( unsigned long long ) * end_row ) ;
2021-08-23 00:00:32 +02:00
qs = GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2021-06-20 16:41:04 +02:00
" claim_next_shard " ,
params ) ;
switch ( qs )
{
case GNUNET_DB_STATUS_HARD_ERROR :
GNUNET_break ( 0 ) ;
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
return qs ;
case GNUNET_DB_STATUS_SOFT_ERROR :
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
continue ;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
/* continued below */
break ;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
2021-06-21 00:17:16 +02:00
/* someone else got this shard already,
try again */
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
continue ;
}
} /* claim_next_shard */
/* commit */
commit :
{
enum GNUNET_DB_QueryStatus qs ;
2022-11-08 15:21:01 +01:00
qs = TEH_PG_commit ( pg ) ;
2021-06-20 16:41:04 +02:00
switch ( qs )
{
case GNUNET_DB_STATUS_HARD_ERROR :
GNUNET_break ( 0 ) ;
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
return qs ;
case GNUNET_DB_STATUS_SOFT_ERROR :
2022-11-10 16:37:28 +01:00
TEH_PG_rollback ( pg ) ;
2021-06-20 16:41:04 +02:00
continue ;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS :
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT :
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ;
}
}
} /* retry 'for' loop */
return GNUNET_DB_STATUS_SOFT_ERROR ;
}
2022-04-14 00:00:50 +02:00
/**
* Function called to abort work on a shard .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param job_name name of the operation to abort a word shard for
* @ param start_row inclusive start row of the shard
* @ param end_row exclusive end row of the shard
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_abort_shard ( void * cls ,
const char * job_name ,
uint64_t start_row ,
uint64_t end_row )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( job_name ) ,
GNUNET_PQ_query_param_uint64 ( & start_row ) ,
GNUNET_PQ_query_param_uint64 ( & end_row ) ,
GNUNET_PQ_query_param_end
} ;
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" abort_shard " ,
params ) ;
}
2021-06-20 16:41:04 +02:00
/**
* Function called to persist that work on a shard was completed .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param job_name name of the operation to grab a word shard for
* @ param start_row inclusive start row of the shard
* @ param end_row exclusive end row of the shard
* @ return transaction status code
*/
enum GNUNET_DB_QueryStatus
postgres_complete_shard ( void * cls ,
const char * job_name ,
uint64_t start_row ,
uint64_t end_row )
{
2021-08-23 00:00:32 +02:00
struct PostgresClosure * pg = cls ;
2021-06-20 16:41:04 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( job_name ) ,
GNUNET_PQ_query_param_uint64 ( & start_row ) ,
GNUNET_PQ_query_param_uint64 ( & end_row ) ,
GNUNET_PQ_query_param_end
} ;
2021-06-21 00:17:16 +02:00
GNUNET_log ( GNUNET_ERROR_TYPE_INFO ,
" Completing shard %llu-%llu \n " ,
( unsigned long long ) start_row ,
( unsigned long long ) end_row ) ;
2021-08-23 00:00:32 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2021-06-20 16:41:04 +02:00
" complete_shard " ,
params ) ;
}
2021-09-03 19:08:02 +02:00
/**
2022-11-10 16:37:28 +01:00
* Function called to release a revolving shard
* back into the work pool . Clears the
* " completed " flag .
2021-09-03 19:08:02 +02:00
*
* @ param cls the @ e cls of this struct with the plugin - specific state
2022-11-10 16:37:28 +01:00
* @ param job_name name of the operation to grab a word shard for
* @ param start_row inclusive start row of the shard
* @ param end_row exclusive end row of the shard
2021-09-03 19:08:02 +02:00
* @ return transaction status code
*/
2022-11-10 16:37:28 +01:00
enum GNUNET_DB_QueryStatus
postgres_release_revolving_shard ( void * cls ,
const char * job_name ,
uint32_t start_row ,
uint32_t end_row )
2021-09-03 19:08:02 +02:00
{
struct PostgresClosure * pg = cls ;
2022-11-10 16:37:28 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( job_name ) ,
GNUNET_PQ_query_param_uint32 ( & start_row ) ,
GNUNET_PQ_query_param_uint32 ( & end_row ) ,
GNUNET_PQ_query_param_end
} ;
2021-09-03 19:08:02 +02:00
2022-11-10 16:37:28 +01:00
GNUNET_log ( GNUNET_ERROR_TYPE_INFO ,
" Releasing revolving shard %s %u-%u \n " ,
job_name ,
( unsigned int ) start_row ,
( unsigned int ) end_row ) ;
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" release_revolving_shard " ,
params ) ;
}
2021-09-03 19:08:02 +02:00
2022-11-10 16:37:28 +01:00
/**
* Function called to delete all revolving shards .
* To be used after a crash or when the shard size is
* changed .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ return transaction status code
*/
enum GNUNET_GenericReturnValue
postgres_delete_shard_locks ( void * cls )
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_ExecuteStatement es [ ] = {
GNUNET_PQ_make_execute ( " DELETE FROM work_shards; " ) ,
GNUNET_PQ_make_execute ( " DELETE FROM revolving_work_shards; " ) ,
GNUNET_PQ_EXECUTE_STATEMENT_END
} ;
2021-09-03 19:08:02 +02:00
2022-11-10 16:37:28 +01:00
return GNUNET_PQ_exec_statements ( pg - > conn ,
es ) ;
}
2021-09-03 19:08:02 +02:00
2022-01-08 14:40:20 +01:00
/**
2022-11-04 12:18:16 +01:00
* Function called to save the manifest of an extension
* ( age - restriction , policy_extension_ . . . ) After successful storage of the
2022-01-08 14:40:20 +01:00
* configuration it triggers the corresponding event .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param extension_name the name of the extension
2022-11-04 12:58:03 +01:00
* @ param manifest JSON object of the configuration as string
2022-01-08 14:40:20 +01:00
* @ return transaction status code
*/
enum GNUNET_DB_QueryStatus
2022-11-04 12:18:16 +01:00
postgres_set_extension_manifest ( void * cls ,
const char * extension_name ,
const char * manifest )
2022-01-08 14:40:20 +01:00
{
struct PostgresClosure * pg = cls ;
2022-04-04 20:42:26 +02:00
struct GNUNET_PQ_QueryParam pcfg =
2022-11-04 12:18:16 +01:00
( NULL = = manifest | | 0 = = * manifest )
2022-04-04 20:42:26 +02:00
? GNUNET_PQ_query_param_null ( )
2022-11-04 12:18:16 +01:00
: GNUNET_PQ_query_param_string ( manifest ) ;
2022-01-08 14:40:20 +01:00
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_string ( extension_name ) ,
2022-01-11 15:24:43 +01:00
pcfg ,
2022-01-08 14:40:20 +01:00
GNUNET_PQ_query_param_end
} ;
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
2022-11-04 12:18:16 +01:00
" set_extension_manifest " ,
2022-01-08 14:40:20 +01:00
params ) ;
}
2022-03-23 12:25:22 +01:00
/**
* Function called to store configuration data about a partner
* exchange that we are federated with .
*
* @ param cls the @ e cls of this struct with the plugin - specific state
* @ param master_pub public offline signing key of the partner exchange
* @ param start_date when does the following data start to be valid
* @ param end_date when does the validity end ( exclusive )
* @ param wad_frequency how often do we do exchange - to - exchange settlements ?
* @ param wad_fee how much do we charge for transfers to the partner
* @ param partner_base_url base URL of the partner exchange
* @ param master_sig signature with our offline signing key affirming the above
* @ return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_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_MasterSignatureP * master_sig )
{
2022-04-04 20:42:26 +02:00
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
GNUNET_PQ_query_param_auto_from_type ( master_pub ) ,
GNUNET_PQ_query_param_timestamp ( & start_date ) ,
GNUNET_PQ_query_param_timestamp ( & end_date ) ,
GNUNET_PQ_query_param_relative_time ( & wad_frequency ) ,
TALER_PQ_query_param_amount ( wad_fee ) ,
GNUNET_PQ_query_param_auto_from_type ( master_sig ) ,
GNUNET_PQ_query_param_string ( partner_base_url ) ,
GNUNET_PQ_query_param_end
} ;
2022-03-23 12:25:22 +01:00
2022-04-04 20:42:26 +02:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" insert_partner " ,
params ) ;
2022-11-10 16:37:28 +01:00
}
2022-08-05 14:22:08 +02:00
/**
2022-11-10 16:37:28 +01:00
* Function called to clean up one expired purse .
2022-08-05 14:22:08 +02:00
*
* @ param cls the @ e cls of this struct with the plugin - specific state
2022-11-10 16:37:28 +01:00
* @ param start_time select purse expired after this time
* @ param end_time select purse expired before this time
* @ return transaction status code ( # GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no purse expired in the given time interval ) .
2022-08-05 14:22:08 +02:00
*/
static enum GNUNET_DB_QueryStatus
2022-11-10 16:37:28 +01:00
postgres_expire_purse (
2022-08-05 14:22:08 +02:00
void * cls ,
2022-11-10 16:37:28 +01:00
struct GNUNET_TIME_Absolute start_time ,
struct GNUNET_TIME_Absolute end_time )
2022-08-05 14:22:08 +02:00
{
struct PostgresClosure * pg = cls ;
2022-11-10 16:37:28 +01:00
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ( ) ;
2022-08-05 14:22:08 +02:00
struct GNUNET_PQ_QueryParam params [ ] = {
2022-11-10 16:37:28 +01:00
GNUNET_PQ_query_param_absolute_time ( & start_time ) ,
GNUNET_PQ_query_param_absolute_time ( & end_time ) ,
GNUNET_PQ_query_param_absolute_time ( & now ) ,
2022-08-05 14:22:08 +02:00
GNUNET_PQ_query_param_end
} ;
2022-11-10 16:37:28 +01:00
bool found = false ;
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_bool ( " found " ,
& found ) ,
GNUNET_PQ_result_spec_end
2022-08-05 14:22:08 +02:00
} ;
enum GNUNET_DB_QueryStatus qs ;
2022-11-10 16:37:28 +01:00
qs = GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" call_expire_purse " ,
params ,
rs ) ;
if ( qs < 0 )
return qs ;
GNUNET_assert ( GNUNET_DB_STATUS_SUCCESS_ONE_RESULT = = qs ) ;
return found
? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
: GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ;
2022-08-05 14:22:08 +02:00
}
/**
2022-11-10 16:37:28 +01:00
* Function called to return meta data about a purse by the
* merge capability key .
2022-08-05 14:22:08 +02:00
*
* @ param cls the @ e cls of this struct with the plugin - specific state
2022-11-10 16:37:28 +01:00
* @ param merge_pub public key representing the merge capability
* @ param [ out ] purse_pub public key of the purse
* @ param [ out ] purse_expiration when would an unmerged purse expire
* @ param [ out ] h_contract_terms contract associated with the purse
* @ param [ out ] age_limit the age limit for deposits into the purse
* @ param [ out ] target_amount amount to be put into the purse
* @ param [ out ] balance amount put so far into the purse
* @ param [ out ] purse_sig signature of the purse over the initialization data
* @ return transaction status code
2022-08-05 14:22:08 +02:00
*/
static enum GNUNET_DB_QueryStatus
2022-11-10 16:37:28 +01:00
postgres_select_purse_by_merge_pub (
2022-08-05 14:22:08 +02:00
void * cls ,
2022-11-10 16:37:28 +01:00
const struct TALER_PurseMergePublicKeyP * merge_pub ,
struct TALER_PurseContractPublicKeyP * purse_pub ,
struct GNUNET_TIME_Timestamp * purse_expiration ,
struct TALER_PrivateContractHashP * h_contract_terms ,
uint32_t * age_limit ,
struct TALER_Amount * target_amount ,
struct TALER_Amount * balance ,
struct TALER_PurseContractSignatureP * purse_sig )
2022-08-05 14:22:08 +02:00
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
2022-11-10 16:37:28 +01:00
GNUNET_PQ_query_param_auto_from_type ( merge_pub ) ,
2022-08-05 14:22:08 +02:00
GNUNET_PQ_query_param_end
} ;
2022-11-10 16:37:28 +01:00
struct GNUNET_PQ_ResultSpec rs [ ] = {
GNUNET_PQ_result_spec_auto_from_type ( " purse_pub " ,
purse_pub ) ,
GNUNET_PQ_result_spec_timestamp ( " purse_expiration " ,
purse_expiration ) ,
GNUNET_PQ_result_spec_auto_from_type ( " h_contract_terms " ,
h_contract_terms ) ,
GNUNET_PQ_result_spec_uint32 ( " age_limit " ,
age_limit ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " amount_with_fee " ,
target_amount ) ,
TALER_PQ_RESULT_SPEC_AMOUNT ( " balance " ,
balance ) ,
GNUNET_PQ_result_spec_auto_from_type ( " purse_sig " ,
purse_sig ) ,
GNUNET_PQ_result_spec_end
2022-08-05 14:22:08 +02:00
} ;
2022-11-10 16:37:28 +01:00
return GNUNET_PQ_eval_prepared_singleton_select ( pg - > conn ,
" select_purse_by_merge_pub " ,
params ,
rs ) ;
2022-08-05 14:22:08 +02:00
}
/**
2022-11-10 16:37:28 +01:00
* Set the current @ a balance in the purse
* identified by @ a purse_pub . Used by the auditor
* to update the balance as calculated by the auditor .
2022-08-05 14:22:08 +02:00
*
2022-11-10 16:37:28 +01:00
* @ param cls closure
* @ param purse_pub public key of a purse
* @ param balance new balance to store under the purse
* @ return transaction status
2022-08-05 14:22:08 +02:00
*/
static enum GNUNET_DB_QueryStatus
2022-11-10 16:37:28 +01:00
postgres_set_purse_balance (
2022-08-05 14:22:08 +02:00
void * cls ,
2022-11-10 16:37:28 +01:00
const struct TALER_PurseContractPublicKeyP * purse_pub ,
const struct TALER_Amount * balance )
2022-08-05 14:22:08 +02:00
{
struct PostgresClosure * pg = cls ;
struct GNUNET_PQ_QueryParam params [ ] = {
2022-11-10 16:37:28 +01:00
GNUNET_PQ_query_param_auto_from_type ( purse_pub ) ,
TALER_PQ_query_param_amount ( balance ) ,
2022-08-05 14:22:08 +02:00
GNUNET_PQ_query_param_end
} ;
2022-11-10 16:37:28 +01:00
return GNUNET_PQ_eval_prepared_non_select ( pg - > conn ,
" set_purse_balance " ,
params ) ;
2022-08-05 14:22:08 +02:00
}
2015-01-28 22:47:03 +01:00
/**
2015-03-20 23:51:28 +01:00
* Initialize Postgres database subsystem .
2015-01-28 22:47:03 +01:00
*
2015-03-20 23:51:28 +01:00
* @ param cls a configuration instance
2018-07-06 15:24:03 +02:00
* @ return NULL on error , otherwise a ` struct
* TALER_EXCHANGEDB_Plugin `
2015-01-28 22:47:03 +01:00
*/
2015-03-20 23:51:28 +01:00
void *
2016-03-01 15:35:04 +01:00
libtaler_plugin_exchangedb_postgres_init ( void * cls )
2015-01-28 22:47:03 +01:00
{
2020-02-09 15:53:28 +01:00
const struct GNUNET_CONFIGURATION_Handle * cfg = cls ;
2015-03-20 23:51:28 +01:00
struct PostgresClosure * pg ;
2016-03-01 15:35:04 +01:00
struct TALER_EXCHANGEDB_Plugin * plugin ;
2022-10-09 23:23:14 +02:00
unsigned long long dpl ;
2015-03-20 23:51:28 +01:00
pg = GNUNET_new ( struct PostgresClosure ) ;
2020-02-09 15:53:28 +01:00
pg - > cfg = cfg ;
2020-01-17 03:08:30 +01:00
if ( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_filename ( cfg ,
" exchangedb-postgres " ,
" SQL_DIR " ,
& pg - > sql_dir ) )
{
GNUNET_log_config_missing ( GNUNET_ERROR_TYPE_ERROR ,
" exchangedb-postgres " ,
" CONFIG " ) ;
GNUNET_free ( pg ) ;
return NULL ;
}
2021-10-29 11:28:12 +02:00
if ( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_string ( cfg ,
" exchange " ,
" BASE_URL " ,
& pg - > exchange_url ) )
{
GNUNET_log_config_missing ( GNUNET_ERROR_TYPE_ERROR ,
" exchange " ,
" BASE_URL " ) ;
GNUNET_free ( pg - > sql_dir ) ;
GNUNET_free ( pg ) ;
return NULL ;
}
2019-07-24 12:19:36 +02:00
if ( ( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_time ( cfg ,
" exchangedb " ,
" IDLE_RESERVE_EXPIRATION_TIME " ,
2019-08-25 16:18:24 +02:00
& pg - > idle_reserve_expiration_time ) )
| |
2019-07-24 12:19:36 +02:00
( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_time ( cfg ,
" exchangedb " ,
" LEGAL_RESERVE_EXPIRATION_TIME " ,
& pg - > legal_reserve_expiration_time ) ) )
2017-04-20 21:38:02 +02:00
{
GNUNET_log_config_missing ( GNUNET_ERROR_TYPE_ERROR ,
" exchangedb " ,
2019-07-24 12:19:36 +02:00
" LEGAL/IDLE_RESERVE_EXPIRATION_TIME " ) ;
2021-10-29 11:28:12 +02:00
GNUNET_free ( pg - > exchange_url ) ;
2020-01-17 03:08:30 +01:00
GNUNET_free ( pg - > sql_dir ) ;
2017-04-20 21:38:02 +02:00
GNUNET_free ( pg ) ;
return NULL ;
}
2022-03-26 09:00:19 +01:00
if ( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_time ( cfg ,
" exchangedb " ,
" AGGREGATOR_SHIFT " ,
& pg - > aggregator_shift ) )
{
GNUNET_log_config_missing ( GNUNET_ERROR_TYPE_WARNING ,
" exchangedb " ,
" AGGREGATOR_SHIFT " ) ;
}
2022-10-09 23:23:14 +02:00
if ( GNUNET_OK ! =
GNUNET_CONFIGURATION_get_value_number ( cfg ,
" exchangedb " ,
" DEFAULT_PURSE_LIMIT " ,
& dpl ) )
{
GNUNET_log_config_missing ( GNUNET_ERROR_TYPE_WARNING ,
" exchangedb " ,
" DEFAULT_PURSE_LIMIT " ) ;
pg - > def_purse_limit = 1 ;
}
else
{
pg - > def_purse_limit = ( uint32_t ) dpl ;
}
2022-03-26 09:00:19 +01:00
2019-08-17 21:35:21 +02:00
if ( GNUNET_OK ! =
2020-03-15 20:08:38 +01:00
TALER_config_get_currency ( cfg ,
& pg - > currency ) )
2019-08-17 21:35:21 +02:00
{
2021-10-29 11:28:12 +02:00
GNUNET_free ( pg - > exchange_url ) ;
2020-01-17 03:08:30 +01:00
GNUNET_free ( pg - > sql_dir ) ;
2019-08-17 21:35:21 +02:00
GNUNET_free ( pg ) ;
return NULL ;
}
2021-08-23 00:00:32 +02:00
if ( GNUNET_OK ! =
2022-11-14 05:08:11 +01:00
TEH_PG_internal_setup ( pg ,
true ) )
2021-08-13 22:35:13 +02:00
{
2021-10-29 11:28:12 +02:00
GNUNET_free ( pg - > exchange_url ) ;
2021-08-23 00:00:32 +02:00
GNUNET_free ( pg - > currency ) ;
GNUNET_free ( pg - > sql_dir ) ;
GNUNET_free ( pg ) ;
return NULL ;
2021-08-13 22:35:13 +02:00
}
2016-03-01 15:35:04 +01:00
plugin = GNUNET_new ( struct TALER_EXCHANGEDB_Plugin ) ;
2015-03-20 23:51:28 +01:00
plugin - > cls = pg ;
2015-03-22 12:49:48 +01:00
plugin - > create_tables = & postgres_create_tables ;
2022-03-31 21:31:07 +02:00
plugin - > setup_foreign_servers = & postgres_setup_foreign_servers ;
2021-08-13 22:35:13 +02:00
plugin - > event_listen = & postgres_event_listen ;
plugin - > event_listen_cancel = & postgres_event_listen_cancel ;
plugin - > event_notify = & postgres_event_notify ;
2015-06-12 10:28:17 +02:00
plugin - > get_denomination_info = & postgres_get_denomination_info ;
2019-02-14 13:41:46 +01:00
plugin - > iterate_denomination_info = & postgres_iterate_denomination_info ;
2020-12-06 21:48:31 +01:00
plugin - > iterate_denominations = & postgres_iterate_denominations ;
plugin - > iterate_active_auditors = & postgres_iterate_active_auditors ;
plugin - > iterate_auditor_denominations =
& postgres_iterate_auditor_denominations ;
2020-03-05 23:02:38 +01:00
plugin - > reserves_get = & postgres_reserves_get ;
2022-08-11 23:35:33 +02:00
plugin - > reserves_get_origin = & postgres_reserves_get_origin ;
plugin - > drain_kyc_alert = & postgres_drain_kyc_alert ;
2015-03-22 12:49:48 +01:00
plugin - > reserves_in_insert = & postgres_reserves_in_insert ;
2015-06-11 12:30:14 +02:00
plugin - > get_withdraw_info = & postgres_get_withdraw_info ;
2022-05-01 12:45:12 +02:00
plugin - > do_batch_withdraw = & postgres_do_batch_withdraw ;
2022-11-04 12:18:16 +01:00
plugin - > get_policy_details = & postgres_get_policy_details ;
plugin - > persist_policy_details = & postgres_persist_policy_details ;
2021-12-25 13:56:33 +01:00
plugin - > do_deposit = & postgres_do_deposit ;
2022-11-04 12:18:16 +01:00
plugin - > add_policy_fulfillment_proof = & postgres_add_policy_fulfillment_proof ;
2021-12-25 13:56:33 +01:00
plugin - > do_melt = & postgres_do_melt ;
plugin - > do_refund = & postgres_do_refund ;
plugin - > do_recoup = & postgres_do_recoup ;
plugin - > do_recoup_refresh = & postgres_do_recoup_refresh ;
2022-03-21 02:39:36 +01:00
plugin - > get_reserve_balance = & postgres_get_reserve_balance ;
2018-10-28 11:38:45 +01:00
plugin - > count_known_coins = & postgres_count_known_coins ;
2018-08-19 16:01:57 +02:00
plugin - > ensure_coin_known = & postgres_ensure_coin_known ;
2019-06-26 21:34:52 +02:00
plugin - > get_known_coin = & postgres_get_known_coin ;
2020-01-17 12:52:24 +01:00
plugin - > get_coin_denomination = & postgres_get_coin_denomination ;
2021-10-30 19:28:11 +02:00
plugin - > have_deposit2 = & postgres_have_deposit2 ;
2022-03-27 10:32:28 +02:00
plugin - > aggregate = & postgres_aggregate ;
plugin - > create_aggregation_transient
= & postgres_create_aggregation_transient ;
plugin - > select_aggregation_transient
= & postgres_select_aggregation_transient ;
2022-08-11 23:35:33 +02:00
plugin - > find_aggregation_transient
= & postgres_find_aggregation_transient ;
2022-03-27 10:32:28 +02:00
plugin - > update_aggregation_transient
= & postgres_update_aggregation_transient ;
2016-01-27 16:42:24 +01:00
plugin - > get_ready_deposit = & postgres_get_ready_deposit ;
2015-03-22 12:49:48 +01:00
plugin - > insert_deposit = & postgres_insert_deposit ;
2016-05-05 22:57:55 +02:00
plugin - > insert_refund = & postgres_insert_refund ;
2018-01-02 14:43:15 +01:00
plugin - > select_refunds_by_coin = & postgres_select_refunds_by_coin ;
2017-11-27 23:42:17 +01:00
plugin - > get_melt = & postgres_get_melt ;
plugin - > insert_refresh_reveal = & postgres_insert_refresh_reveal ;
plugin - > get_refresh_reveal = & postgres_get_refresh_reveal ;
2016-01-21 12:09:17 +01:00
plugin - > lookup_wire_transfer = & postgres_lookup_wire_transfer ;
2020-03-05 23:49:47 +01:00
plugin - > lookup_transfer_by_deposit = & postgres_lookup_transfer_by_deposit ;
2017-03-04 16:49:33 +01:00
plugin - > insert_wire_fee = & postgres_insert_wire_fee ;
2022-03-05 17:14:32 +01:00
plugin - > insert_global_fee = & postgres_insert_global_fee ;
2017-03-04 16:49:33 +01:00
plugin - > get_wire_fee = & postgres_get_wire_fee ;
2022-03-05 17:14:32 +01:00
plugin - > get_global_fee = & postgres_get_global_fee ;
2022-03-20 09:44:42 +01:00
plugin - > get_global_fees = & postgres_get_global_fees ;
2017-04-19 18:44:14 +02:00
plugin - > insert_reserve_closed = & postgres_insert_reserve_closed ;
2016-01-27 16:46:51 +01:00
plugin - > wire_prepare_data_insert = & postgres_wire_prepare_data_insert ;
2019-08-25 16:18:24 +02:00
plugin - > wire_prepare_data_mark_finished =
& postgres_wire_prepare_data_mark_finished ;
2020-11-14 22:27:50 +01:00
plugin - > wire_prepare_data_mark_failed =
& postgres_wire_prepare_data_mark_failed ;
2016-01-27 18:28:52 +01:00
plugin - > wire_prepare_data_get = & postgres_wire_prepare_data_get ;
2017-03-18 03:44:59 +01:00
plugin - > start_deferred_wire_out = & postgres_start_deferred_wire_out ;
2017-03-18 02:40:27 +01:00
plugin - > store_wire_transfer_out = & postgres_store_wire_transfer_out ;
2016-05-31 09:13:03 +02:00
plugin - > gc = & postgres_gc ;
2018-04-02 21:12:18 +02:00
plugin - > select_deposits_above_serial_id
= & postgres_select_deposits_above_serial_id ;
2022-06-15 20:49:39 +02:00
plugin - > select_history_requests_above_serial_id
= & postgres_select_history_requests_above_serial_id ;
2022-10-30 17:36:57 +01:00
plugin - > select_purse_decisions_above_serial_id
= & postgres_select_purse_decisions_above_serial_id ;
2022-06-13 15:31:52 +02:00
plugin - > select_purse_deposits_by_purse
= & postgres_select_purse_deposits_by_purse ;
2020-03-05 23:02:38 +01:00
plugin - > select_refreshes_above_serial_id
= & postgres_select_refreshes_above_serial_id ;
2018-04-02 21:12:18 +02:00
plugin - > select_refunds_above_serial_id
= & postgres_select_refunds_above_serial_id ;
plugin - > select_reserves_in_above_serial_id
= & postgres_select_reserves_in_above_serial_id ;
plugin - > select_reserves_in_above_serial_id_by_account
= & postgres_select_reserves_in_above_serial_id_by_account ;
2020-03-05 23:02:38 +01:00
plugin - > select_withdrawals_above_serial_id
= & postgres_select_withdrawals_above_serial_id ;
2018-04-02 21:12:18 +02:00
plugin - > select_wire_out_above_serial_id
= & postgres_select_wire_out_above_serial_id ;
plugin - > select_wire_out_above_serial_id_by_account
= & postgres_select_wire_out_above_serial_id_by_account ;
2020-01-18 23:49:37 +01:00
plugin - > select_recoup_above_serial_id
= & postgres_select_recoup_above_serial_id ;
plugin - > select_recoup_refresh_above_serial_id
= & postgres_select_recoup_refresh_above_serial_id ;
2022-02-17 15:10:14 +01:00
plugin - > get_reserve_by_h_blind
= & postgres_get_reserve_by_h_blind ;
2019-07-23 20:27:41 +02:00
plugin - > get_old_coin_by_h_blind
= & postgres_get_old_coin_by_h_blind ;
2018-04-02 21:12:18 +02:00
plugin - > insert_denomination_revocation
= & postgres_insert_denomination_revocation ;
plugin - > get_denomination_revocation
= & postgres_get_denomination_revocation ;
plugin - > select_deposits_missing_wire
= & postgres_select_deposits_missing_wire ;
2020-11-29 16:21:10 +01:00
plugin - > lookup_auditor_timestamp
= & postgres_lookup_auditor_timestamp ;
plugin - > lookup_auditor_status
= & postgres_lookup_auditor_status ;
plugin - > insert_auditor
= & postgres_insert_auditor ;
2022-11-10 16:37:28 +01:00
2020-11-29 16:21:10 +01:00
plugin - > lookup_wire_timestamp
= & postgres_lookup_wire_timestamp ;
plugin - > insert_wire
= & postgres_insert_wire ;
plugin - > update_wire
= & postgres_update_wire ;
2020-12-09 12:31:10 +01:00
plugin - > get_wire_accounts
= & postgres_get_wire_accounts ;
plugin - > get_wire_fees
= & postgres_get_wire_fees ;
2020-11-29 17:27:53 +01:00
plugin - > insert_signkey_revocation
= & postgres_insert_signkey_revocation ;
2020-12-26 16:29:20 +01:00
plugin - > lookup_signkey_revocation
= & postgres_lookup_signkey_revocation ;
2020-11-29 17:27:53 +01:00
plugin - > lookup_denomination_key
= & postgres_lookup_denomination_key ;
plugin - > insert_auditor_denom_sig
= & postgres_insert_auditor_denom_sig ;
2020-12-22 18:27:34 +01:00
plugin - > select_auditor_denom_sig
= & postgres_select_auditor_denom_sig ;
2020-12-10 11:49:20 +01:00
plugin - > add_denomination_key
= & postgres_add_denomination_key ;
plugin - > lookup_signing_key
= & postgres_lookup_signing_key ;
2021-06-20 16:41:04 +02:00
plugin - > begin_shard
= & postgres_begin_shard ;
2022-04-14 00:00:50 +02:00
plugin - > abort_shard
= & postgres_abort_shard ;
2021-06-20 16:41:04 +02:00
plugin - > complete_shard
= & postgres_complete_shard ;
2021-09-03 19:08:02 +02:00
plugin - > release_revolving_shard
= & postgres_release_revolving_shard ;
2021-12-26 13:05:39 +01:00
plugin - > delete_shard_locks
= & postgres_delete_shard_locks ;
2022-11-04 12:18:16 +01:00
plugin - > set_extension_manifest
= & postgres_set_extension_manifest ;
2022-03-23 12:25:22 +01:00
plugin - > insert_partner
= & postgres_insert_partner ;
2022-05-16 15:43:40 +02:00
plugin - > expire_purse
= & postgres_expire_purse ;
2022-03-23 12:25:22 +01:00
plugin - > select_purse_by_merge_pub
= & postgres_select_purse_by_merge_pub ;
2022-06-19 14:04:41 +02:00
plugin - > set_purse_balance
= & postgres_set_purse_balance ;
2022-11-10 16:37:28 +01:00
2022-10-03 23:54:12 +02:00
/* NEW style, sort alphabetically! */
2022-10-12 14:48:49 +02:00
plugin - > do_reserve_open
= & TEH_PG_do_reserve_open ;
2022-11-08 17:40:47 +01:00
plugin - > drop_tables
= & TEH_PG_drop_tables ;
2022-11-08 13:34:53 +01:00
plugin - > do_withdraw
= & TEH_PG_do_withdraw ;
2022-10-13 22:43:22 +02:00
plugin - > free_coin_transaction_list
= & TEH_COMMON_free_coin_transaction_list ;
plugin - > free_reserve_history
= & TEH_COMMON_free_reserve_history ;
plugin - > get_coin_transactions
= & TEH_PG_get_coin_transactions ;
2022-10-13 19:07:25 +02:00
plugin - > get_expired_reserves
= & TEH_PG_get_expired_reserves ;
2022-11-08 13:28:17 +01:00
plugin - > get_purse_request
= & TEH_PG_get_purse_request ;
2022-10-15 16:19:14 +02:00
plugin - > get_reserve_history
= & TEH_PG_get_reserve_history ;
plugin - > get_reserve_status
= & TEH_PG_get_reserve_status ;
2022-10-13 19:07:25 +02:00
plugin - > get_unfinished_close_requests
= & TEH_PG_get_unfinished_close_requests ;
2022-10-08 18:07:05 +02:00
plugin - > insert_records_by_table
= & TEH_PG_insert_records_by_table ;
2022-10-04 19:18:43 +02:00
plugin - > insert_reserve_open_deposit
= & TEH_PG_insert_reserve_open_deposit ;
2022-10-03 23:54:12 +02:00
plugin - > insert_close_request
= & TEH_PG_insert_close_request ;
2022-11-07 16:35:34 +01:00
plugin - > delete_aggregation_transient
= & TEH_PG_delete_aggregation_transient ;
plugin - > get_link_data
= & TEH_PG_get_link_data ;
2022-10-03 23:54:12 +02:00
plugin - > iterate_reserve_close_info
= & TEH_PG_iterate_reserve_close_info ;
plugin - > iterate_kyc_reference
= & TEH_PG_iterate_kyc_reference ;
2022-10-10 08:20:36 +02:00
plugin - > lookup_records_by_table
= & TEH_PG_lookup_records_by_table ;
plugin - > lookup_serial_by_table
= & TEH_PG_lookup_serial_by_table ;
2022-11-02 12:17:05 +01:00
plugin - > select_account_merges_above_serial_id
= & TEH_PG_select_account_merges_above_serial_id ;
plugin - > select_all_purse_decisions_above_serial_id
= & TEH_PG_select_all_purse_decisions_above_serial_id ;
plugin - > select_purse
= & TEH_PG_select_purse ;
plugin - > select_purse_deposits_above_serial_id
= & TEH_PG_select_purse_deposits_above_serial_id ;
plugin - > select_purse_merges_above_serial_id
= & TEH_PG_select_purse_merges_above_serial_id ;
plugin - > select_purse_requests_above_serial_id
= & TEH_PG_select_purse_requests_above_serial_id ;
2022-10-03 23:54:12 +02:00
plugin - > select_reserve_close_info
= & TEH_PG_select_reserve_close_info ;
2022-10-30 17:36:57 +01:00
plugin - > select_reserve_closed_above_serial_id
= & TEH_PG_select_reserve_closed_above_serial_id ;
plugin - > select_reserve_open_above_serial_id
= & TEH_PG_select_reserve_open_above_serial_id ;
2022-11-10 16:37:28 +01:00
/*need to sort*/
2022-11-08 13:28:17 +01:00
plugin - > insert_purse_request
= & TEH_PG_insert_purse_request ;
2022-11-08 15:21:01 +01:00
plugin - > iterate_active_signkeys
= & TEH_PG_iterate_active_signkeys ;
plugin - > commit
= & TEH_PG_commit ;
2022-11-08 17:40:47 +01:00
plugin - > preflight
= & TEH_PG_preflight ;
plugin - > create_shard_tables
= & TEH_PG_create_shard_tables ;
plugin - > insert_aggregation_tracking
= & TEH_PG_insert_aggregation_tracking ;
plugin - > setup_partitions
= & TEH_PG_setup_partitions ;
2022-11-10 16:37:28 +01:00
plugin - > select_aggregation_amounts_for_kyc_check
= & TEH_PG_select_aggregation_amounts_for_kyc_check ;
plugin - > select_satisfied_kyc_processes
= & TEH_PG_select_satisfied_kyc_processes ;
plugin - > kyc_provider_account_lookup
= & TEH_PG_kyc_provider_account_lookup ;
plugin - > lookup_kyc_requirement_by_row
= & TEH_PG_lookup_kyc_requirement_by_row ;
plugin - > insert_kyc_requirement_for_account
2022-11-14 05:08:11 +01:00
= & TEH_PG_insert_kyc_requirement_for_account ;
2022-11-10 16:37:28 +01:00
plugin - > lookup_kyc_process_by_account
= & TEH_PG_lookup_kyc_process_by_account ;
plugin - > update_kyc_process_by_row
= & TEH_PG_update_kyc_process_by_row ;
plugin - > insert_kyc_requirement_process
= & TEH_PG_insert_kyc_requirement_process ;
plugin - > select_withdraw_amounts_for_kyc_check
= & TEH_PG_select_withdraw_amounts_for_kyc_check ;
plugin - > select_merge_amounts_for_kyc_check
= & TEH_PG_select_merge_amounts_for_kyc_check ;
plugin - > profit_drains_set_finished
= & TEH_PG_profit_drains_set_finished ;
plugin - > profit_drains_get_pending
= & TEH_PG_profit_drains_get_pending ;
plugin - > get_drain_profit
= & TEH_PG_get_drain_profit ;
plugin - > get_purse_deposit
= & TEH_PG_get_purse_deposit ;
plugin - > insert_contract
= & TEH_PG_insert_contract ;
plugin - > select_contract
= & TEH_PG_select_contract ;
plugin - > select_purse_merge
= & TEH_PG_select_purse_merge ;
plugin - > select_contract_by_purse
= & TEH_PG_select_contract_by_purse ;
plugin - > insert_drain_profit
= & TEH_PG_insert_drain_profit ;
plugin - > do_reserve_purse
= & TEH_PG_do_reserve_purse ;
plugin - > lookup_global_fee_by_time
= & TEH_PG_lookup_global_fee_by_time ;
plugin - > do_purse_deposit
= & TEH_PG_do_purse_deposit ;
plugin - > activate_signing_key
= & TEH_PG_activate_signing_key ;
plugin - > update_auditor
= & TEH_PG_update_auditor ;
plugin - > begin_revolving_shard
= & TEH_PG_begin_revolving_shard ;
plugin - > get_extension_manifest
= & TEH_PG_get_extension_manifest ;
plugin - > insert_history_request
= & TEH_PG_insert_history_request ;
plugin - > do_purse_merge
= & TEH_PG_do_purse_merge ;
plugin - > start_read_committed
= & TEH_PG_start_read_committed ;
plugin - > start_read_only
= & TEH_PG_start_read_only ;
plugin - > insert_denomination_info
= & TEH_PG_insert_denomination_info ;
plugin - > do_batch_withdraw_insert
= & TEH_PG_do_batch_withdraw_insert ;
plugin - > lookup_wire_fee_by_time
= & TEH_PG_lookup_wire_fee_by_time ;
plugin - > start
= & TEH_PG_start ;
plugin - > rollback
= & TEH_PG_rollback ;
2022-10-03 23:54:12 +02:00
2022-11-10 16:37:28 +01:00
2015-03-20 23:51:28 +01:00
return plugin ;
2015-01-28 22:47:03 +01:00
}
2015-03-20 23:51:28 +01:00
/**
* Shutdown Postgres database subsystem .
*
2016-03-01 15:35:04 +01:00
* @ param cls a ` struct TALER_EXCHANGEDB_Plugin `
2015-03-20 23:51:28 +01:00
* @ return NULL ( always )
*/
void *
2016-03-01 15:35:04 +01:00
libtaler_plugin_exchangedb_postgres_done ( void * cls )
2015-03-20 23:51:28 +01:00
{
2016-03-01 15:35:04 +01:00
struct TALER_EXCHANGEDB_Plugin * plugin = cls ;
2015-03-20 23:51:28 +01:00
struct PostgresClosure * pg = plugin - > cls ;
2021-08-23 00:00:32 +02:00
if ( NULL ! = pg - > conn )
2021-11-21 15:16:58 +01:00
{
2021-08-23 00:00:32 +02:00
GNUNET_PQ_disconnect ( pg - > conn ) ;
2021-11-21 15:16:58 +01:00
pg - > conn = NULL ;
}
2021-10-29 11:28:12 +02:00
GNUNET_free ( pg - > exchange_url ) ;
2020-01-17 03:08:30 +01:00
GNUNET_free ( pg - > sql_dir ) ;
2019-09-05 03:53:47 +02:00
GNUNET_free ( pg - > currency ) ;
2015-03-20 23:51:28 +01:00
GNUNET_free ( pg ) ;
GNUNET_free ( plugin ) ;
return NULL ;
}
2019-10-31 12:59:50 +01:00
2016-03-01 15:35:04 +01:00
/* end of plugin_exchangedb_postgres.c */