exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit e8a4dded80704b5d21a73d4ccefc403ca53f9828
parent 3f2e0af9919658227a00b0bb18f4bd2de5acecb6
Author: Christian Grothoff <grothoff@gnu.org>
Date:   Wed,  8 Apr 2026 21:27:51 +0200

remove DB plugins (part I)

Diffstat:
Asrc/auditordb/del_denomination_balance.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/del_reserve_info.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/delete_auditor_closure_lag.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/delete_early_aggregation.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/delete_generic.c | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/delete_pending_deposit.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/delete_purse_info.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/delete_reserve_in_inconsistency.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/delete_wire_out_inconsistency_if_matching.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_amount_arithmetic_inconsistency.c | 175+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_auditor_closure_lags.c | 173+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_auditor_progress.c | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_bad_sig_losses.c | 181+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_balance.c | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_balances.c | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_coin_inconsistency.c | 185+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_denomination_balance.c | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_denomination_key_validity_withdraw_inconsistency.c | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_denomination_pending.c | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_denominations_without_sigs.c | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_deposit_confirmations.c | 232+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_emergency.c | 180+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_emergency_by_count.c | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_exchange_signkeys.c | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_fee_time_inconsistency.c | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_misattribution_in_inconsistency.c | 168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_progress_points.c | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_purse_info.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_purse_not_closed_inconsistencies.c | 168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_purses.c | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_reserve_balance_insufficient_inconsistency.c | 168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_reserve_balance_summary_wrong_inconsistency.c | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_reserve_in_inconsistency.c | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_reserve_info.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_reserve_not_closed_inconsistency.c | 169+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_reserves.c | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_row_inconsistency.c | 174+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_row_minor_inconsistencies.c | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_wire_fee_summary.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_wire_format_inconsistency.c | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/get_wire_out_inconsistency.c | 173+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/helper.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_amount_arithmetic_inconsistency.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_auditor_closure_lags.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_auditor_progress.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_bad_sig_losses.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_balance.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_coin_inconsistency.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_denomination_balance.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_denomination_key_validity_withdraw_inconsistency.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_denomination_pending.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_denominations_without_sigs.c | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_deposit_confirmation.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_early_aggregation.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_emergency.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_emergency_by_count.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_exchange_signkey.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_fee_time_inconsistency.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_historic_denom_revenue.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_historic_reserve_revenue.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_misattribution_in_inconsistency.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_pending_deposit.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_purse_info.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_purse_not_closed_inconsistencies.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_reserve_balance_insufficient_inconsistency.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_reserve_balance_summary_wrong_inconsistency.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_reserve_in_inconsistency.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_reserve_info.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_reserve_not_closed_inconsistency.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_row_inconsistency.c | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_row_minor_inconsistencies.c | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_wire_format_inconsistency.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/insert_wire_out_inconsistency.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/lookup_reserve_in_inconsistency.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/auditordb/plugin_auditordb_postgres.c | 505++++++++++++++++++++++---------------------------------------------------------
Asrc/auditordb/select_early_aggregations.c | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/select_historic_denom_revenue.c | 172+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/select_historic_reserve_revenue.c | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/select_pending_deposits.c | 183+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/select_purse_expired.c | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/select_reserve_in_inconsistency.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/template.c | 26++++++++++++++++++++++++++
Asrc/auditordb/update_auditor_progress.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/update_balance.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/update_denomination_balance.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/update_generic_suppressed.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/update_purse_info.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/update_reserve_info.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/auditordb/update_wire_fee_summary.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/abort_shard.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/activate_signing_key.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/add_denomination_key.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/add_policy_fulfillment_proof.c | 157+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/aggregate.c | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/batch_ensure_coin_known.c | 459+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/begin_revolving_shard.c | 259+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/begin_shard.c | 264+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/clear_aml_lock.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/commit.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/complete_shard.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/compute_shard.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/count_known_coins.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/create_aggregation_transient.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/create_tables.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/delete_aggregation_transient.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/delete_shard_locks.c | 40++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/disable_rules.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_check_deposit_idempotent.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_deposit.c | 173+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_purse_delete.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_purse_deposit.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_purse_merge.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_recoup.c | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_recoup_refresh.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_refresh.c | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_refund.c | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_reserve_open.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_reserve_purse.c | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/do_withdraw.c | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/drain_kyc_alert.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/drop_tables.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/enable_rules.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/ensure_coin_known.c | 168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/event_listen.c | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/event_listen_cancel.c | 36++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/event_notify.c | 39+++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/expire_purse.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/find_aggregation_transient.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/gc.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_coin_denomination.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_coin_transactions.c | 1188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_denomination_by_serial.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_denomination_info.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_denomination_revocation.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_drain_profit.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_expired_reserves.c | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_extension_manifest.c | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_global_fee.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_global_fees.c | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_known_coin.c | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_kyc_rules.c | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_old_coin_by_h_blind.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_pending_kyc_requirement_process.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_policy_details.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_purse_deposit.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_purse_request.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_ready_deposit.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_refresh.c | 207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_reserve_balance.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_reserve_by_h_planchets.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_reserve_history.c | 998+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_signature_for_known_coin.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_unfinished_close_requests.c | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_wire_accounts.c | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_wire_fee.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_wire_fees.c | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_wire_hash_for_contract.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/get_withdraw.c | 193+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/have_deposit2.c | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/inject_auditor_triggers.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_active_legitimization_measure.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_aml_decision.c | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_aml_officer.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_aml_program_failure.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_auditor.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_auditor_denom_sig.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_close_request.c | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_contract.c | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_denomination_info.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_denomination_revocation.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_drain_profit.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_global_fee.c | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_kyc_failure.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_kyc_requirement_process.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_partner.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_purse_request.c | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_records_by_table.c | 2451+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_refund.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_reserve_closed.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_reserve_open_deposit.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_sanction_list_hit.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_signkey_revocation.c | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_successor_measure.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_wire.c | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/insert_wire_fee.c | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/iterate_active_auditors.c | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/iterate_active_signkeys.c | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/iterate_auditor_denominations.c | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/iterate_denomination_info.c | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/iterate_denominations.c | 175+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/iterate_kyc_reference.c | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/iterate_reserve_close_info.c | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/kyc_provider_account_lookup.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/kycauth_in_insert.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_active_legitimization.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_aml_file_number.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_aml_history.c | 202+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_aml_officer.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_auditor_status.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_auditor_timestamp.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_completed_legitimization.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_denomination_key.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_global_fee_by_time.c | 180+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_h_payto_by_access_token.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_kyc_history.c | 193+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_kyc_process_by_account.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_kyc_requirement_by_row.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_kyc_status_by_token.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_pending_legitimization.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_records_by_table.c | 3802+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_rules_by_access_token.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_serial_by_table.c | 466+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_signing_key.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_signkey_revocation.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_transfer_by_deposit.c | 222+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_wire_fee_by_time.c | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_wire_timestamp.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/lookup_wire_transfer.c | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/mark_refresh_reveal_success.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/persist_kyc_attributes.c | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/persist_policy_details.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/exchangedb/plugin_exchangedb_postgres.c | 870+++++++++++++++++++++----------------------------------------------------------
Asrc/exchangedb/preflight.c | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/profit_drains_get_pending.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/profit_drains_set_finished.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/release_revolving_shard.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/reserves_get.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/reserves_get_origin.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/reserves_in_insert.c | 377+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/reserves_update.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/rollback.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_account_merges_above_serial_id.c | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_aggregation_amounts_for_kyc_check.c | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_aggregation_transient.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_aggregations_above_serial.c | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_all_kyc_attributes.c | 170+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_all_purse_decisions_above_serial_id.c | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_all_purse_deletions_above_serial_id.c | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_aml_attributes.c | 191+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_aml_decisions.c | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_aml_measures.c | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_aml_statistics.c | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_auditor_denom_sig.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_batch_deposits_missing_wire.c | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_coin_deposits_above_serial_id.c | 202+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_contract.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_contract_by_purse.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_deposit_amounts_for_kyc_check.c | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_exchange_credit_transfers.c | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_exchange_debit_transfers.c | 183+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_exchange_kycauth_transfers.c | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_kyc_accounts.c | 237+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_kyc_attributes.c | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_merge_amounts_for_kyc_check.c | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_purse.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_purse_by_merge_pub.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_purse_decisions_above_serial_id.c | 160+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_purse_deposits_above_serial_id.c | 200+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_purse_deposits_by_purse.c | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_purse_merge.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_purse_merges_above_serial_id.c | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_purse_requests_above_serial_id.c | 176+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_recoup_above_serial_id.c | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_recoup_refresh_above_serial_id.c | 206+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_refreshes_above_serial_id.c | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_refunds_above_serial_id.c | 221+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_refunds_by_coin.c | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_reserve_close_info.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_reserve_closed_above_serial_id.c | 175+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_reserve_open_above_serial_id.c | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_reserves_in_above_serial_id.c | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_reserves_in_above_serial_id_by_account.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_wire_out_above_serial_id.c | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_wire_out_above_serial_id_by_account.c | 159+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_withdraw_amounts_for_kyc_check.c | 160+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/select_withdrawals_above_serial_id.c | 214+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/set_aml_lock.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/set_extension_manifest.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/set_purse_balance.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/start.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/start_deferred_wire_out.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/start_read_committed.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/start_read_only.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/store_wire_transfer_out.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/test_aml_officer.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/trigger_kyc_rule_for_account.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/update_aggregation_transient.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/update_auditor.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/update_kyc_process_by_row.c | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/update_wire.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/wad_in_insert.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/wire_prepare_data_get.c | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/wire_prepare_data_insert.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/wire_prepare_data_mark_failed.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/wire_prepare_data_mark_finished.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/del_denomination_balance.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/del_reserve_info.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/delete_auditor_closure_lag.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/delete_early_aggregation.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/delete_generic.h | 39+++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/delete_pending_deposit.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/delete_purse_info.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/delete_reserve_in_inconsistency.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/delete_wire_out_inconsistency_if_matching.h | 36++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_amount_arithmetic_inconsistency.h | 383+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_auditor_closure_lags.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_auditor_progress.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_bad_sig_losses.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_balance.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_balances.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_coin_inconsistency.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_denomination_balance.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_denomination_key_validity_withdraw_inconsistency.h | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_denomination_pending.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_denominations_without_sigs.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_deposit_confirmations.h | 292+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_emergency.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_emergency_by_count.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_exchange_signkeys.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_fee_time_inconsistency.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_misattribution_in_inconsistency.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_progress_points.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_purse_info.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_purse_not_closed_inconsistencies.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_purses.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_reserve_balance_insufficient_inconsistency.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_reserve_balance_summary_wrong_inconsistency.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_reserve_in_inconsistency.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_reserve_info.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_reserve_not_closed_inconsistency.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_reserves.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_row_inconsistency.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_row_minor_inconsistencies.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_wire_fee_summary.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_wire_format_inconsistency.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/get_wire_out_inconsistency.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_amount_arithmetic_inconsistency.h | 37+++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_auditor_closure_lags.h | 37+++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_auditor_progress.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_bad_sig_losses.h | 36++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_balance.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_coin_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_denomination_balance.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_denomination_key_validity_withdraw_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_denomination_pending.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_denominations_without_sigs.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_deposit_confirmation.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_early_aggregation.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_emergency.h | 37+++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_emergency_by_count.h | 37+++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_exchange_signkey.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_fee_time_inconsistency.h | 37+++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_historic_denom_revenue.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_historic_reserve_revenue.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_misattribution_in_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_pending_deposit.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_purse_info.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_purse_not_closed_inconsistencies.h | 37+++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_reserve_balance_insufficient_inconsistency.h | 37+++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_reserve_balance_summary_wrong_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_reserve_in_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_reserve_info.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_reserve_not_closed_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_row_inconsistency.h | 37+++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_row_minor_inconsistencies.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_wire_format_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/insert_wire_out_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/lookup_reserve_in_inconsistency.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/select_early_aggregations.h | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/select_historic_denom_revenue.h | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/select_historic_reserve_revenue.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/select_pending_deposits.h | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/select_purse_expired.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/select_reserve_in_inconsistency.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/template.h | 31+++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/update_auditor_progress.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/update_balance.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/update_denomination_balance.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/update_generic_suppressed.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/update_purse_info.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/update_reserve_info.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/auditor-database/update_wire_fee_summary.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/abort_shard.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/activate_signing_key.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/add_denomination_key.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/add_policy_fulfillment_proof.h | 40++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/aggregate.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/batch_ensure_coin_known.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/begin_revolving_shard.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/begin_shard.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/clear_aml_lock.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/commit.h | 39+++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/complete_shard.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/compute_shard.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/count_known_coins.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/create_aggregation_transient.h | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/create_tables.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/delete_aggregation_transient.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/delete_shard_locks.h | 40++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/disable_rules.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_check_deposit_idempotent.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_deposit.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_purse_delete.h | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_purse_deposit.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_purse_merge.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_recoup.h | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_recoup_refresh.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_refresh.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_refund.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_reserve_open.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_reserve_purse.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/do_withdraw.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/drain_kyc_alert.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/drop_tables.h | 40++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/enable_rules.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/ensure_coin_known.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/event_listen.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/event_listen_cancel.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/event_notify.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/expire_purse.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/find_aggregation_transient.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/gc.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_coin_denomination.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_coin_transactions.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_denomination_by_serial.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_denomination_info.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_denomination_revocation.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_drain_profit.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_expired_reserves.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_extension_manifest.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_global_fee.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_global_fees.h | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_known_coin.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_kyc_rules.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_old_coin_by_h_blind.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_pending_kyc_requirement_process.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_policy_details.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_purse_deposit.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_purse_request.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_ready_deposit.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_refresh.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_reserve_balance.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_reserve_by_h_planchets.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_reserve_history.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_signature_for_known_coin.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_unfinished_close_requests.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_wire_accounts.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_wire_fee.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_wire_fees.h | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_wire_hash_for_contract.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/get_withdraw.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/have_deposit2.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/inject_auditor_triggers.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_active_legitimization_measure.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_aml_decision.h | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_aml_officer.h | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_aml_program_failure.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_auditor.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_auditor_denom_sig.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_close_request.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_contract.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_denomination_info.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_denomination_revocation.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_drain_profit.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_global_fee.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_kyc_failure.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_kyc_requirement_process.h | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_partner.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_purse_request.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_records_by_table.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_refund.h | 40++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_reserve_closed.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_reserve_open_deposit.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_sanction_list_hit.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_signkey_revocation.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_successor_measure.h | 40++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_wire.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/insert_wire_fee.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/iterate_active_auditors.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/iterate_active_signkeys.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/iterate_auditor_denominations.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/iterate_denomination_info.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/iterate_denominations.h | 287+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/iterate_kyc_reference.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/iterate_reserve_close_info.h | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/kyc_provider_account_lookup.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/kycauth_in_insert.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_active_legitimization.h | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_aml_file_number.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_aml_history.h | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_aml_officer.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_auditor_status.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_auditor_timestamp.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_completed_legitimization.h | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_denomination_key.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_global_fee_by_time.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_h_payto_by_access_token.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_kyc_history.h | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_kyc_process_by_account.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_kyc_requirement_by_row.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_kyc_status_by_token.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_pending_legitimization.h | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_records_by_table.h | 904+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_rules_by_access_token.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_serial_by_table.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_signing_key.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_signkey_revocation.h | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_transfer_by_deposit.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_wire_fee_by_time.h | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_wire_timestamp.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/lookup_wire_transfer.h | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/mark_refresh_reveal_success.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/persist_kyc_attributes.h | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/persist_policy_details.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/preflight.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/profit_drains_get_pending.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/profit_drains_set_finished.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/release_revolving_shard.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/reserves_get.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/reserves_get_origin.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/reserves_in_insert.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/reserves_update.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/rollback.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_account_merges_above_serial_id.h | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_aggregation_amounts_for_kyc_check.h | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_aggregation_transient.h | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_aggregations_above_serial.h | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_all_kyc_attributes.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_all_purse_decisions_above_serial_id.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_all_purse_deletions_above_serial_id.h | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_aml_attributes.h | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_aml_decisions.h | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_aml_measures.h | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_aml_statistics.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_auditor_denom_sig.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_batch_deposits_missing_wire.h | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_coin_deposits_above_serial_id.h | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_contract.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_contract_by_purse.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_deposit_amounts_for_kyc_check.h | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_exchange_credit_transfers.h | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_exchange_debit_transfers.h | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_exchange_kycauth_transfers.h | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_kyc_accounts.h | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_kyc_attributes.h | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_merge_amounts_for_kyc_check.h | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_purse.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_purse_by_merge_pub.h | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_purse_decisions_above_serial_id.h | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_purse_deposits_above_serial_id.h | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_purse_deposits_by_purse.h | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_purse_merge.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_purse_merges_above_serial_id.h | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_purse_requests_above_serial_id.h | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_recoup_above_serial_id.h | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_recoup_refresh_above_serial_id.h | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_refreshes_above_serial_id.h | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_refunds_above_serial_id.h | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_refunds_by_coin.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_reserve_close_info.h | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_reserve_closed_above_serial_id.h | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_reserve_open_above_serial_id.h | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_reserves_in_above_serial_id.h | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_reserves_in_above_serial_id_by_account.h | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_wire_out_above_serial_id.h | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_wire_out_above_serial_id_by_account.h | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_withdraw_amounts_for_kyc_check.h | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/select_withdrawals_above_serial_id.h | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/set_aml_lock.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/set_extension_manifest.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/set_purse_balance.h | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/start.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/start_deferred_wire_out.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/start_read_committed.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/start_read_only.h | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/store_wire_transfer_out.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/test_aml_officer.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/trigger_kyc_rule_for_account.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/update_aggregation_transient.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/update_auditor.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/update_kyc_process_by_row.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/update_wire.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/wad_in_insert.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/wire_prepare_data_get.h | 1753+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/wire_prepare_data_insert.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/wire_prepare_data_mark_failed.h | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/include/taler/exchange-database/wire_prepare_data_mark_finished.h | 41+++++++++++++++++++++++++++++++++++++++++
587 files changed, 59333 insertions(+), 1010 deletions(-)

diff --git a/src/auditordb/del_denomination_balance.c b/src/auditordb/del_denomination_balance.c @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/del_denomination_balance.c + * @brief Implementation of the del_denomination_balance function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "del_denomination_balance.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_del_denomination_balance (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_del_denomination_balance", + "DELETE" + " FROM auditor_denomination_pending" + " WHERE denom_pub_hash=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_del_denomination_balance", + params); +} diff --git a/src/auditordb/del_reserve_info.c b/src/auditordb/del_reserve_info.c @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_del_reserve_info.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "del_reserve_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_del_reserve_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_del_reserve_info", + "DELETE" + " FROM auditor_reserves" + " WHERE reserve_pub=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_del_reserve_info", + params); +} diff --git a/src/auditordb/delete_auditor_closure_lag.c b/src/auditordb/delete_auditor_closure_lag.c @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/delete_auditor_closure_lag.c + * @brief Implementation of the delete_auditor_closure_lag function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "delete_auditor_closure_lag.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_auditor_closure_lag (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_Amount *amount, + const struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_FullPayto credit_account_uri) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + amount), + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_string (credit_account_uri.full_payto), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "delete_auditor_closure_lag", + "DELETE FROM auditor_closure_lags " + " WHERE (amount).frac=($1::taler_amount).frac" + " AND (amount).val=($1::taler_amount).val" + " AND wtid=$2" + " AND account=$3;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "delete_auditor_closure_lag", + params); +} diff --git a/src/auditordb/delete_early_aggregation.c b/src/auditordb/delete_early_aggregation.c @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/delete_early_aggregation.c + * @brief Implementation of the delete_early_aggregation function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "delete_early_aggregation.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_early_aggregation (struct AUDITORDB_PostgresContext *ctx, + uint64_t batch_deposit_serial_id) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&batch_deposit_serial_id), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_delete_early_aggregation", + "DELETE" + " FROM auditor_early_aggregations" + " WHERE batch_deposit_serial_id=$1;"); + return GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "auditor_delete_early_aggregation", + params); +} diff --git a/src/auditordb/delete_generic.c b/src/auditordb/delete_generic.c @@ -0,0 +1,83 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "delete_generic.h" + +struct Preparations +{ + /** + * Database reconnect counter. + */ + unsigned long long cnt; + + /** + * Which DB did we do prepare for. + */ + struct AUDITORDB_PostgresContext *ctx; + +}; + +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_generic (struct AUDITORDB_PostgresContext *ctx, + enum TALER_AUDITORDB_DeletableSuppressableTables table, + uint64_t row_id) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&row_id), + GNUNET_PQ_query_param_end + }; + static struct Preparations preps[ + TALER_AUDITORDB_DELETABLESUPPRESSABLE_TABLES_MAX]; + + struct Preparations *prep = &preps[table]; + const char *table_name = AUDITORDB_get_deletable_suppressable_table_name (table); + char statement_name[256]; + + GNUNET_snprintf (statement_name, + sizeof (statement_name), + "delete_%s", + table_name); + if ( (ctx != prep->ctx) || + (prep->cnt < ctx->prep_gen) ) + { + char sql[256]; + struct GNUNET_PQ_PreparedStatement ps[] = { + GNUNET_PQ_make_prepare (statement_name, + sql), + GNUNET_PQ_PREPARED_STATEMENT_END + }; + + GNUNET_snprintf (sql, + sizeof (sql), + "DELETE FROM %s" + " WHERE row_id=$1", + table_name); + if (GNUNET_OK != + GNUNET_PQ_prepare_statements (ctx->conn, + ps)) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + prep->ctx = ctx; + prep->cnt = ctx->prep_gen; + } + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + statement_name, + params); +} diff --git a/src/auditordb/delete_pending_deposit.c b/src/auditordb/delete_pending_deposit.c @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/delete_pending_deposit.c + * @brief Implementation of the delete_pending_deposit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "delete_pending_deposit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_pending_deposit (struct AUDITORDB_PostgresContext *ctx, + uint64_t batch_deposit_serial_id) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&batch_deposit_serial_id), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_delete_pending_deposit", + "DELETE" + " FROM auditor_pending_deposits" + " WHERE batch_deposit_serial_id=$1;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_delete_pending_deposit", + params); +} diff --git a/src/auditordb/delete_purse_info.c b/src/auditordb/delete_purse_info.c @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/delete_purse_info.c + * @brief Implementation of the delete_purse_info function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "delete_purse_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_purse_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_purses_delete", + "DELETE FROM auditor_purses " + " WHERE purse_pub=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_purses_delete", + params); +} diff --git a/src/auditordb/delete_reserve_in_inconsistency.c b/src/auditordb/delete_reserve_in_inconsistency.c @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/delete_reserve_in_inconsistency.c + * @brief Implementation of the delete_reserve_in_inconsistency function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "delete_reserve_in_inconsistency.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + uint64_t row_id) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&row_id), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "delete_reserve_in_inconsistency", + "DELETE FROM auditor_reserve_in_inconsistency " + " WHERE row_id=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "delete_reserve_in_inconsistency", + params); +} diff --git a/src/auditordb/delete_wire_out_inconsistency_if_matching.c b/src/auditordb/delete_wire_out_inconsistency_if_matching.c @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "delete_wire_out_inconsistency_if_matching.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_wire_out_inconsistency_if_matching (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_WireOutInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->destination_account.full_payto), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_uint64 (&dc->wire_out_row_id), + TALER_PQ_query_param_amount (ctx->conn, + &dc->expected), + TALER_PQ_query_param_amount (ctx->conn, + &dc->claimed), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_wire_out_inconsistency_delete_if_matching", + "DELETE FROM auditor_wire_out_inconsistency " + " WHERE destination_account=$1" + " AND diagnostic=$2" + " AND wire_out_serial_id=$3" + " AND (expected).val=($4::taler_amount).val" + " AND (expected).frac=($4::taler_amount).frac" + " AND (claimed).val=($5::taler_amount).val" + " AND (claimed).frac=($5::taler_amount).frac;" + ); + return GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "auditor_wire_out_inconsistency_delete_if_matching", + params); +} diff --git a/src/auditordb/get_amount_arithmetic_inconsistency.c b/src/auditordb/get_amount_arithmetic_inconsistency.c @@ -0,0 +1,175 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_amount_arithmetic_inconsistency.h" + +/** + * Closure for #deposit_confirmation_cb(). + */ +struct AmountArithmeticInconsistencyContext +{ + + /** + * Function to call for each deposit confirmation. + */ + TALER_AUDITORDB_AmountArithmeticInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_deposit_confirmations(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct DepositConfirmationContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +amount_arithmetic_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AmountArithmeticInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_AmountArithmeticInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_uint64 ("problem_row_id", + &dc.problem_row_id), + GNUNET_PQ_result_spec_string ("operation", + &dc.operation), + TALER_PQ_RESULT_SPEC_AMOUNT ("exchange_amount", + &dc.exchange_amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("auditor_amount", + &dc.auditor_amount), + GNUNET_PQ_result_spec_bool ("profitable", + &dc.profitable), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_amount_arithmetic_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_AmountArithmeticInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct AmountArithmeticInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_amount_arithmetic_inconsistency_select_desc", + "SELECT" + " row_id" + ",problem_row_id" + ",operation" + ",exchange_amount" + ",auditor_amount" + ",profitable" + ",suppressed" + " FROM auditor_amount_arithmetic_inconsistency" + " WHERE (row_id<$1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_amount_arithmetic_inconsistency_select_asc", + "SELECT" + " row_id" + ",problem_row_id" + ",operation" + ",exchange_amount" + ",auditor_amount" + ",profitable" + ",suppressed" + " FROM auditor_amount_arithmetic_inconsistency" + " WHERE (row_id>$1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_amount_arithmetic_inconsistency_select_asc" + : "auditor_amount_arithmetic_inconsistency_select_desc", + params, + &amount_arithmetic_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_auditor_closure_lags.c b/src/auditordb/get_auditor_closure_lags.c @@ -0,0 +1,173 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_auditor_closure_lags.h" + + +struct ClosureLagsContext +{ + + /** + * Function to call for each closure lag . + */ + TALER_AUDITORDB_ClosureLagsCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_auditor_closure_lags(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct ClosureLagsContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +closure_lags_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ClosureLagsContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_ClosureLags dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_uint64 ("problem_row_id", + &dc.problem_row_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &dc.amount), + GNUNET_PQ_result_spec_absolute_time ("deadline", + &dc.deadline), + GNUNET_PQ_result_spec_auto_from_type ("wtid", + &dc.wtid), + GNUNET_PQ_result_spec_string ("account", + &dc.account.full_payto), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_auditor_closure_lags (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ClosureLagsCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct ClosureLagsContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_closure_lags_get_desc", + "SELECT" + " row_id" + ",problem_row_id" + ",amount" + ",deadline" + ",wtid" + ",account" + ",suppressed" + " FROM auditor_closure_lags" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_closure_lags_get_asc", + "SELECT" + " row_id" + ",problem_row_id" + ",amount" + ",deadline" + ",wtid" + ",account" + ",suppressed" + " FROM auditor_closure_lags" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_closure_lags_get_asc" + : "auditor_closure_lags_get_desc", + params, + &closure_lags_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_auditor_progress.c b/src/auditordb/get_auditor_progress.c @@ -0,0 +1,178 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_auditor_progress.c + * @brief Implementation of get_auditor_progress function + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_auditor_progress.h" +#include "pg_helper.h" + + +/** + * Closure for #auditor_progress_cb(). + */ +struct AuditorProgressContext +{ + + /** + * Where to store results. + */ + uint64_t **dst; + + /** + * Offset in @e dst. + */ + unsigned int off; + + /** + * Length of array at @e dst. + */ + unsigned int len; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Set to true on failure. + */ + bool failure; +}; + + +/** + * Helper function for #AUDITORDB_get_auditor_progress(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct AuditorProgressContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +auditor_progress_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AuditorProgressContext *ctx = cls; + + GNUNET_assert (num_results == ctx->len); + for (unsigned int i = 0; i < num_results; i++) + { + bool is_missing = false; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ("progress_offset", + ctx->dst[i]), + &is_missing), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->failure = true; + return; + } + if (is_missing) + *ctx->dst[i] = 0; + ctx->off++; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_auditor_progress (struct AUDITORDB_PostgresContext *ctx, + const char *progress_key, + uint64_t *progress_offset, + ...) +{ + unsigned int cnt = 1; + va_list ap; + + va_start (ap, + progress_offset); + while (NULL != va_arg (ap, + const char *)) + { + cnt++; + (void) va_arg (ap, + uint64_t *); + } + va_end (ap); + { + const char *keys[cnt]; + uint64_t *dsts[cnt]; + unsigned int off = 1; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_array_ptrs_string (cnt, + keys, + ctx->conn), + GNUNET_PQ_query_param_end + }; + struct AuditorProgressContext ctx = { + .dst = dsts, + .len = cnt, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + keys[0] = progress_key; + dsts[0] = progress_offset; + va_start (ap, + progress_offset); + while (off < cnt) + { + keys[off] = va_arg (ap, + const char *); + dsts[off] = va_arg (ap, + uint64_t *); + off++; + } + GNUNET_assert (NULL == va_arg (ap, + const char *)); + va_end (ap); + + PREPARE (ctx, + "get_auditor_progress", + "SELECT" + " auditor_do_get_auditor_progress AS progress_offset" + " FROM auditor_do_get_auditor_progress " + "($1);"); + ctx.off = 0; + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "get_auditor_progress", + params, + &auditor_progress_cb, + &ctx); + GNUNET_PQ_cleanup_query_params_closures (params); + if (ctx.failure) + return GNUNET_DB_STATUS_HARD_ERROR; + if (qs < 0) + return qs; + GNUNET_assert (ctx.off == cnt); + return qs; + } +} diff --git a/src/auditordb/get_bad_sig_losses.c b/src/auditordb/get_bad_sig_losses.c @@ -0,0 +1,181 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_bad_sig_losses.h" + + +struct BadSigLossesContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_BadSigLossesCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_bad_sig_losses(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct BadSigLossesContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +bad_sig_losses_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct BadSigLossesContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_BadSigLosses dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_uint64 ("problem_row_id", + &dc.problem_row_id), + GNUNET_PQ_result_spec_string ("operation", + &dc.operation), + TALER_PQ_RESULT_SPEC_AMOUNT ("loss", + &dc.loss), + GNUNET_PQ_result_spec_auto_from_type ("operation_specific_pub", + &dc.operation_specific_pub), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_bad_sig_losses (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + const struct GNUNET_CRYPTO_EddsaPublicKey *op_spec_pub, + const char *op, + TALER_AUDITORDB_BadSigLossesCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + NULL == op_spec_pub + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (op_spec_pub), + NULL == op + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (op), + GNUNET_PQ_query_param_end + }; + struct BadSigLossesContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_bad_sig_losses_get_desc", + "SELECT" + " row_id" + ",problem_row_id" + ",operation" + ",loss" + ",operation_specific_pub" + ",suppressed" + " FROM auditor_bad_sig_losses" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " AND ($4::BYTEA IS NULL OR operation_specific_pub = $4)" + " AND ($5::TEXT IS NULL OR operation = $5)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_bad_sig_losses_get_asc", + "SELECT" + " row_id" + ",problem_row_id" + ",operation" + ",loss" + ",operation_specific_pub" + ",suppressed" + " FROM auditor_bad_sig_losses" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " AND ($4::BYTEA IS NULL OR operation_specific_pub = $4)" + " AND ($5::TEXT IS NULL OR operation = $5)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_bad_sig_losses_get_asc" + : "auditor_bad_sig_losses_get_desc", + params, + &bad_sig_losses_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_balance.c b/src/auditordb/get_balance.c @@ -0,0 +1,192 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/get_balance.c + * @brief Implementation of the get_balance function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_balance.h" +#include "pg_helper.h" + + +/** + * Closure for #balance_cb(). + */ +struct BalanceContext +{ + + /** + * Where to store results. + */ + struct TALER_Amount **dst; + + /** + * Offset in @e dst. + */ + unsigned int off; + + /** + * Length of array at @e dst. + */ + unsigned int len; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Set to true on failure. + */ + bool failure; + +}; + + +/** + * Helper function for #AUDITORDB_get_balance(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct BalanceContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +balance_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct BalanceContext *ctx = cls; + struct AUDITORDB_PostgresContext *ctx = ctx->ctx; + + GNUNET_assert (num_results <= ctx->len); + for (unsigned int i = 0; i < num_results; i++) + { + bool is_missing; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_amount ("balance", + ctx->currency, + ctx->dst[i]), + &is_missing), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->failure = true; + return; + } + if (is_missing) + { + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + ctx->dst[i])); + } + ctx->off++; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_balance (struct AUDITORDB_PostgresContext *ctx, + const char *balance_key, + struct TALER_Amount *balance_value, + ...) +{ + unsigned int cnt = 1; + va_list ap; + + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + balance_value)); + va_start (ap, + balance_value); + while (NULL != va_arg (ap, + const char *)) + { + struct TALER_Amount *dst; + + cnt++; + dst = va_arg (ap, + struct TALER_Amount *); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + dst)); + } + va_end (ap); + { + const char *keys[cnt]; + struct TALER_Amount *dsts[cnt]; + unsigned int off = 1; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_array_ptrs_string (cnt, + keys, + ctx->conn), + GNUNET_PQ_query_param_end + }; + struct BalanceContext ctx = { + .dst = dsts, + .len = cnt, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + keys[0] = balance_key; + dsts[0] = balance_value; + va_start (ap, + balance_value); + while (off < cnt) + { + keys[off] = va_arg (ap, + const char *); + dsts[off] = va_arg (ap, + struct TALER_Amount *); + off++; + } + GNUNET_assert (NULL == va_arg (ap, + const char *)); + va_end (ap); + + PREPARE (ctx, + "get_balance", + "SELECT " + " auditor_do_get_balance AS balance" + " FROM auditor_do_get_balance " + "($1);"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "get_balance", + params, + &balance_cb, + &ctx); + GNUNET_PQ_cleanup_query_params_closures (params); + if (ctx.failure) + return GNUNET_DB_STATUS_HARD_ERROR; + if (qs < 0) + return qs; + GNUNET_assert (qs == ctx.off); + return qs; + } +} diff --git a/src/auditordb/get_balances.c b/src/auditordb/get_balances.c @@ -0,0 +1,134 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_balances.h" + + +struct BalancesContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_BalancesCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_balances(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct BalancesContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +balances_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct BalancesContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_Balances dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("balance_key", + &dc.balance_key), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance_value", + &dc.balance_value), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_balances (struct AUDITORDB_PostgresContext *ctx, + const char *balance_key, + TALER_AUDITORDB_BalancesCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + NULL == balance_key + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (balance_key), + GNUNET_PQ_query_param_end + }; + struct BalancesContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_balances_get", + "SELECT" + " balance_key" + ",balance_value" + " FROM auditor_balances" + " WHERE ($1::TEXT IS NULL OR balance_key = $1)" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "auditor_balances_get", + params, + &balances_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_coin_inconsistency.c b/src/auditordb/get_coin_inconsistency.c @@ -0,0 +1,184 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_coin_inconsistency.h" + +/** + * Closure for #deposit_confirmation_cb(). + */ +struct CoinInconsistencyContext +{ + + /** + * Function to call for each deposit confirmation. + */ + TALER_AUDITORDB_CoinInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_deposit_confirmations(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct DepositConfirmationContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +coin_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t serial_id; + + struct TALER_AUDITORDB_CoinInconsistency dc; + + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &serial_id), + GNUNET_PQ_result_spec_string ("operation", + &dc.operation), + TALER_PQ_RESULT_SPEC_AMOUNT ("exchange_amount", + &dc.exchange_amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("auditor_amount", + &dc.auditor_amount), + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", &dc.coin_pub), + GNUNET_PQ_result_spec_bool ("profitable", + &dc.profitable), + + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + + dcc->qs = i + 1; + + + rval = dcc->cb (dcc->cb_cls, + serial_id, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_coin_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, // maybe not needed + TALER_AUDITORDB_CoinInconsistencyCallback cb, + void *cb_cls) +{ + + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct CoinInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + + PREPARE (ctx, + "auditor_coin_inconsistency_select_desc", + "SELECT" + " row_id" + ",operation" + ",exchange_amount" + ",auditor_amount" + ",coin_pub" + ",profitable" + " FROM auditor_coin_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_coin_inconsistency_select_asc", + "SELECT" + " row_id" + ",operation" + ",exchange_amount" + ",auditor_amount" + ",coin_pub" + ",profitable" + " FROM auditor_coin_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + (limit > 0) ? + "auditor_coin_inconsistency_select_asc" + : + "auditor_coin_inconsistency_select_desc", + params, + &coin_inconsistency_cb, + &dcc); + + + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} +\ No newline at end of file diff --git a/src/auditordb/get_denomination_balance.c b/src/auditordb/get_denomination_balance.c @@ -0,0 +1,66 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_denomination_balance.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_denomination_balance.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_denomination_balance (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + struct TALER_AUDITORDB_DenominationCirculationData *dcd) +{ + 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[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("denom_balance", + &dcd->denom_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("denom_loss", + &dcd->denom_loss), + TALER_PQ_RESULT_SPEC_AMOUNT ("denom_risk", + &dcd->denom_risk), + TALER_PQ_RESULT_SPEC_AMOUNT ("recoup_loss", + &dcd->recoup_loss), + GNUNET_PQ_result_spec_uint64 ("num_issued", + &dcd->num_issued), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "auditor_denomination_pending_select", + "SELECT" + " denom_balance" + ",denom_loss" + ",num_issued" + ",denom_risk" + ",recoup_loss" + " FROM auditor_denomination_pending" + " WHERE denom_pub_hash=$1"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "auditor_denomination_pending_select", + params, + rs); +} diff --git a/src/auditordb/get_denomination_key_validity_withdraw_inconsistency.c b/src/auditordb/get_denomination_key_validity_withdraw_inconsistency.c @@ -0,0 +1,171 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_denomination_key_validity_withdraw_inconsistency.h" + + +/** + * Closure for #denomination_key_validity_withdraw_inconsistency_cb(). + */ +struct DenominationKeyValidityWithdrawInconsistencyContext +{ + + /** + * Function to call for each denomination key validity... + */ + TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_deposit_confirmations(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct DepositConfirmationContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +denomination_key_validity_withdraw_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct DenominationKeyValidityWithdrawInconsistencyContext *dcc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_uint64 ("problem_row_id", + &dc.problem_row_id), + GNUNET_PQ_result_spec_absolute_time ("execution_date", + &dc.execution_date), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc.reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ("denompub_h", + &dc.denompub_h), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_denomination_key_validity_withdraw_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct DenominationKeyValidityWithdrawInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_denomination_key_validity_withdraw_inconsistency_get_desc", + "SELECT" + " row_id" + ",problem_row_id" + ",execution_date" + ",reserve_pub" + ",denompub_h" + ",suppressed" + " FROM auditor_denomination_key_validity_withdraw_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_denomination_key_validity_withdraw_inconsistency_get_asc", + "SELECT" + " row_id" + ",problem_row_id" + ",execution_date" + ",reserve_pub" + ",denompub_h" + ",suppressed" + " FROM auditor_denomination_key_validity_withdraw_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_denomination_key_validity_withdraw_inconsistency_get_asc" + : "auditor_denomination_key_validity_withdraw_inconsistency_get_desc", + params, + &denomination_key_validity_withdraw_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_denomination_pending.c b/src/auditordb/get_denomination_pending.c @@ -0,0 +1,171 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_denomination_pending.h" + + +struct DenominationPendingContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_DenominationPendingCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_denomination_pending(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct DenominationPendingContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +denomination_pending_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct DenominationPendingContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t serial_id; + struct TALER_AUDITORDB_DenominationPending dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &serial_id), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &dc.denom_pub_hash), + TALER_PQ_RESULT_SPEC_AMOUNT ("denom_balance", + &dc.denom_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("denom_loss", + &dc.denom_loss), + GNUNET_PQ_result_spec_uint64 ("num_issued", + &dc.num_issued), + TALER_PQ_RESULT_SPEC_AMOUNT ("denom_risk", + &dc.denom_risk), + TALER_PQ_RESULT_SPEC_AMOUNT ("recoup_loss", + &dc.recoup_loss), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + serial_id, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_denomination_pending (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_DenominationPendingCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct DenominationPendingContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_denomination_pending_get_desc", + "SELECT" + " row_id," + " denom_pub_hash," + " denom_balance," + " denom_loss," + " num_issued," + " denom_risk," + " recoup_loss" + " FROM auditor_denomination_pending" + " WHERE (row_id < $1)" + " ORDER BY row_id DESC" + " LIMIT $2" + ); + PREPARE (ctx, + "auditor_denomination_pending_get_asc", + "SELECT" + " row_id," + " denom_pub_hash," + " denom_balance," + " denom_loss," + " num_issued," + " denom_risk," + " recoup_loss" + " FROM auditor_denomination_pending" + " WHERE (row_id > $1)" + " ORDER BY row_id ASC" + " LIMIT $2" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_denomination_pending_get_asc" + : "auditor_denomination_pending_get_desc", + params, + &denomination_pending_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_denominations_without_sigs.c b/src/auditordb/get_denominations_without_sigs.c @@ -0,0 +1,171 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_denominations_without_sigs.h" + + +struct DenominationsWithoutSigsContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_DenominationsWithoutSigsCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_denominations_without_sigs(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct DenominationsWithoutSigsContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +denominations_without_sigs_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct DenominationsWithoutSigsContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_DenominationsWithoutSigs dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_auto_from_type ("denompub_h", + &dc.denompub_h), + TALER_PQ_RESULT_SPEC_AMOUNT ("value", + &dc.value), + GNUNET_PQ_result_spec_absolute_time ("start_time", + &dc.start_time), + GNUNET_PQ_result_spec_absolute_time ("end_time", + &dc.end_time), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + + dcc->qs = i + 1; + + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_denominations_without_sigs (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_DenominationsWithoutSigsCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct DenominationsWithoutSigsContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_denominations_without_sigs_get_desc", + "SELECT" + " row_id," + " denompub_h," + " value," + " start_time," + " end_time," + " suppressed" + " FROM auditor_denominations_without_sigs" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_denominations_without_sigs_get_asc", + "SELECT" + " row_id," + " denompub_h," + " value," + " start_time," + " end_time," + " suppressed" + " FROM auditor_denominations_without_sigs" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_denominations_without_sigs_get_asc" + : "auditor_denominations_without_sigs_get_desc", + params, + &denominations_without_sigs_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_deposit_confirmations.c b/src/auditordb/get_deposit_confirmations.c @@ -0,0 +1,232 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * @file pg_get_deposit_confirmations.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_deposit_confirmations.h" +#include "pg_helper.h" + + +/** + * Closure for #deposit_confirmation_cb(). + */ +struct DepositConfirmationContext +{ + + /** + * Function to call for each deposit confirmation. + */ + TALER_AUDITORDB_DepositConfirmationCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_deposit_confirmations(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct DepositConfirmationContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +deposit_confirmation_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct DepositConfirmationContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_DepositConfirmation dc = { 0 }; + struct TALER_CoinSpendPublicKeyP *coin_pubs = NULL; + struct TALER_CoinSpendSignatureP *coin_sigs = NULL; + size_t num_pubs = 0; + size_t num_sigs = 0; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &dc.h_contract_terms), + GNUNET_PQ_result_spec_auto_from_type ("h_policy", + &dc.h_policy), + GNUNET_PQ_result_spec_auto_from_type ("h_wire", + &dc.h_wire), + GNUNET_PQ_result_spec_timestamp ("exchange_timestamp", + &dc.exchange_timestamp), + GNUNET_PQ_result_spec_timestamp ("refund_deadline", + &dc.refund_deadline), + GNUNET_PQ_result_spec_timestamp ("wire_deadline", + &dc.wire_deadline), + TALER_PQ_RESULT_SPEC_AMOUNT ("total_without_fee", + &dc.total_without_fee), + GNUNET_PQ_result_spec_auto_array_from_type (ctx->conn, + "coin_pubs", + &num_pubs, + coin_pubs), + GNUNET_PQ_result_spec_auto_array_from_type (ctx->conn, + "coin_sigs", + &num_sigs, + coin_sigs), + GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", + &dc.merchant), + GNUNET_PQ_result_spec_auto_from_type ("exchange_sig", + &dc.exchange_sig), + GNUNET_PQ_result_spec_auto_from_type ("exchange_pub", + &dc.exchange_pub), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &dc.master_sig), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + if (num_sigs != num_pubs) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + GNUNET_PQ_cleanup_result (rs); + return; + } + dcc->qs = i + 1; + dc.coin_pubs = coin_pubs; + dc.coin_sigs = coin_sigs; + dc.num_coins = num_sigs; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_deposit_confirmations (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_DepositConfirmationCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct DepositConfirmationContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_deposit_confirmation_select_desc", + "SELECT" + " row_id" + ",h_contract_terms" + ",h_policy" + ",h_wire" + ",exchange_timestamp" + ",wire_deadline" + ",refund_deadline" + ",total_without_fee" + ",coin_pubs" + ",coin_sigs" + ",merchant_pub" + ",exchange_sig" + ",exchange_pub" + ",master_sig" + ",suppressed" + " FROM auditor_deposit_confirmations" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_deposit_confirmation_select_asc", + "SELECT" + " row_id" + ",h_contract_terms" + ",h_policy" + ",h_wire" + ",exchange_timestamp" + ",wire_deadline" + ",refund_deadline" + ",total_without_fee" + ",coin_pubs" + ",coin_sigs" + ",merchant_pub" + ",exchange_sig" + ",exchange_pub" + ",master_sig" + ",suppressed" + " FROM auditor_deposit_confirmations" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_deposit_confirmation_select_asc" + : "auditor_deposit_confirmation_select_desc", + params, + &deposit_confirmation_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_emergency.c b/src/auditordb/get_emergency.c @@ -0,0 +1,180 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_emergency.h" + +/** + * Closure for #emergency_cb(). + */ +struct EmergencyContext +{ + + /** + * Function to call for each deposit confirmation. + */ + TALER_AUDITORDB_EmergencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_emergency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct Emergency *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +emergency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct EmergencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_Emergency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_auto_from_type ("denompub_h", + &dc.denompub_h), + TALER_PQ_RESULT_SPEC_AMOUNT ("denom_risk", + &dc.denom_risk), + TALER_PQ_RESULT_SPEC_AMOUNT ("denom_loss", + &dc.denom_loss), + GNUNET_PQ_result_spec_absolute_time ("deposit_start", + &dc.deposit_start), + GNUNET_PQ_result_spec_absolute_time ("deposit_end", + &dc.deposit_end), + TALER_PQ_RESULT_SPEC_AMOUNT ("value", + &dc.value), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_emergency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_EmergencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct EmergencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_emergency_get_desc", + "SELECT" + " row_id" + ",denompub_h" + ",denom_risk" + ",denom_loss" + ",deposit_start" + ",deposit_end" + ",value" + ",suppressed" + " FROM auditor_emergency" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_emergency_get_asc", + "SELECT" + " row_id" + ",denompub_h" + ",denom_risk" + ",denom_loss" + ",deposit_start" + ",deposit_end" + ",value" + ",suppressed" + " FROM auditor_emergency" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_emergency_get_asc" + : "auditor_emergency_get_desc", + params, + &emergency_cb, + &dcc); + + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_emergency_by_count.c b/src/auditordb/get_emergency_by_count.c @@ -0,0 +1,184 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_emergency_by_count.h" + + +/** + * Closure for #emergency_cb(). + */ +struct EmergencyByCountContext +{ + + /** + * Function to call for each deposit confirmation. + */ + TALER_AUDITORDB_EmergenciesByCountCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_emergency_by_count(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct Emergency *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +emergency_by_count_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct EmergencyByCountContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_EmergenciesByCount dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_auto_from_type ("denompub_h", + &dc.denompub_h), + GNUNET_PQ_result_spec_uint64 ("num_issued", + &dc.num_issued), + GNUNET_PQ_result_spec_uint64 ("num_known", + &dc.num_known), + TALER_PQ_RESULT_SPEC_AMOUNT ("risk", + &dc.risk), + GNUNET_PQ_result_spec_absolute_time ("start", + &dc.start), + GNUNET_PQ_result_spec_absolute_time ("deposit_end", + &dc.deposit_end), + TALER_PQ_RESULT_SPEC_AMOUNT ("value", + &dc.value), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_emergency_by_count (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_EmergenciesByCountCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct EmergencyByCountContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_emergency_by_count_get_desc", + "SELECT" + " row_id" + ",denompub_h" + ",num_issued" + ",num_known" + ",risk" + ",start" + ",deposit_end" + ",value" + ",suppressed" + " FROM auditor_emergency_by_count" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_emergency_by_count_get_asc", + "SELECT" + " row_id" + ",denompub_h" + ",num_issued" + ",num_known" + ",risk" + ",start" + ",deposit_end" + ",value" + ",suppressed" + " FROM auditor_emergency_by_count" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_emergency_by_count_get_asc" + : "auditor_emergency_by_count_get_desc", + params, + &emergency_by_count_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_exchange_signkeys.c b/src/auditordb/get_exchange_signkeys.c @@ -0,0 +1,184 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" + +#include "get_exchange_signkeys.h" + + +struct ExchangeSignkeysContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_ExchangeSignkeysCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_exchange_signkeys(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct ExchangeSignkeysContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +exchange_signkeys_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ExchangeSignkeysContext *dcc = cls; + // struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t serial_id; + + struct TALER_AUDITORDB_ExchangeSignkeys dc; + + struct GNUNET_PQ_ResultSpec rs[] = { + + GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), + + GNUNET_PQ_result_spec_auto_from_type ("exchange_pub", &dc.exchange_pub), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", &dc.master_sig), + GNUNET_PQ_result_spec_absolute_time ("ep_valid_from", &dc.ep_valid_from), + GNUNET_PQ_result_spec_absolute_time ("ep_expire_sign", + &dc.ep_expire_sign), + GNUNET_PQ_result_spec_absolute_time ("ep_expire_legal", + &dc.ep_expire_legal), + GNUNET_PQ_result_spec_bool ("suppressed", &dc.suppressed), + + + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + + dcc->qs = i + 1; + + rval = dcc->cb (dcc->cb_cls, + serial_id, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_exchange_signkeys (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, // maybe not needed + TALER_AUDITORDB_ExchangeSignkeysCallback cb, + void *cb_cls) +{ + + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct ExchangeSignkeysContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_exchange_signkeys_get_desc", + "SELECT" + " row_id," + " exchange_pub," + " master_sig," + " ep_valid_from," + " ep_expire_sign," + " ep_expire_legal," + " suppressed" + " FROM auditor_exchange_signkeys" + " WHERE (row_id < $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_exchange_signkeys_get_asc", + "SELECT" + " row_id," + " exchange_pub," + " master_sig," + " ep_valid_from," + " ep_expire_sign," + " ep_expire_legal," + " suppressed" + " FROM auditor_exchange_signkeys" + " WHERE (row_id > $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + (limit > 0) + ? + "auditor_exchange_signkeys_get_asc" + : + "auditor_exchange_signkeys_get_desc", + params, + &exchange_signkeys_cb, + &dcc); + + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_fee_time_inconsistency.c b/src/auditordb/get_fee_time_inconsistency.c @@ -0,0 +1,166 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_fee_time_inconsistency.h" + + +/** + * Closure for #feetimeinconsistency_cb(). + */ +struct FeeTimeInconsistencyContext +{ + + /** + * Function to call for each fee time inconsistency + */ + TALER_AUDITORDB_FeeTimeInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_emergency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct Emergency *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +fee_time_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct FeeTimeInconsistencyContext *dcc = cls; + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_FeeTimeInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_uint64 ("problem_row_id", + &dc.problem_row_id), + GNUNET_PQ_result_spec_string ("fee_type", + &dc.type), + GNUNET_PQ_result_spec_absolute_time ("fee_time", + &dc.time), + GNUNET_PQ_result_spec_string ("diagnostic", + &dc.diagnostic), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_fee_time_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_FeeTimeInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct FeeTimeInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_fee_time_inconsistency_get_desc", + "SELECT" + " row_id" + ",problem_row_id" + ",fee_type" + ",fee_time" + ",diagnostic" + " FROM auditor_fee_time_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_fee_time_inconsistency_get_asc", + "SELECT" + " row_id" + ",problem_row_id" + ",fee_type" + ",fee_time" + ",diagnostic" + " FROM auditor_fee_time_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_fee_time_inconsistency_get_asc" + : "auditor_fee_time_inconsistency_get_desc", + params, + &fee_time_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_misattribution_in_inconsistency.c b/src/auditordb/get_misattribution_in_inconsistency.c @@ -0,0 +1,168 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" + +#include "get_misattribution_in_inconsistency.h" + + +struct MisattributionInInconsistencyContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_MisattributionInInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_misattribution_in_inconsistency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct MisattributionInInconsistencyContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +misattribution_in_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct MisattributionInInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_MisattributionInInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &dc.amount), + GNUNET_PQ_result_spec_uint64 ("bank_row", + &dc.bank_row), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc.reserve_pub), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_misattribution_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_MisattributionInInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct MisattributionInInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_misattribution_in_inconsistency_get_desc", + "SELECT" + " row_id" + ",amount" + ",bank_row" + ",reserve_pub" + ",suppressed" + " FROM auditor_misattribution_in_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_misattribution_in_inconsistency_get_asc", + "SELECT" + " row_id" + ",amount" + ",bank_row" + ",reserve_pub" + ",suppressed" + " FROM auditor_misattribution_in_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_misattribution_in_inconsistency_get_asc" + : "auditor_misattribution_in_inconsistency_get_desc", + params, + &misattribution_in_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_progress_points.c b/src/auditordb/get_progress_points.c @@ -0,0 +1,138 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/get_progress_points.c + * @brief Implementation of the get_progress_points function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_progress_points.h" +#include "pg_helper.h" + + +struct ProgressContext +{ + + /** + * Function to call for each progress point. + */ + TALER_AUDITORDB_ProgressPointsCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_progress_points(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct ProgressContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +progress_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ProgressContext *dcc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_Progress dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("progress_key", + &dc.progress_key), + GNUNET_PQ_result_spec_uint64 ("progress_offset", + &dc.progress_offset), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_progress_points (struct AUDITORDB_PostgresContext *ctx, + const char *progress_key, + TALER_AUDITORDB_ProgressPointsCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + NULL == progress_key + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (progress_key), + GNUNET_PQ_query_param_end + }; + struct ProgressContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_progress_points_get", + "SELECT" + " progress_key" + ",progress_offset" + " FROM auditor_progress" + " WHERE ($1::TEXT IS NULL OR progress_key = $1)" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "auditor_progress_points_get", + params, + &progress_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_purse_info.c b/src/auditordb/get_purse_info.c @@ -0,0 +1,61 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/get_purse_info.c + * @brief Implementation of the get_purse_info function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_purse_info.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_purse_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + uint64_t *rowid, + struct TALER_Amount *balance, + struct GNUNET_TIME_Timestamp *expiration_date) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + balance), + GNUNET_PQ_result_spec_timestamp ("expiration_date", + expiration_date), + GNUNET_PQ_result_spec_uint64 ("auditor_purses_rowid", + rowid), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "auditor_get_purse_info", + "SELECT" + " auditor_purses_rowid" + ",expiration_date" + ",balance" + " FROM auditor_purses" + " WHERE purse_pub=$1"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "auditor_get_purse_info", + params, + rs); +} diff --git a/src/auditordb/get_purse_not_closed_inconsistencies.c b/src/auditordb/get_purse_not_closed_inconsistencies.c @@ -0,0 +1,168 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_purse_not_closed_inconsistencies.h" + + +/** + * Closure for #purse_not_closed_inconsistencies_cb(). + */ +struct PurseNotClosedInconsistenciesContext +{ + + /** + * Function to call for each purse not closed_inconsistencies. + */ + TALER_AUDITORDB_PurseNotClosedInconsistenciesCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_purse_not_closed_inconsistencies(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct PurseNotClosedInconsistencies *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +purse_not_closed_inconsistencies_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PurseNotClosedInconsistenciesContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_PurseNotClosedInconsistencies dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &dc.purse_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &dc.amount), + GNUNET_PQ_result_spec_absolute_time ("expiration_date", + &dc.expiration_date), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_purse_not_closed_inconsistencies (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_PurseNotClosedInconsistenciesCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct PurseNotClosedInconsistenciesContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_purse_not_closed_inconsistencies_get_desc", + "SELECT" + " row_id" + ",purse_pub" + ",amount" + ",expiration_date" + ",suppressed" + " FROM auditor_purse_not_closed_inconsistencies" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_purse_not_closed_inconsistencies_get_asc", + "SELECT" + " row_id" + ",purse_pub" + ",amount" + ",expiration_date" + ",suppressed" + " FROM auditor_purse_not_closed_inconsistencies" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_purse_not_closed_inconsistencies_get_asc" + : "auditor_purse_not_closed_inconsistencies_get_desc", + params, + &purse_not_closed_inconsistencies_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_purses.c b/src/auditordb/get_purses.c @@ -0,0 +1,163 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_purses.h" + + +struct PursesContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_PursesCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_purses(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct PursesContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +purses_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PursesContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_Purses dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("auditor_purses_rowid", + &dc.auditor_purses_rowid), + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &dc.purse_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + &dc.balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("target", + &dc.target), + GNUNET_PQ_result_spec_absolute_time ("expiration_date", + &dc.expiration_date), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + dc.auditor_purses_rowid, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_purses (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_PursesCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct PursesContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_purses_get_desc", + "SELECT" + " auditor_purses_rowid," + " purse_pub," + " balance," + " target," + " expiration_date" + " FROM auditor_purses" + " WHERE (auditor_purses_rowid < $1)" + " ORDER BY auditor_purses_rowid DESC" + " LIMIT $2" + ); + PREPARE (ctx, + "auditor_purses_get_asc", + "SELECT" + " auditor_purses_rowid," + " purse_pub," + " balance," + " target," + " expiration_date" + " FROM auditor_purses" + " WHERE (auditor_purses_rowid > $1)" + " ORDER BY auditor_purses_rowid ASC" + " LIMIT $2" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_purses_get_asc" + : "auditor_purses_get_desc", + params, + &purses_cb, + &dcc); + + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_reserve_balance_insufficient_inconsistency.c b/src/auditordb/get_reserve_balance_insufficient_inconsistency.c @@ -0,0 +1,168 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_reserve_balance_insufficient_inconsistency.h" + + +/** + * Closure for #reserve_balance_insufficient_inconsistency_cb(). + */ +struct ReserveBalanceInsufficientInconsistencyContext +{ + + /** + * Function to call for each ReserveBalanceInsufficientInconsistency. + */ + TALER_AUDITORDB_ReserveBalanceInsufficientInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_reserve_balance_insufficient_inconsistency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct ReserveBalanceInsufficientInconsistency *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserve_balance_insufficient_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveBalanceInsufficientInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc.reserve_pub), + GNUNET_PQ_result_spec_bool ("inconsistency_gain", + &dc.inconsistency_gain), + TALER_PQ_RESULT_SPEC_AMOUNT ("inconsistency_amount", + &dc.inconsistency_amount), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_balance_insufficient_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ReserveBalanceInsufficientInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct ReserveBalanceInsufficientInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_reserve_balance_insufficient_inconsistency_get_desc", + "SELECT" + " row_id" + ",reserve_pub" + ",inconsistency_gain" + ",inconsistency_amount" + ",suppressed" + " FROM auditor_reserve_balance_insufficient_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_reserve_balance_insufficient_inconsistency_get_asc", + "SELECT" + " row_id" + ",reserve_pub" + ",inconsistency_gain" + ",inconsistency_amount" + ",suppressed" + " FROM auditor_reserve_balance_insufficient_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_reserve_balance_insufficient_inconsistency_get_asc" + : "auditor_reserve_balance_insufficient_inconsistency_get_desc", + params, + &reserve_balance_insufficient_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_reserve_balance_summary_wrong_inconsistency.c b/src/auditordb/get_reserve_balance_summary_wrong_inconsistency.c @@ -0,0 +1,166 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_reserve_balance_summary_wrong_inconsistency.h" + + +struct ReserveBalanceSummaryWrongInconsistencyContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_reserve_balance_summary_wrong_inconsistency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct ReserveBalanceSummaryWrongInconsistencyContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserve_balance_summary_wrong_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveBalanceSummaryWrongInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc.reserve_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("exchange_amount", + &dc.exchange_amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("auditor_amount", + &dc.auditor_amount), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_balance_summary_wrong_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct ReserveBalanceSummaryWrongInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_reserve_balance_summary_wrong_inconsistency_get_desc", + "SELECT" + " row_id" + ",reserve_pub" + ",exchange_amount" + ",auditor_amount" + ",suppressed" + " FROM auditor_reserve_balance_summary_wrong_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_reserve_balance_summary_wrong_inconsistency_get_asc", + "SELECT" + " row_id" + ",reserve_pub" + ",exchange_amount" + ",auditor_amount" + ",suppressed" + " FROM auditor_reserve_balance_summary_wrong_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_reserve_balance_summary_wrong_inconsistency_get_asc" + : "auditor_reserve_balance_summary_wrong_inconsistency_get_desc", + params, + &reserve_balance_summary_wrong_inconsistency_cb, + &dcc); + + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_reserve_in_inconsistency.c b/src/auditordb/get_reserve_in_inconsistency.c @@ -0,0 +1,182 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_reserve_in_inconsistency.h" + + +struct ReserveInInconsistencyContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_ReserveInInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_reserve_in_inconsistency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct ReserveInInconsistencyContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserve_in_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveInInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_ReserveInInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.serial_id), + GNUNET_PQ_result_spec_uint64 ("bank_row_id", + &dc.bank_row_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_exchange_expected", + &dc.amount_exchange_expected), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_wired", + &dc.amount_wired), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc.reserve_pub), + GNUNET_PQ_result_spec_absolute_time ("timestamp", + &dc.timestamp), + GNUNET_PQ_result_spec_string ("account", + &dc.account.full_payto), + GNUNET_PQ_result_spec_string ("diagnostic", + &dc.diagnostic), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ReserveInInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct ReserveInInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_reserve_in_inconsistency_get_desc", + "SELECT" + " row_id" + ",bank_row_id" + ",amount_exchange_expected" + ",amount_wired" + ",reserve_pub" + ",timestamp" + ",account" + ",diagnostic" + ",suppressed" + " FROM auditor_reserve_in_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_reserve_in_inconsistency_get_asc", + "SELECT" + " row_id" + ",bank_row_id" + ",amount_exchange_expected" + ",amount_wired" + ",reserve_pub" + ",timestamp" + ",account" + ",diagnostic" + ",suppressed" + " FROM auditor_reserve_in_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_reserve_in_inconsistency_get_asc" + : "auditor_reserve_in_inconsistency_get_desc", + params, + &reserve_in_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_reserve_info.c b/src/auditordb/get_reserve_info.c @@ -0,0 +1,87 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_reserve_info.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_reserve_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t *rowid, + struct TALER_AUDITORDB_ReserveFeeBalance *rfb, + struct GNUNET_TIME_Timestamp *expiration_date, + struct TALER_FullPayto *sender_account) +{ + 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 ("reserve_balance", + &rfb->reserve_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_loss", + &rfb->reserve_loss), + TALER_PQ_RESULT_SPEC_AMOUNT ("withdraw_fee_balance", + &rfb->withdraw_fee_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("close_fee_balance", + &rfb->close_fee_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee_balance", + &rfb->purse_fee_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("open_fee_balance", + &rfb->open_fee_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee_balance", + &rfb->history_fee_balance), + GNUNET_PQ_result_spec_timestamp ("expiration_date", + expiration_date), + GNUNET_PQ_result_spec_uint64 ("auditor_reserves_rowid", + rowid), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("origin_account", + &sender_account->full_payto), + NULL), + GNUNET_PQ_result_spec_end + }; + + sender_account->full_payto = NULL; + PREPARE (ctx, + "auditor_get_reserve_info", + "SELECT" + " reserve_balance" + ",reserve_loss" + ",withdraw_fee_balance" + ",close_fee_balance" + ",purse_fee_balance" + ",open_fee_balance" + ",history_fee_balance" + ",expiration_date" + ",auditor_reserves_rowid" + ",origin_account" + " FROM auditor_reserves" + " WHERE reserve_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "auditor_get_reserve_info", + params, + rs); +} diff --git a/src/auditordb/get_reserve_not_closed_inconsistency.c b/src/auditordb/get_reserve_not_closed_inconsistency.c @@ -0,0 +1,169 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_reserve_not_closed_inconsistency.h" + + +struct ReserveNotClosedInconsistencyContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_ReserveNotClosedInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_reserve_not_closed_inconsistency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct ReserveNotClosedInconsistencyContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserve_not_closed_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveNotClosedInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_ReserveNotClosedInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc.reserve_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + &dc.balance), + GNUNET_PQ_result_spec_absolute_time ("expiration_time", + &dc.expiration_time), + GNUNET_PQ_result_spec_string ("diagnostic", + &dc.diagnostic), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_not_closed_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ReserveNotClosedInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct ReserveNotClosedInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_reserve_not_closed_inconsistency_get_desc", + "SELECT" + " row_id" + ",reserve_pub" + ",balance" + ",expiration_time" + ",diagnostic" + ",suppressed" + " FROM auditor_reserve_not_closed_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_reserve_not_closed_inconsistency_get_asc", + "SELECT" + " row_id" + ",reserve_pub" + ",balance" + ",expiration_time" + ",diagnostic" + ",suppressed" + " FROM auditor_reserve_not_closed_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_reserve_not_closed_inconsistency_get_asc" + : "auditor_reserve_not_closed_inconsistency_get_desc", + params, + &reserve_not_closed_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_reserves.c b/src/auditordb/get_reserves.c @@ -0,0 +1,186 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_reserves.h" + + +struct ReservesContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_ReservesCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_reserves(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct ReservesContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserves_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReservesContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_Reserves dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("auditor_reserves_rowid", + &dc.auditor_reserves_rowid), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc.reserve_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_balance", + &dc.reserve_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_loss", + &dc.reserve_loss), + TALER_PQ_RESULT_SPEC_AMOUNT ("withdraw_fee_balance", + &dc.withdraw_fee_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("close_fee_balance", + &dc.close_fee_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee_balance", + &dc.purse_fee_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("open_fee_balance", + &dc.open_fee_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee_balance", + &dc.history_fee_balance), + GNUNET_PQ_result_spec_absolute_time ("expiration_date", + &dc.expiration_date), + GNUNET_PQ_result_spec_string ("origin_account", + &dc.origin_account.full_payto), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + dc.auditor_reserves_rowid, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserves (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_ReservesCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct ReservesContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_reserves_get_desc", + "SELECT" + " auditor_reserves_rowid," + " reserve_pub," + " reserve_balance," + " reserve_loss," + " withdraw_fee_balance," + " close_fee_balance," + " purse_fee_balance," + " open_fee_balance," + " history_fee_balance," + " expiration_date," + " origin_account" + " FROM auditor_reserves" + " WHERE (auditor_reserves_rowid < $1)" + " ORDER BY auditor_reserves_rowid DESC" + " LIMIT $2" + ); + PREPARE (ctx, + "auditor_reserves_get_asc", + "SELECT" + " auditor_reserves_rowid," + " reserve_pub," + " reserve_balance," + " reserve_loss," + " withdraw_fee_balance," + " close_fee_balance," + " purse_fee_balance," + " open_fee_balance," + " history_fee_balance," + " expiration_date," + " origin_account" + " FROM auditor_reserves" + " WHERE (auditor_reserves_rowid > $1)" + " ORDER BY auditor_reserves_rowid ASC" + " LIMIT $2" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_reserves_get_asc" + : "auditor_reserves_get_desc", + params, + &reserves_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_row_inconsistency.c b/src/auditordb/get_row_inconsistency.c @@ -0,0 +1,173 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_row_inconsistency.h" + +/** + * Closure for #deposit_confirmation_cb(). + */ +struct RowInconsistencyContext +{ + + /** + * Function to call for each deposit confirmation. + */ + TALER_AUDITORDB_RowInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_deposit_confirmations(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct DepositConfirmationContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +row_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct RowInconsistencyContext *dcc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t serial_id; + + struct TALER_AUDITORDB_RowInconsistency dc; + + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", &serial_id), + + GNUNET_PQ_result_spec_string ("row_table", &dc.row_table), + GNUNET_PQ_result_spec_string ("diagnostic", &dc.diagnostic), + GNUNET_PQ_result_spec_bool ("suppressed", &dc.suppressed), + + + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + + dcc->qs = i + 1; + + + rval = dcc->cb (dcc->cb_cls, + serial_id, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_row_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, // maybe not needed + TALER_AUDITORDB_RowInconsistencyCallback cb, + void *cb_cls) +{ + + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct RowInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + + PREPARE (ctx, + "auditor_row_inconsistency_select_desc", + "SELECT" + " row_id" + ",row_table" + ",diagnostic" + ",suppressed" + " FROM auditor_row_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_row_inconsistency_select_asc", + "SELECT" + " row_id" + ",row_table" + ",diagnostic" + ",suppressed" + " FROM auditor_row_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR suppressed is false)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + (limit > 0) ? + "auditor_row_inconsistency_select_asc" + : + "auditor_row_inconsistency_select_desc", + params, + &row_inconsistency_cb, + &dcc); + + + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} +\ No newline at end of file diff --git a/src/auditordb/get_row_minor_inconsistencies.c b/src/auditordb/get_row_minor_inconsistencies.c @@ -0,0 +1,164 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_row_minor_inconsistencies.h" + + +struct RowMinorInconsistenciesContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_RowMinorInconsistenciesCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_row_minor_inconsistencies(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct RowMinorInconsistenciesContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +row_minor_inconsistencies_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct RowMinorInconsistenciesContext *dcc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_RowMinorInconsistencies dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_string ("row_table", + &dc.row_table), + GNUNET_PQ_result_spec_uint64 ("problem_row", + &dc.problem_row), + GNUNET_PQ_result_spec_string ("diagnostic", + &dc.diagnostic), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_row_minor_inconsistencies (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_RowMinorInconsistenciesCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct RowMinorInconsistenciesContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_row_minor_inconsistencies_get_desc", + "SELECT" + " row_id" + ",problem_row" + ",row_table" + ",diagnostic" + ",suppressed" + " FROM auditor_row_minor_inconsistencies" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_row_minor_inconsistencies_get_asc", + "SELECT" + " row_id" + ",problem_row" + ",row_table" + ",diagnostic" + ",suppressed" + " FROM auditor_row_minor_inconsistencies" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_row_minor_inconsistencies_get_asc" + : "auditor_row_minor_inconsistencies_get_desc", + params, + &row_minor_inconsistencies_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_wire_fee_summary.c b/src/auditordb/get_wire_fee_summary.c @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_wire_fee_summary.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_wire_fee_summary.h" +#include "pg_helper.h" + + +/** + * Get summary information about an exchanges wire fee balance. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param[out] wire_fee_balance set amount the exchange gained in wire fees + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_wire_fee_summary (struct AUDITORDB_PostgresContext *ctx, + struct TALER_Amount *wire_fee_balance) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee_balance", + wire_fee_balance), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "auditor_wire_fee_balance_select", + "SELECT" + " wire_fee_balance" + " FROM auditor_wire_fee_balance"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "auditor_wire_fee_balance_select", + params, + rs); +} diff --git a/src/auditordb/get_wire_format_inconsistency.c b/src/auditordb/get_wire_format_inconsistency.c @@ -0,0 +1,165 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_wire_format_inconsistency.h" + + +struct WireFormatInconsistencyContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_WireFormatInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_wire_format_inconsistency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct WireFormatInconsistencyContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +wire_format_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct WireFormatInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_WireFormatInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &dc.amount), + GNUNET_PQ_result_spec_uint64 ("wire_offset", + &dc.wire_offset), + GNUNET_PQ_result_spec_string ("diagnostic", + &dc.diagnostic), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_wire_format_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_WireFormatInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct WireFormatInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_wire_format_inconsistency_get_desc", + "SELECT" + " row_id," + " amount," + " wire_offset," + " diagnostic," + " suppressed" + " FROM auditor_wire_format_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_wire_format_inconsistency_get_asc", + "SELECT" + " row_id," + " amount," + " wire_offset," + " diagnostic," + " suppressed" + " FROM auditor_wire_format_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_wire_format_inconsistency_get_asc" + : "auditor_wire_format_inconsistency_get_desc", + params, + &wire_format_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/get_wire_out_inconsistency.c b/src/auditordb/get_wire_out_inconsistency.c @@ -0,0 +1,173 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "get_wire_out_inconsistency.h" + + +struct WireOutInconsistencyContext +{ + + /** + * Function to call for each bad sig loss. + */ + TALER_AUDITORDB_WireOutInconsistencyCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_get_wire_out_inconsistency(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct WireOutInconsistencyContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +wire_out_inconsistency_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct WireOutInconsistencyContext *dcc = cls; + struct AUDITORDB_PostgresContext *ctx = dcc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_WireOutInconsistency dc; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc.row_id), + GNUNET_PQ_result_spec_string ("destination_account", + &dc.destination_account.full_payto), + GNUNET_PQ_result_spec_string ("diagnostic", + &dc.diagnostic), + GNUNET_PQ_result_spec_uint64 ("wire_out_serial_id", + &dc.wire_out_row_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("expected", + &dc.expected), + TALER_PQ_RESULT_SPEC_AMOUNT ("claimed", + &dc.claimed), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc.suppressed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue rval; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + dcc->qs = i + 1; + rval = dcc->cb (dcc->cb_cls, + &dc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != rval) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_get_wire_out_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_WireOutInconsistencyCallback cb, + void *cb_cls) +{ + uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_uint64 (&plimit), + GNUNET_PQ_query_param_end + }; + struct WireOutInconsistencyContext dcc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_wire_out_inconsistency_get_desc", + "SELECT" + " row_id" + ",destination_account" + ",diagnostic" + ",wire_out_serial_id" + ",expected" + ",claimed" + ",suppressed" + " FROM auditor_wire_out_inconsistency" + " WHERE (row_id < $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3" + ); + PREPARE (ctx, + "auditor_wire_out_inconsistency_get_asc", + "SELECT" + " row_id" + ",destination_account" + ",diagnostic" + ",wire_out_serial_id" + ",expected" + ",claimed" + ",suppressed" + " FROM auditor_wire_out_inconsistency" + " WHERE (row_id > $1)" + " AND ($2 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "auditor_wire_out_inconsistency_get_asc" + : "auditor_wire_out_inconsistency_get_desc", + params, + &wire_out_inconsistency_cb, + &dcc); + if (qs > 0) + return dcc.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/helper.c b/src/auditordb/helper.c @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2015, 2016 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file auditordb/auditordb_plugin.c + * @brief Logic to load database plugin + * @author Christian Grothoff + * @author Sree Harsha Totakura <sreeharsha@totakura.in> + */ +#include "taler/platform.h" +#include "taler/taler_auditordb_plugin.h" +#include <ltdl.h> +#include "helper.h" + + +const char * +AUDITORDB_get_deletable_suppressable_table_name (enum + TALER_AUDITORDB_DeletableSuppressableTables + table) +{ + const char *tables[] = { + "auditor_amount_arithmetic_inconsistency", + "auditor_closure_lags", + "auditor_progress", + "auditor_bad_sig_losses", + "auditor_coin_inconsistency", + "auditor_denomination_key_validity_withdraw_inconsistency", + "auditor_denomination_pending", + "auditor_denomination_without_sig", + "auditor_deposit_confirmations", + "auditor_emergency", + "auditor_emergency_by_count", + "auditor_fee_time_inconsistency", + "auditor_misattribution_in_inconsistency", + "auditor_purse_not_closed_inconsistency", + "auditor_refreshes_haning", + "auditor_reserve_balance_insufficient_inconsistency", + "auditor_reserve_balance_summary_wrong_inconsistency", + "auditor_reserve_in_inconsistency", + "auditor_reserve_not_closed_inconsistency", + "auditor_row_inconsistency", + "auditor_row_minor_inconsistency", + "auditor_wire_format_inconsistency", + "auditor_wire_out_inconsistency", + NULL, + }; + + if ( (table < 0) || + (table >= TALER_AUDITORDB_DELETABLESUPPRESSABLE_TABLES_MAX)) + { + GNUNET_break (0); + return NULL; + } + return tables[table]; +} diff --git a/src/auditordb/insert_amount_arithmetic_inconsistency.c b/src/auditordb/insert_amount_arithmetic_inconsistency.c @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_amount_arithmetic_inconsistency.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_amount_arithmetic_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_AmountArithmeticInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->operation), + GNUNET_PQ_query_param_uint64 (&dc->problem_row_id), + TALER_PQ_query_param_amount (ctx->conn, + &dc->exchange_amount), + TALER_PQ_query_param_amount (ctx->conn, + &dc->auditor_amount), + GNUNET_PQ_query_param_bool (dc->profitable), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_amount_arithmetic_inconsistency_insert", + "INSERT INTO auditor_amount_arithmetic_inconsistency " + "(operation" + ",problem_row_id" + ",exchange_amount" + ",auditor_amount" + ",profitable" + ") VALUES ($1,$2,$3,$4,$5);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_amount_arithmetic_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_auditor_closure_lags.c b/src/auditordb/insert_auditor_closure_lags.c @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_auditor_closure_lags.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_auditor_closure_lags (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ClosureLags *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + &dc->amount), + GNUNET_PQ_query_param_uint64 (&dc->problem_row_id), + GNUNET_PQ_query_param_absolute_time (&dc->deadline), + GNUNET_PQ_query_param_auto_from_type (&dc->wtid), + GNUNET_PQ_query_param_string (dc->account.full_payto), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_closure_lags_insert", + "INSERT INTO auditor_closure_lags " + "(amount" + ",problem_row_id" + ",deadline" + ",wtid" + ",account" + ") VALUES ($1,$2,$3,$4,$5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_closure_lags_insert", + params); +} diff --git a/src/auditordb/insert_auditor_progress.c b/src/auditordb/insert_auditor_progress.c @@ -0,0 +1,95 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_auditor_progress.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_auditor_progress.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_auditor_progress (struct AUDITORDB_PostgresContext *ctx, + const char *progress_key, + uint64_t progress_offset, + ...) +{ + unsigned int cnt = 1; + va_list ap; + + va_start (ap, + progress_offset); + while (NULL != va_arg (ap, + const char *)) + { + cnt++; + (void) va_arg (ap, + uint64_t); + } + va_end (ap); + { + const char *keys[cnt]; + uint64_t offsets[cnt]; + unsigned int off = 1; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_array_ptrs_string (cnt, + keys, + ctx->conn), + GNUNET_PQ_query_param_array_uint64 (cnt, + offsets, + ctx->conn), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + keys[0] = progress_key; + offsets[0] = progress_offset; + + va_start (ap, + progress_offset); + while (off < cnt) + { + keys[off] = va_arg (ap, + const char *); + offsets[off] = va_arg (ap, + uint64_t); + off++; + } + GNUNET_assert (NULL == va_arg (ap, + const char *)); + va_end (ap); + + PREPARE (ctx, + "auditor_progress_insert", + "INSERT INTO auditor_progress " + "(progress_key" + ",progress_offset" + ") SELECT *" + " FROM UNNEST (CAST($1 AS TEXT[])," + " CAST($2 AS INT8[]))" + " ON CONFLICT DO NOTHING;"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_progress_insert", + params); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; + } +} diff --git a/src/auditordb/insert_bad_sig_losses.c b/src/auditordb/insert_bad_sig_losses.c @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_bad_sig_losses.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_bad_sig_losses (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_BadSigLosses *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->operation), + GNUNET_PQ_query_param_uint64 (&dc->problem_row_id), + TALER_PQ_query_param_amount (ctx->conn, + &dc->loss), + GNUNET_PQ_query_param_auto_from_type (&dc->operation_specific_pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_bad_sig_losses_insert", + "INSERT INTO auditor_bad_sig_losses " + "(operation" + ",problem_row_id" + ",loss" + ",operation_specific_pub" + ") VALUES ($1,$2,$3,$4);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_bad_sig_losses_insert", + params); +} diff --git a/src/auditordb/insert_balance.c b/src/auditordb/insert_balance.c @@ -0,0 +1,96 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_balance.c + * @brief Implementation of the insert_balance function + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_balance.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_balance (struct AUDITORDB_PostgresContext *ctx, + const char *balance_key, + const struct TALER_Amount *balance_value, + ...) +{ + unsigned int cnt = 1; + va_list ap; + + va_start (ap, + balance_value); + while (NULL != va_arg (ap, + const char *)) + { + cnt++; + (void) va_arg (ap, + const struct TALER_Amount *); + } + va_end (ap); + { + const char *keys[cnt]; + struct TALER_Amount amounts[cnt]; + unsigned int off = 1; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_array_ptrs_string (cnt, + keys, + ctx->conn), + TALER_PQ_query_param_array_amount (cnt, + amounts, + ctx->conn), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + keys[0] = balance_key; + amounts[0] = *balance_value; + + va_start (ap, + balance_value); + while (off < cnt) + { + keys[off] = va_arg (ap, + const char *); + amounts[off] = *va_arg (ap, + const struct TALER_Amount *); + off++; + } + GNUNET_assert (NULL == va_arg (ap, + const char *)); + va_end (ap); + + PREPARE (ctx, + "auditor_balance_insert", + "INSERT INTO auditor_balances " + "(balance_key" + ",balance_value.val" + ",balance_value.frac" + ") SELECT *" + " FROM UNNEST (CAST($1 AS TEXT[])," + " CAST($2 AS taler_amount[]))" + " ON CONFLICT DO NOTHING;"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_balance_insert", + params); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; + } +} diff --git a/src/auditordb/insert_coin_inconsistency.c b/src/auditordb/insert_coin_inconsistency.c @@ -0,0 +1,50 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_coin_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_coin_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_CoinInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->operation), + TALER_PQ_query_param_amount (ctx->conn, + &dc->exchange_amount), + TALER_PQ_query_param_amount (ctx->conn, + &dc->auditor_amount), + GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub), + GNUNET_PQ_query_param_bool (dc->profitable), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_coin_inconsistency_insert", + "INSERT INTO auditor_coin_inconsistency " + "(operation" + ",exchange_amount" + ",auditor_amount" + ",coin_pub" + ",profitable" + ") VALUES ($1,$2,$3,$4,$5)" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_coin_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_denomination_balance.c b/src/auditordb/insert_denomination_balance.c @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_denomination_balance.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_denomination_balance.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_denomination_balance (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + const struct TALER_AUDITORDB_DenominationCirculationData *dcd) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), + TALER_PQ_query_param_amount (ctx->conn, + &dcd->denom_balance), + TALER_PQ_query_param_amount (ctx->conn, + &dcd->denom_loss), + GNUNET_PQ_query_param_uint64 (&dcd->num_issued), + TALER_PQ_query_param_amount (ctx->conn, + &dcd->denom_risk), + TALER_PQ_query_param_amount (ctx->conn, + &dcd->recoup_loss), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_denomination_pending_insert", + "INSERT INTO auditor_denomination_pending " + "(denom_pub_hash" + ",denom_balance" + ",denom_loss" + ",num_issued" + ",denom_risk" + ",recoup_loss" + ") VALUES (" + "$1,$2,$3,$4,$5,$6" + ");"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_denomination_pending_insert", + params); +} diff --git a/src/auditordb/insert_denomination_key_validity_withdraw_inconsistency.c b/src/auditordb/insert_denomination_key_validity_withdraw_inconsistency.c @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_denomination_key_validity_withdraw_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_denomination_key_validity_withdraw_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&dc->execution_date), + GNUNET_PQ_query_param_uint64 (&dc->problem_row_id), + GNUNET_PQ_query_param_auto_from_type (&dc->reserve_pub), + GNUNET_PQ_query_param_auto_from_type (&dc->denompub_h), + + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_denomination_key_validity_withdraw_inconsistency_insert", + "INSERT INTO auditor_denomination_key_validity_withdraw_inconsistency " + "(execution_date" + ",problem_row_id" + ",reserve_pub" + ",denompub_h" + ") VALUES ($1,$2,$3,$4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_denomination_key_validity_withdraw_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_denomination_pending.c b/src/auditordb/insert_denomination_pending.c @@ -0,0 +1,59 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" + +#include "insert_denomination_pending.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_denomination_pending (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_DenominationPending *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&dc->denom_pub_hash), + TALER_PQ_query_param_amount (ctx->conn, &dc->denom_balance), + TALER_PQ_query_param_amount (ctx->conn, &dc->denom_loss), + GNUNET_PQ_query_param_uint64 (&dc->num_issued), + TALER_PQ_query_param_amount (ctx->conn, &dc->denom_risk), + TALER_PQ_query_param_amount (ctx->conn, &dc->recoup_loss), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_denomination_pending_insert", + "INSERT INTO auditor_denomination_pending " + "( denom_pub_hash," + " denom_balance," + " denom_loss," + " num_issued," + " denom_risk," + " recoup_loss" + ") VALUES ($1,$2,$3,$4,$5,$6)" + " ON CONFLICT (denom_pub_hash) UPDATE" + " SET denom_balance = excluded.denom_balance, " + " denom_loss = excluded.denom_loss," + " num_issued = excluded.num_issued," + " denom_risk = excluded.denom_risk," + " recoup_loss = excluded.recoup_loss," + " suppressed = false;" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_denomination_pending_insert", + params); +} diff --git a/src/auditordb/insert_denominations_without_sigs.c b/src/auditordb/insert_denominations_without_sigs.c @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_denominations_without_sigs.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_denominations_without_sigs (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_DenominationsWithoutSigs *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&dc->denompub_h), + TALER_PQ_query_param_amount (ctx->conn, &dc->value), + GNUNET_PQ_query_param_absolute_time (&dc->start_time), + GNUNET_PQ_query_param_absolute_time (&dc->end_time), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_denominations_without_sigs_insert", + "INSERT INTO auditor_denominations_without_sigs " + "(denompub_h," + " value," + " start_time," + " end_time" + ") VALUES ($1,$2,$3,$4)" + " ON CONFLICT (denompub_h) DO UPDATE" + " SET value = excluded.value," + " start_time = excluded.start_time," + " end_time = excluded.end_time," + " suppressed = false" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_denominations_without_sigs_insert", + params); +} diff --git a/src/auditordb/insert_deposit_confirmation.c b/src/auditordb/insert_deposit_confirmation.c @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_deposit_confirmation.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_deposit_confirmation.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_deposit_confirmation (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_DepositConfirmation *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&dc->h_contract_terms), + GNUNET_PQ_query_param_auto_from_type (&dc->h_policy), + GNUNET_PQ_query_param_auto_from_type (&dc->h_wire), + GNUNET_PQ_query_param_timestamp (&dc->exchange_timestamp), + GNUNET_PQ_query_param_timestamp (&dc->wire_deadline), + GNUNET_PQ_query_param_timestamp (&dc->refund_deadline), + TALER_PQ_query_param_amount (ctx->conn, + &dc->total_without_fee), + GNUNET_PQ_query_param_array_auto_from_type (dc->num_coins, + dc->coin_pubs, + ctx->conn), + GNUNET_PQ_query_param_array_auto_from_type (dc->num_coins, + dc->coin_sigs, + ctx->conn), + GNUNET_PQ_query_param_auto_from_type (&dc->merchant), + GNUNET_PQ_query_param_auto_from_type (&dc->exchange_sig), + GNUNET_PQ_query_param_auto_from_type (&dc->exchange_pub), + GNUNET_PQ_query_param_auto_from_type (&dc->master_sig), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_deposit_confirmation_insert", + "INSERT INTO auditor_deposit_confirmations " + "(h_contract_terms" + ",h_policy" + ",h_wire" + ",exchange_timestamp" + ",wire_deadline" + ",refund_deadline" + ",total_without_fee" + ",coin_pubs" + ",coin_sigs" + ",merchant_pub" + ",exchange_sig" + ",exchange_pub" + ",master_sig" /* master_sig could be normalized... */ + ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13);"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_deposit_confirmation_insert", + params); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; +} diff --git a/src/auditordb/insert_early_aggregation.c b/src/auditordb/insert_early_aggregation.c @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/insert_early_aggregation.c + * @brief Implementation of the insert_early_aggregation function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_early_aggregation.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_early_aggregation (struct AUDITORDB_PostgresContext *ctx, + uint64_t batch_deposit_serial_id, + uint64_t tracking_serial_id, + const struct TALER_Amount *total_amount) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&batch_deposit_serial_id), + GNUNET_PQ_query_param_uint64 (&tracking_serial_id), + TALER_PQ_query_param_amount (ctx->conn, + total_amount), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_insert_early_aggregation", + "INSERT INTO auditor_early_aggregations" + "(batch_deposit_serial_id" + ",tracking_serial_id" + ",amount" + ") VALUES ($1,$2,$3);"); + return GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "auditor_insert_early_aggregation", + params); +} diff --git a/src/auditordb/insert_emergency.c b/src/auditordb/insert_emergency.c @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_emergency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_emergency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_Emergency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&dc->denompub_h), + TALER_PQ_query_param_amount (ctx->conn, + &dc->denom_risk), + TALER_PQ_query_param_amount (ctx->conn, + &dc->denom_loss), + GNUNET_PQ_query_param_absolute_time (&dc->deposit_start), + GNUNET_PQ_query_param_absolute_time (&dc->deposit_end), + TALER_PQ_query_param_amount (ctx->conn, + &dc->value), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_emergency_insert", + "INSERT INTO auditor_emergency " + "(denompub_h" + ",denom_risk" + ",denom_loss" + ",deposit_start" + ",deposit_end" + ",value" + ") VALUES ($1,$2,$3,$4,$5,$6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_emergency_insert", + params); +} diff --git a/src/auditordb/insert_emergency_by_count.c b/src/auditordb/insert_emergency_by_count.c @@ -0,0 +1,50 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_emergency_by_count.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_emergency_by_count (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_EmergenciesByCount *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&dc->denompub_h), + GNUNET_PQ_query_param_uint64 (&dc->num_issued), + GNUNET_PQ_query_param_uint64 (&dc->num_known), + TALER_PQ_query_param_amount (ctx->conn, &dc->risk), + GNUNET_PQ_query_param_absolute_time (&dc->start), + GNUNET_PQ_query_param_absolute_time (&dc->deposit_end), + TALER_PQ_query_param_amount (ctx->conn, &dc->value), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_emergency_by_count_insert", + "INSERT INTO auditor_emergency_by_count " + "(denompub_h" + ",num_issued" + ",num_known" + ",risk" + ",start" + ",deposit_end" + ",value" + ") VALUES ($1,$2,$3,$4,$5,$6,$7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_emergency_by_count_insert", + params); +} diff --git a/src/auditordb/insert_exchange_signkey.c b/src/auditordb/insert_exchange_signkey.c @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_exchange_signkey.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_exchange_signkey.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_exchange_signkey (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ExchangeSigningKey *sk) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&sk->ep_start), + GNUNET_PQ_query_param_timestamp (&sk->ep_expire), + GNUNET_PQ_query_param_timestamp (&sk->ep_end), + GNUNET_PQ_query_param_auto_from_type (&sk->exchange_pub), + GNUNET_PQ_query_param_auto_from_type (&sk->master_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_insert_exchange_signkey", + "INSERT INTO auditor_exchange_signkeys " + "(ep_valid_from" + ",ep_expire_sign" + ",ep_expire_legal" + ",exchange_pub" + ",master_sig" + ") VALUES ($1,$2,$3,$4,$5);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_insert_exchange_signkey", + params); +} diff --git a/src/auditordb/insert_fee_time_inconsistency.c b/src/auditordb/insert_fee_time_inconsistency.c @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_fee_time_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_fee_time_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_FeeTimeInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->type), + GNUNET_PQ_query_param_uint64 (&dc->problem_row_id), + GNUNET_PQ_query_param_absolute_time (&dc->time), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_fee_time_inconsistency_insert", + "INSERT INTO auditor_fee_time_inconsistency " + "(fee_type" + ",problem_row_id" + ",fee_time" + ",diagnostic" + ") VALUES ($1,$2,$3,$4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_fee_time_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_historic_denom_revenue.c b/src/auditordb/insert_historic_denom_revenue.c @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_historic_denom_revenue.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_historic_denom_revenue.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_historic_denom_revenue (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + struct GNUNET_TIME_Timestamp revenue_timestamp, + const struct TALER_Amount *revenue_balance, + const struct TALER_Amount *loss_balance) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), + GNUNET_PQ_query_param_timestamp (&revenue_timestamp), + TALER_PQ_query_param_amount (ctx->conn, + revenue_balance), + TALER_PQ_query_param_amount (ctx->conn, + loss_balance), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_historic_denomination_revenue_insert", + "INSERT INTO auditor_historic_denomination_revenue" + "(denom_pub_hash" + ",revenue_timestamp" + ",revenue_balance" + ",loss_balance" + ") VALUES ($1,$2,$3,$4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_historic_denomination_revenue_insert", + params); +} diff --git a/src/auditordb/insert_historic_reserve_revenue.c b/src/auditordb/insert_historic_reserve_revenue.c @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_historic_reserve_revenue.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_historic_reserve_revenue.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_historic_reserve_revenue (struct AUDITORDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp start_time, + struct GNUNET_TIME_Timestamp end_time, + const struct TALER_Amount *reserve_profits) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&start_time), + GNUNET_PQ_query_param_timestamp (&end_time), + TALER_PQ_query_param_amount (ctx->conn, + reserve_profits), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_historic_reserve_summary_insert", + "INSERT INTO auditor_historic_reserve_summary" + "(start_date" + ",end_date" + ",reserve_profits" + ") VALUES ($1,$2,$3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_historic_reserve_summary_insert", + params); +} diff --git a/src/auditordb/insert_misattribution_in_inconsistency.c b/src/auditordb/insert_misattribution_in_inconsistency.c @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_misattribution_in_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_misattribution_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_MisattributionInInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + &dc->amount), + GNUNET_PQ_query_param_uint64 (&dc->bank_row), + GNUNET_PQ_query_param_auto_from_type (&dc->reserve_pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_misattribution_in_inconsistency_insert", + "INSERT INTO auditor_misattribution_in_inconsistency " + "(amount," + " bank_row," + " reserve_pub" + ") VALUES ($1,$2,$3);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_misattribution_in_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_pending_deposit.c b/src/auditordb/insert_pending_deposit.c @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/insert_pending_deposit.c + * @brief Implementation of the insert_pending_deposit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_pending_deposit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_pending_deposit (struct AUDITORDB_PostgresContext *ctx, + uint64_t batch_deposit_serial_id, + const struct TALER_FullPaytoHashP *wire_target_h_payto, + const struct TALER_Amount *total_amount, + struct GNUNET_TIME_Timestamp deadline) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + total_amount), + GNUNET_PQ_query_param_auto_from_type (wire_target_h_payto), + GNUNET_PQ_query_param_uint64 (&batch_deposit_serial_id), + GNUNET_PQ_query_param_timestamp (&deadline), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_insert_pending_deposit", + "INSERT INTO auditor_pending_deposits " + "(total_amount" + ",wire_target_h_payto" + ",batch_deposit_serial_id" + ",deadline" + ") VALUES ($1,$2,$3,$4);"); + return GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "auditor_insert_pending_deposit", + params); +} diff --git a/src/auditordb/insert_purse_info.c b/src/auditordb/insert_purse_info.c @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/insert_purse_info.c + * @brief Implementation of the insert_purse_info function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_purse_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_purse_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_Amount *balance, + struct GNUNET_TIME_Timestamp expiration_date) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + TALER_PQ_query_param_amount (ctx->conn, + balance), + GNUNET_PQ_query_param_timestamp (&expiration_date), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_purses_insert", + "INSERT INTO auditor_purses " + "(purse_pub" + ",target" + ",expiration_date" + ") VALUES ($1,$2,$3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_purses_insert", + params); +} diff --git a/src/auditordb/insert_purse_not_closed_inconsistencies.c b/src/auditordb/insert_purse_not_closed_inconsistencies.c @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_purse_not_closed_inconsistencies.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_purse_not_closed_inconsistencies (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_PurseNotClosedInconsistencies *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&dc->purse_pub), + TALER_PQ_query_param_amount (ctx->conn, + &dc->amount), + GNUNET_PQ_query_param_absolute_time (&dc->expiration_date), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_purse_not_closed_inconsistencies_insert", + "INSERT INTO auditor_purse_not_closed_inconsistencies " + "(purse_pub" + ",amount" + ",expiration_date" + ") VALUES ($1,$2,$3)" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_purse_not_closed_inconsistencies_insert", + params); +} diff --git a/src/auditordb/insert_reserve_balance_insufficient_inconsistency.c b/src/auditordb/insert_reserve_balance_insufficient_inconsistency.c @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" + +#include "insert_reserve_balance_insufficient_inconsistency.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_balance_insufficient_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + + GNUNET_PQ_query_param_auto_from_type (&dc->reserve_pub), + GNUNET_PQ_query_param_bool (dc->inconsistency_gain), + TALER_PQ_query_param_amount (ctx->conn, &dc->inconsistency_amount), + + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_reserve_balance_insufficient_inconsistency_insert", + "INSERT INTO auditor_reserve_balance_insufficient_inconsistency " + "(reserve_pub" + ",inconsistency_gain" + ",inconsistency_amount" + ") VALUES ($1,$2,$3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_reserve_balance_insufficient_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_reserve_balance_summary_wrong_inconsistency.c b/src/auditordb/insert_reserve_balance_summary_wrong_inconsistency.c @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" + +#include "insert_reserve_balance_summary_wrong_inconsistency.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_balance_summary_wrong_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + + GNUNET_PQ_query_param_auto_from_type (&dc->reserve_pub), + TALER_PQ_query_param_amount (ctx->conn, &dc->exchange_amount), + TALER_PQ_query_param_amount (ctx->conn, &dc->auditor_amount), + + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_reserve_balance_summary_wrong_inconsistency_insert", + "INSERT INTO auditor_reserve_balance_summary_wrong_inconsistency " + "(reserve_pub," + " exchange_amount," + " auditor_amount" + ") VALUES ($1,$2,$3);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_reserve_balance_summary_wrong_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_reserve_in_inconsistency.c b/src/auditordb/insert_reserve_in_inconsistency.c @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_reserve_in_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ReserveInInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&dc->bank_row_id), + TALER_PQ_query_param_amount (ctx->conn, + &dc->amount_exchange_expected), + TALER_PQ_query_param_amount (ctx->conn, + &dc->amount_wired), + GNUNET_PQ_query_param_auto_from_type (&dc->reserve_pub), + GNUNET_PQ_query_param_absolute_time (&dc->timestamp), + GNUNET_PQ_query_param_string (dc->account.full_payto), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_reserve_in_inconsistency_insert", + "INSERT INTO auditor_reserve_in_inconsistency " + "(bank_row_id," + " amount_exchange_expected," + " amount_wired," + " reserve_pub," + " timestamp," + " account," + " diagnostic" + ") VALUES ($1,$2,$3,$4,$5,$6,$7);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_reserve_in_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_reserve_info.c b/src/auditordb/insert_reserve_info.c @@ -0,0 +1,77 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_reserve_info.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_reserve_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_AUDITORDB_ReserveFeeBalance *rfb, + struct GNUNET_TIME_Timestamp expiration_date, + const struct TALER_FullPayto origin_account) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->reserve_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->reserve_loss), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->withdraw_fee_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->close_fee_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->purse_fee_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->open_fee_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->history_fee_balance), + GNUNET_PQ_query_param_timestamp (&expiration_date), + NULL == origin_account.full_payto + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (origin_account.full_payto), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_insert_reserve_info", + "INSERT INTO auditor_reserves " + "(reserve_pub" + ",reserve_balance" + ",reserve_loss" + ",withdraw_fee_balance" + ",close_fee_balance" + ",purse_fee_balance" + ",open_fee_balance" + ",history_fee_balance" + ",expiration_date" + ",origin_account" + ") VALUES " + "($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_insert_reserve_info", + params); +} diff --git a/src/auditordb/insert_reserve_not_closed_inconsistency.c b/src/auditordb/insert_reserve_not_closed_inconsistency.c @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_reserve_not_closed_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_not_closed_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ReserveNotClosedInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&dc->reserve_pub), + TALER_PQ_query_param_amount (ctx->conn, + &dc->balance), + GNUNET_PQ_query_param_absolute_time (&dc->expiration_time), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_reserve_not_closed_inconsistency_insert", + "INSERT INTO auditor_reserve_not_closed_inconsistency " + "(reserve_pub," + " balance," + " expiration_time," + " diagnostic" + ") VALUES ($1,$2,$3,$4)" + " ON CONFLICT DO NOTHING;" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_reserve_not_closed_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_row_inconsistency.c b/src/auditordb/insert_row_inconsistency.c @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_row_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_row_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_RowInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->row_table), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_uint64 (&dc->row_id), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_insert_row_inconsistency", + "INSERT INTO auditor_row_inconsistency " + "(row_table" + ",diagnostic" + ",problem_row_id" + ") VALUES ($1,$2,$3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_insert_row_inconsistency", + params); +} diff --git a/src/auditordb/insert_row_minor_inconsistencies.c b/src/auditordb/insert_row_minor_inconsistencies.c @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_row_minor_inconsistencies.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_row_minor_inconsistencies (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_RowMinorInconsistencies *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->row_table), + GNUNET_PQ_query_param_uint64 (&dc->problem_row), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_row_minor_inconsistencies_insert", + "INSERT INTO auditor_row_minor_inconsistencies " + "(row_table" + ",problem_row" + ",diagnostic" + ") VALUES ($1,$2,$3);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_row_minor_inconsistencies_insert", + params); +} diff --git a/src/auditordb/insert_wire_format_inconsistency.c b/src/auditordb/insert_wire_format_inconsistency.c @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "insert_wire_format_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_wire_format_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_WireFormatInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + &dc->amount), + GNUNET_PQ_query_param_uint64 (&dc->wire_offset), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_wire_format_inconsistency_insert", + "INSERT INTO auditor_wire_format_inconsistency " + "(amount" + ",wire_offset" + ",diagnostic" + ") VALUES ($1,$2,$3);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_wire_format_inconsistency_insert", + params); +} diff --git a/src/auditordb/insert_wire_out_inconsistency.c b/src/auditordb/insert_wire_out_inconsistency.c @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" + +#include "insert_wire_out_inconsistency.h" + +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_wire_out_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_WireOutInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (dc->destination_account.full_payto), + GNUNET_PQ_query_param_string (dc->diagnostic), + GNUNET_PQ_query_param_uint64 (&dc->wire_out_row_id), + TALER_PQ_query_param_amount (ctx->conn, + &dc->expected), + TALER_PQ_query_param_amount (ctx->conn, + &dc->claimed), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_wire_out_inconsistency_insert", + "INSERT INTO auditor_wire_out_inconsistency " + "(destination_account" + ",diagnostic" + ",wire_out_serial_id" + ",expected" + ",claimed" + ") VALUES ($1,$2,$3,$4,$5);" + ); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_wire_out_inconsistency_insert", + params); +} diff --git a/src/auditordb/lookup_reserve_in_inconsistency.c b/src/auditordb/lookup_reserve_in_inconsistency.c @@ -0,0 +1,73 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "lookup_reserve_in_inconsistency.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_lookup_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + uint64_t bank_row_id, + struct TALER_AUDITORDB_ReserveInInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&bank_row_id), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc->serial_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_exchange_expected", + &dc->amount_exchange_expected), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_wired", + &dc->amount_wired), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc->reserve_pub), + GNUNET_PQ_result_spec_absolute_time ("timestamp", + &dc->timestamp), + GNUNET_PQ_result_spec_string ("account", + &dc->account.full_payto), + GNUNET_PQ_result_spec_string ("diagnostic", + &dc->diagnostic), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc->suppressed), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "auditor_lookup_reserve_in_inconsistency", + "SELECT" + " row_id" + ",amount_exchange_expected" + ",amount_wired" + ",reserve_pub" + ",timestamp" + ",account" + ",diagnostic" + ",suppressed" + " FROM auditor_reserve_in_inconsistency" + " WHERE (bank_row_id = $1)" + ); + dc->bank_row_id = bank_row_id; + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "auditor_lookup_reserve_in_inconsistency", + params, + rs); +} diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c @@ -23,113 +23,113 @@ #include "taler/taler_pq_lib.h" #include <pthread.h> #include <libpq-fe.h> -#include "pg_delete_auditor_closure_lag.h" -#include "pg_delete_early_aggregation.h" -#include "pg_delete_generic.h" -#include "pg_delete_pending_deposit.h" -#include "pg_delete_purse_info.h" -#include "pg_delete_reserve_in_inconsistency.h" -#include "pg_del_denomination_balance.h" -#include "pg_del_reserve_info.h" -#include "pg_get_auditor_progress.h" -#include "pg_get_balance.h" -#include "pg_get_balances.h" -#include "pg_get_denomination_balance.h" -#include "pg_get_deposit_confirmations.h" -#include "pg_get_purse_info.h" -#include "pg_get_reserve_info.h" -#include "pg_get_wire_fee_summary.h" +#include "delete_auditor_closure_lag.h" +#include "delete_early_aggregation.h" +#include "delete_generic.h" +#include "delete_pending_deposit.h" +#include "delete_purse_info.h" +#include "delete_reserve_in_inconsistency.h" +#include "del_denomination_balance.h" +#include "del_reserve_info.h" +#include "get_auditor_progress.h" +#include "get_balance.h" +#include "get_balances.h" +#include "get_denomination_balance.h" +#include "get_deposit_confirmations.h" +#include "get_purse_info.h" +#include "get_reserve_info.h" +#include "get_wire_fee_summary.h" #include "pg_helper.h" -#include "pg_insert_auditor_progress.h" -#include "pg_insert_balance.h" -#include "pg_insert_denomination_balance.h" -#include "pg_insert_deposit_confirmation.h" -#include "pg_insert_early_aggregation.h" -#include "pg_insert_exchange_signkey.h" -#include "pg_insert_historic_denom_revenue.h" -#include "pg_insert_historic_reserve_revenue.h" -#include "pg_insert_pending_deposit.h" -#include "pg_insert_purse_info.h" -#include "pg_insert_reserve_info.h" -#include "pg_select_reserve_in_inconsistency.h" -#include "pg_select_historic_denom_revenue.h" -#include "pg_select_historic_reserve_revenue.h" -#include "pg_get_progress_points.h" -#include "pg_select_pending_deposits.h" -#include "pg_select_purse_expired.h" -#include "pg_update_generic_suppressed.h" -#include "pg_update_auditor_progress.h" -#include "pg_update_denomination_balance.h" -#include "pg_update_purse_info.h" -#include "pg_update_reserve_info.h" -#include "pg_update_wire_fee_summary.h" -#include "pg_get_amount_arithmetic_inconsistency.h" -#include "pg_get_coin_inconsistency.h" -#include "pg_get_row_inconsistency.h" -#include "pg_update_balance.h" -#include "pg_select_early_aggregations.h" - -#include "pg_insert_coin_inconsistency.h" -#include "pg_insert_row_inconsistency.h" -#include "pg_insert_amount_arithmetic_inconsistency.h" - -#include "pg_get_auditor_closure_lags.h" -#include "pg_insert_auditor_closure_lags.h" - -#include "pg_get_emergency_by_count.h" -#include "pg_insert_emergency_by_count.h" - -#include "pg_get_emergency.h" -#include "pg_insert_emergency.h" - -#include "pg_get_bad_sig_losses.h" -#include "pg_insert_bad_sig_losses.h" - -#include "pg_get_denomination_key_validity_withdraw_inconsistency.h" -#include "pg_insert_denomination_key_validity_withdraw_inconsistency.h" - -#include "pg_get_fee_time_inconsistency.h" -#include "pg_insert_fee_time_inconsistency.h" - -#include "pg_get_purse_not_closed_inconsistencies.h" -#include "pg_insert_purse_not_closed_inconsistencies.h" - -#include "pg_get_reserve_balance_insufficient_inconsistency.h" -#include "pg_insert_reserve_balance_insufficient_inconsistency.h" - -#include "pg_get_reserve_in_inconsistency.h" -#include "pg_lookup_reserve_in_inconsistency.h" -#include "pg_insert_reserve_in_inconsistency.h" - -#include "pg_get_reserve_not_closed_inconsistency.h" -#include "pg_insert_reserve_not_closed_inconsistency.h" - -#include "pg_get_denominations_without_sigs.h" -#include "pg_insert_denominations_without_sigs.h" - -#include "pg_get_misattribution_in_inconsistency.h" -#include "pg_insert_misattribution_in_inconsistency.h" - -#include "pg_get_reserves.h" -#include "pg_get_purses.h" - -#include "pg_get_denomination_pending.h" -#include "pg_insert_denomination_pending.h" - -#include "pg_get_exchange_signkeys.h" - -#include "pg_get_wire_format_inconsistency.h" -#include "pg_insert_wire_format_inconsistency.h" - -#include "pg_get_wire_out_inconsistency.h" -#include "pg_insert_wire_out_inconsistency.h" -#include "pg_delete_wire_out_inconsistency_if_matching.h" - -#include "pg_get_reserve_balance_summary_wrong_inconsistency.h" -#include "pg_insert_reserve_balance_summary_wrong_inconsistency.h" - -#include "pg_get_row_minor_inconsistencies.h" -#include "pg_insert_row_minor_inconsistencies.h" +#include "insert_auditor_progress.h" +#include "insert_balance.h" +#include "insert_denomination_balance.h" +#include "insert_deposit_confirmation.h" +#include "insert_early_aggregation.h" +#include "insert_exchange_signkey.h" +#include "insert_historic_denom_revenue.h" +#include "insert_historic_reserve_revenue.h" +#include "insert_pending_deposit.h" +#include "insert_purse_info.h" +#include "insert_reserve_info.h" +#include "select_reserve_in_inconsistency.h" +#include "select_historic_denom_revenue.h" +#include "select_historic_reserve_revenue.h" +#include "get_progress_points.h" +#include "select_pending_deposits.h" +#include "select_purse_expired.h" +#include "update_generic_suppressed.h" +#include "update_auditor_progress.h" +#include "update_denomination_balance.h" +#include "update_purse_info.h" +#include "update_reserve_info.h" +#include "update_wire_fee_summary.h" +#include "get_amount_arithmetic_inconsistency.h" +#include "get_coin_inconsistency.h" +#include "get_row_inconsistency.h" +#include "update_balance.h" +#include "select_early_aggregations.h" + +#include "insert_coin_inconsistency.h" +#include "insert_row_inconsistency.h" +#include "insert_amount_arithmetic_inconsistency.h" + +#include "get_auditor_closure_lags.h" +#include "insert_auditor_closure_lags.h" + +#include "get_emergency_by_count.h" +#include "insert_emergency_by_count.h" + +#include "get_emergency.h" +#include "insert_emergency.h" + +#include "get_bad_sig_losses.h" +#include "insert_bad_sig_losses.h" + +#include "get_denomination_key_validity_withdraw_inconsistency.h" +#include "insert_denomination_key_validity_withdraw_inconsistency.h" + +#include "get_fee_time_inconsistency.h" +#include "insert_fee_time_inconsistency.h" + +#include "get_purse_not_closed_inconsistencies.h" +#include "insert_purse_not_closed_inconsistencies.h" + +#include "get_reserve_balance_insufficient_inconsistency.h" +#include "insert_reserve_balance_insufficient_inconsistency.h" + +#include "get_reserve_in_inconsistency.h" +#include "lookup_reserve_in_inconsistency.h" +#include "insert_reserve_in_inconsistency.h" + +#include "get_reserve_not_closed_inconsistency.h" +#include "insert_reserve_not_closed_inconsistency.h" + +#include "get_denominations_without_sigs.h" +#include "insert_denominations_without_sigs.h" + +#include "get_misattribution_in_inconsistency.h" +#include "insert_misattribution_in_inconsistency.h" + +#include "get_reserves.h" +#include "get_purses.h" + +#include "get_denomination_pending.h" +#include "insert_denomination_pending.h" + +#include "get_exchange_signkeys.h" + +#include "get_wire_format_inconsistency.h" +#include "insert_wire_format_inconsistency.h" + +#include "get_wire_out_inconsistency.h" +#include "insert_wire_out_inconsistency.h" +#include "delete_wire_out_inconsistency_if_matching.h" + +#include "get_reserve_balance_summary_wrong_inconsistency.h" +#include "insert_reserve_balance_summary_wrong_inconsistency.h" + +#include "get_row_minor_inconsistencies.h" +#include "insert_row_minor_inconsistencies.h" #define LOG(kind,...) GNUNET_log_from (kind, "taler-auditordb-postgres", \ __VA_ARGS__) @@ -140,7 +140,7 @@ * This should only be used by testcases or when restarting the * auditor from scratch. * - * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param cls the `struct AUDITORDB_PostgresContext` with the plugin-specific state * @param drop_exchangelist drop all tables, including schema versioning * and the exchange and deposit_confirmations table; NOT to be * used when restarting the auditor @@ -150,7 +150,7 @@ static enum GNUNET_GenericReturnValue postgres_drop_tables (void *cls, bool drop_exchangelist) { - struct PostgresClosure *pc = cls; + struct AUDITORDB_PostgresContext *pc = cls; struct GNUNET_PQ_Context *conn; enum GNUNET_GenericReturnValue ret; @@ -171,7 +171,7 @@ postgres_drop_tables (void *cls, /** * Create the necessary tables if they are not present * - * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param cls the `struct AUDITORDB_PostgresContext` with the plugin-specific state * @param support_partitions true to support partitioning * @param num_partitions number of partitions to use * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure @@ -181,7 +181,7 @@ postgres_create_tables (void *cls, bool support_partitions, uint32_t num_partitions) { - struct PostgresClosure *pc = cls; + struct AUDITORDB_PostgresContext *pc = cls; enum GNUNET_GenericReturnValue ret = GNUNET_OK; struct GNUNET_PQ_Context *conn; struct GNUNET_PQ_QueryParam params[] = { @@ -246,15 +246,13 @@ postgres_create_tables (void *cls, * @param cb_cls closure for @a cb * @return handle useful to cancel the listener */ -static struct GNUNET_DB_EventHandler * -postgres_event_listen (void *cls, +struct GNUNET_DB_EventHandler * +AUDITORDB_event_listen (struct AUDITORDB_PostgresContext *pg, const struct GNUNET_DB_EventHeaderP *es, struct GNUNET_TIME_Relative timeout, GNUNET_DB_EventCallback cb, void *cb_cls) { - struct PostgresClosure *pg = cls; - return GNUNET_PQ_event_listen (pg->conn, es, timeout, @@ -283,14 +281,12 @@ postgres_event_listen_cancel (struct GNUNET_DB_EventHandler *eh) * @param extra additional event data provided * @param extra_size number of bytes in @a extra */ -static void -postgres_event_notify (void *cls, +void +AUDITORDB_event_notify (struct AUDITORDB_PostgresContext *pg, const struct GNUNET_DB_EventHeaderP *es, const void *extra, size_t extra_size) { - struct PostgresClosure *pg = cls; - return GNUNET_PQ_event_notify (pg->conn, es, extra, @@ -305,7 +301,7 @@ postgres_event_notify (void *cls, * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue -setup_connection (struct PostgresClosure *pg) +setup_connection (struct AUDITORDB_PostgresContext *pg) { struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"), @@ -336,15 +332,14 @@ setup_connection (struct PostgresClosure *pg) * Do a pre-flight check that we are not in an uncommitted transaction. * If we are, rollback the previous transaction and output a warning. * - * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param cls the `struct AUDITORDB_PostgresContext` with the plugin-specific state * @return #GNUNET_OK on success, * #GNUNET_NO if we rolled back an earlier transaction * #GNUNET_SYSERR if we have no DB connection */ -static enum GNUNET_GenericReturnValue -postgres_preflight (void *cls) +enum GNUNET_GenericReturnValue +AUDITORDB_preflight (struct AUDITORDB_PostgresContext *pg) { - struct PostgresClosure *pg = cls; struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_execute ("ROLLBACK"), GNUNET_PQ_EXECUTE_STATEMENT_END @@ -378,13 +373,12 @@ postgres_preflight (void *cls) /** * Start a transaction. * - * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param cls the `struct AUDITORDB_PostgresContext` with the plugin-specific state * @return #GNUNET_OK on success */ -static enum GNUNET_GenericReturnValue -postgres_start (void *cls) +enum GNUNET_GenericReturnValue +AUDITORDB_start (struct AUDITORDB_PostgresContext *pg) { - struct PostgresClosure *pg = cls; struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"), GNUNET_PQ_EXECUTE_STATEMENT_END @@ -406,12 +400,11 @@ postgres_start (void *cls) /** * Roll back the current transaction of a database connection. * - * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param cls the `struct AUDITORDB_PostgresContext` with the plugin-specific state */ -static void -postgres_rollback (void *cls) +void +AUDITORDB_rollback (struct AUDITORDB_PostgresContext *pg) { - struct PostgresClosure *pg = cls; struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_execute ("ROLLBACK"), GNUNET_PQ_EXECUTE_STATEMENT_END @@ -426,13 +419,12 @@ postgres_rollback (void *cls) /** * Commit the current transaction of a database connection. * - * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param cls the `struct AUDITORDB_PostgresContext` with the plugin-specific state * @return transaction status code */ -static enum GNUNET_DB_QueryStatus -postgres_commit (void *cls) +enum GNUNET_DB_QueryStatus +AUDITORDB_commit (struct AUDITORDB_PostgresContext *pg) { - struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_end }; @@ -454,10 +446,9 @@ postgres_commit (void *cls) * @return #GNUNET_OK on success, * #GNUNET_SYSERR on DB errors */ -static enum GNUNET_GenericReturnValue -postgres_gc (void *cls) +enum GNUNET_GenericReturnValue +AUDITORDB_gc (struct AUDITORDB_PostgresContext *pg) { - struct PostgresClosure *pg = cls; /* For now, we hard-code the cut-off date based on the common legal requirement to keep data for 10 years. Might make it configurable in the future. */ @@ -511,18 +502,13 @@ postgres_gc (void *cls) * @param cls a configuration instance * @return NULL on error, otherwise a `struct TALER_AUDITORDB_Plugin` */ -void * -libtaler_plugin_auditordb_postgres_init (void *cls); - -/* Declaration used to squash compiler warning */ -void * -libtaler_plugin_auditordb_postgres_init (void *cls) +struct AUDITORDB_PostgresContext * +AUDITORDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, + bool skip_preflight) { - const struct GNUNET_CONFIGURATION_Handle *cfg = cls; - struct PostgresClosure *pg; - struct TALER_AUDITORDB_Plugin *plugin; + struct AUDITORDB_PostgresContext *pg; - pg = GNUNET_new (struct PostgresClosure); + pg = GNUNET_new (struct AUDITORDB_PostgresContext); pg->cfg = cfg; if (GNUNET_OK != TALER_config_get_currency (cfg, @@ -532,213 +518,7 @@ libtaler_plugin_auditordb_postgres_init (void *cls) GNUNET_free (pg); return NULL; } - - plugin = GNUNET_new (struct TALER_AUDITORDB_Plugin); - plugin->cls = pg; - plugin->preflight = &postgres_preflight; - plugin->drop_tables = &postgres_drop_tables; - plugin->create_tables = &postgres_create_tables; - plugin->event_listen = &postgres_event_listen; - plugin->event_listen_cancel = &postgres_event_listen_cancel; - plugin->event_notify = &postgres_event_notify; - plugin->start = &postgres_start; - plugin->commit = &postgres_commit; - plugin->rollback = &postgres_rollback; - plugin->gc = &postgres_gc; - - plugin->get_auditor_progress - = &TAH_PG_get_auditor_progress; - - plugin->get_balance = &TAH_PG_get_balance; - plugin->get_balances = &TAH_PG_get_balances; - - plugin->insert_auditor_progress - = &TAH_PG_insert_auditor_progress; - plugin->insert_balance - = &TAH_PG_insert_balance; - plugin->update_generic_suppressed - = &TAH_PG_update_generic_suppressed; - plugin->delete_generic - = &TAH_PG_delete_generic; - plugin->delete_wire_out_inconsistency_if_matching - = &TAH_PG_delete_wire_out_inconsistency_if_matching; - - plugin->delete_auditor_closure_lag - = &TAH_PG_delete_auditor_closure_lag; - - plugin->update_auditor_progress - = &TAH_PG_update_auditor_progress; - plugin->insert_deposit_confirmation - = &TAH_PG_insert_deposit_confirmation; - plugin->get_deposit_confirmations - = &TAH_PG_get_deposit_confirmations; - - plugin->get_amount_arithmetic_inconsistency - = &TAH_PG_get_amount_arithmetic_inconsistency; - plugin->get_coin_inconsistency - = &TAH_PG_get_coin_inconsistency; - plugin->get_row_inconsistency - = &TAH_PG_get_row_inconsistency; - - - plugin->insert_amount_arithmetic_inconsistency - = &TAH_PG_insert_amount_arithmetic_inconsistency; - plugin->insert_coin_inconsistency - = &TAH_PG_insert_coin_inconsistency; - plugin->insert_row_inconsistency - = &TAH_PG_insert_row_inconsistency; - - plugin->insert_reserve_info - = &TAH_PG_insert_reserve_info; - plugin->update_reserve_info - = &TAH_PG_update_reserve_info; - plugin->get_reserve_info - = &TAH_PG_get_reserve_info; - plugin->del_reserve_info - = &TAH_PG_del_reserve_info; - - plugin->insert_pending_deposit - = &TAH_PG_insert_pending_deposit; - plugin->select_pending_deposits - = &TAH_PG_select_pending_deposits; - plugin->delete_pending_deposit - = &TAH_PG_delete_pending_deposit; - - plugin->insert_purse_info - = &TAH_PG_insert_purse_info; - plugin->update_purse_info - = &TAH_PG_update_purse_info; - plugin->get_purse_info - = &TAH_PG_get_purse_info; - plugin->delete_purse_info - = &TAH_PG_delete_purse_info; - plugin->select_purse_expired - = &TAH_PG_select_purse_expired; - - plugin->insert_denomination_balance - = &TAH_PG_insert_denomination_balance; - plugin->update_denomination_balance - = &TAH_PG_update_denomination_balance; - plugin->del_denomination_balance - = &TAH_PG_del_denomination_balance; - plugin->get_denomination_balance - = &TAH_PG_get_denomination_balance; - - plugin->insert_historic_denom_revenue - = &TAH_PG_insert_historic_denom_revenue; - - plugin->select_historic_denom_revenue - = &TAH_PG_select_historic_denom_revenue; - - plugin->insert_historic_reserve_revenue - = &TAH_PG_insert_historic_reserve_revenue; - plugin->select_historic_reserve_revenue - = &TAH_PG_select_historic_reserve_revenue; - - - plugin->insert_emergency = &TAH_PG_insert_emergency; - plugin->get_emergency = &TAH_PG_get_emergency; - - plugin->insert_emergency_by_count = &TAH_PG_insert_emergency_by_count; - plugin->get_emergency_by_count = &TAH_PG_get_emergency_by_count; - - - plugin->insert_denomination_key_validity_withdraw_inconsistency = - &TAH_PG_insert_denomination_key_validity_withdraw_inconsistency; - plugin->get_denomination_key_validity_withdraw_inconsistency = - &TAH_PG_get_denomination_key_validity_withdraw_inconsistency; - - plugin->insert_purse_not_closed_inconsistencies = - &TAH_PG_insert_purse_not_closed_inconsistencies; - plugin->get_purse_not_closed_inconsistencies = - &TAH_PG_get_purse_not_closed_inconsistencies; - - - plugin->insert_reserve_balance_insufficient_inconsistency = - &TAH_PG_insert_reserve_balance_insufficient_inconsistency; - plugin->get_reserve_balance_insufficient_inconsistency = - &TAH_PG_get_reserve_balance_insufficient_inconsistency; - - plugin->insert_bad_sig_losses = &TAH_PG_insert_bad_sig_losses; - plugin->get_bad_sig_losses = &TAH_PG_get_bad_sig_losses; - - plugin->insert_auditor_closure_lags = &TAH_PG_insert_auditor_closure_lags; - plugin->get_auditor_closure_lags = &TAH_PG_get_auditor_closure_lags; - - plugin->insert_reserve_in_inconsistency = - &TAH_PG_insert_reserve_in_inconsistency; - plugin->get_reserve_in_inconsistency - = &TAH_PG_get_reserve_in_inconsistency; - plugin->lookup_reserve_in_inconsistency - = &TAH_PG_lookup_reserve_in_inconsistency; - - plugin->insert_reserve_not_closed_inconsistency = - &TAH_PG_insert_reserve_not_closed_inconsistency; - plugin->get_reserve_not_closed_inconsistency = - &TAH_PG_get_reserve_not_closed_inconsistency; - - plugin->insert_denominations_without_sigs = - &TAH_PG_insert_denominations_without_sigs; - plugin->get_denominations_without_sigs = - &TAH_PG_get_denominations_without_sigs; - - plugin->get_progress_points - = &TAH_PG_get_progress_points; - - - plugin->insert_misattribution_in_inconsistency = - &TAH_PG_insert_misattribution_in_inconsistency; - plugin->get_misattribution_in_inconsistency = - &TAH_PG_get_misattribution_in_inconsistency; - - plugin->get_reserves = &TAH_PG_get_reserves; - plugin->get_purses = &TAH_PG_get_purses; - - plugin->insert_denomination_pending = &TAH_PG_insert_denomination_pending; - plugin->get_denomination_pending = &TAH_PG_get_denomination_pending; - - plugin->get_exchange_signkeys = &TAH_PG_get_exchange_signkeys; - - plugin->insert_wire_format_inconsistency = - &TAH_PG_insert_wire_format_inconsistency; - plugin->get_wire_format_inconsistency = &TAH_PG_get_wire_format_inconsistency; - - plugin->insert_early_aggregation - = &TAH_PG_insert_early_aggregation; - plugin->delete_early_aggregation - = &TAH_PG_delete_early_aggregation; - - plugin->insert_wire_out_inconsistency - = &TAH_PG_insert_wire_out_inconsistency; - plugin->get_wire_out_inconsistency - = &TAH_PG_get_wire_out_inconsistency; - plugin->select_reserve_in_inconsistency - = &TAH_PG_select_reserve_in_inconsistency; - plugin->delete_reserve_in_inconsistency - = &TAH_PG_delete_reserve_in_inconsistency; - plugin->select_early_aggregations - = &TAH_PG_select_early_aggregations; - - plugin->insert_reserve_balance_summary_wrong_inconsistency = - &TAH_PG_insert_reserve_balance_summary_wrong_inconsistency; - plugin->get_reserve_balance_summary_wrong_inconsistency = - &TAH_PG_get_reserve_balance_summary_wrong_inconsistency; - - - plugin->insert_row_minor_inconsistencies = - &TAH_PG_insert_row_minor_inconsistencies; - plugin->get_row_minor_inconsistencies = &TAH_PG_get_row_minor_inconsistencies; - - plugin->insert_fee_time_inconsistency = &TAH_PG_insert_fee_time_inconsistency; - plugin->get_fee_time_inconsistency = &TAH_PG_get_fee_time_inconsistency; - - plugin->update_balance - = &TAH_PG_update_balance; - - plugin->insert_exchange_signkey - = &TAH_PG_insert_exchange_signkey; - - return plugin; + return pg; } @@ -748,22 +528,15 @@ libtaler_plugin_auditordb_postgres_init (void *cls) * @param cls a `struct TALER_AUDITORDB_Plugin` * @return NULL (always) */ -void * -libtaler_plugin_auditordb_postgres_done (void *cls); - -/* Declaration used to squash compiler warning */ -void * -libtaler_plugin_auditordb_postgres_done (void *cls) +void +AUDITORDB_disconnect (struct AUDITORDB_PostgresContext *pg) { - struct TALER_AUDITORDB_Plugin *plugin = cls; - struct PostgresClosure *pg = plugin->cls; - + if (NULL == pg) + return; if (NULL != pg->conn) GNUNET_PQ_disconnect (pg->conn); GNUNET_free (pg->currency); GNUNET_free (pg); - GNUNET_free (plugin); - return NULL; } diff --git a/src/auditordb/select_early_aggregations.c b/src/auditordb/select_early_aggregations.c @@ -0,0 +1,171 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/select_early_aggregations.c + * @brief Implementation of the select_early_aggregations function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_early_aggregations.h" +#include "pg_helper.h" + + +/** + * Closure for #early_aggregation_cb(). + */ +struct EarlyAggregationContext +{ + + /** + * Function to call for each early aggregation. + */ + TALER_AUDITORDB_EarlyAggregationsCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_select_purse_expired(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct EarlyAggregationContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +early_aggregation_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct EarlyAggregationContext *eic = cls; + struct AUDITORDB_PostgresContext *ctx = eic->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_AUDITORDB_EarlyAggregation ea; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &ea.row_id), + GNUNET_PQ_result_spec_uint64 ("batch_deposit_serial_id", + &ea.batch_deposit_serial_id), + GNUNET_PQ_result_spec_uint64 ("tracking_serial_id", + &ea.tracking_serial_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &ea.total), + GNUNET_PQ_result_spec_bool ("suppressed", + &ea.suppressed), + GNUNET_PQ_result_spec_end + }; + + /* just to be safe in case the structure changes */ + memset (&ea, + 0, + sizeof (ea)); + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + eic->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + eic->cb (eic->cb_cls, + &ea); + } + eic->qs = num_results; +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_select_early_aggregations (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_EarlyAggregationsCallback cb, + void *cb_cls) +{ + uint64_t ulimit = (limit < 0) ? -limit : limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_end + }; + struct EarlyAggregationContext eic = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_select_early_aggregations_asc", + "SELECT" + " row_id" + ",batch_deposit_serial_id" + ",tracking_serial_id" + ",amount" + ",suppressed" + " FROM auditor_early_aggregations" + " WHERE row_id > $1" + " AND ($3 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $2;"); + PREPARE (ctx, + "auditor_select_early_aggregations_desc", + "SELECT" + " row_id" + ",batch_deposit_serial_id" + ",tracking_serial_id" + ",amount" + ",suppressed" + " FROM auditor_early_aggregations" + " WHERE row_id < $1" + " AND ($3 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $2;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit < 0) + ? "auditor_select_early_aggregations_desc" + : "auditor_select_early_aggregations_asc ", + params, + &early_aggregation_cb, + &eic); + if (0 > qs) + return qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != eic.qs); + return eic.qs; +} diff --git a/src/auditordb/select_historic_denom_revenue.c b/src/auditordb/select_historic_denom_revenue.c @@ -0,0 +1,172 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_historic_denom_revenue.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_historic_denom_revenue.h" +#include "pg_helper.h" + + +/** + * Closure for #historic_denom_revenue_cb(). + */ +struct HistoricDenomRevenueContext +{ + /** + * Function to call for each result. + */ + TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Number of results processed. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_select_historic_denom_revenue(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct HistoricRevenueContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +historic_denom_revenue_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct HistoricDenomRevenueContext *hrc = cls; + struct AUDITORDB_PostgresContext *ctx = hrc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t rowid; + struct TALER_DenominationHashP denom_pub_hash; + struct GNUNET_TIME_Timestamp revenue_timestamp; + struct TALER_Amount revenue_balance; + struct TALER_Amount loss; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &rowid), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &denom_pub_hash), + GNUNET_PQ_result_spec_timestamp ("revenue_timestamp", + &revenue_timestamp), + TALER_PQ_RESULT_SPEC_AMOUNT ("revenue_balance", + &revenue_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("loss_balance", + &loss), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + hrc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + + hrc->qs = i + 1; + if (GNUNET_OK != + hrc->cb (hrc->cb_cls, + rowid, + &denom_pub_hash, + revenue_timestamp, + &revenue_balance, + &loss)) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_select_historic_denom_revenue (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb, + void *cb_cls) +{ + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_end + }; + struct HistoricDenomRevenueContext hrc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_historic_denomination_revenue_select_inc", + "SELECT" + " row_id" + ",denom_pub_hash" + ",revenue_timestamp" + ",revenue_balance" + ",loss_balance" + " FROM auditor_historic_denomination_revenue" + " WHERE row_id > $1" + " ORDER BY row_id ASC" + " LIMIT $2;"); + PREPARE (ctx, + "auditor_historic_denomination_revenue_select_dec", + "SELECT" + " row_id" + ",denom_pub_hash" + ",revenue_timestamp" + ",revenue_balance" + ",loss_balance" + " FROM auditor_historic_denomination_revenue" + " WHERE row_id < $1" + " ORDER BY row_id DESC" + " LIMIT $2;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + limit > 0 + ? "auditor_historic_denomination_revenue_select_inc" + : "auditor_historic_denomination_revenue_select_dec", + params, + &historic_denom_revenue_cb, + &hrc); + if (qs <= 0) + return qs; + return hrc.qs; +} diff --git a/src/auditordb/select_historic_reserve_revenue.c b/src/auditordb/select_historic_reserve_revenue.c @@ -0,0 +1,165 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_historic_reserve_revenue.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_historic_reserve_revenue.h" +#include "pg_helper.h" + + +/** + * Closure for #historic_reserve_revenue_cb(). + */ +struct HistoricReserveRevenueContext +{ + /** + * Function to call for each result. + */ + TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Number of results processed. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_select_historic_reserve_revenue(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct HistoricRevenueContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +historic_reserve_revenue_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct HistoricReserveRevenueContext *hrc = cls; + struct AUDITORDB_PostgresContext *ctx = hrc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t rowid; + struct GNUNET_TIME_Timestamp start_date; + struct GNUNET_TIME_Timestamp end_date; + struct TALER_Amount reserve_profits; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &rowid), + GNUNET_PQ_result_spec_timestamp ("start_date", + &start_date), + GNUNET_PQ_result_spec_timestamp ("end_date", + &end_date), + TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_profits", + &reserve_profits), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + hrc->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + hrc->qs = i + 1; + if (GNUNET_OK != + hrc->cb (hrc->cb_cls, + rowid, + start_date, + end_date, + &reserve_profits)) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_select_historic_reserve_revenue (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb, + void *cb_cls) +{ + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + struct HistoricReserveRevenueContext hrc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + + PREPARE (ctx, + "auditor_historic_reserve_summary_select_inc", + "SELECT" + " row_id" + ",start_date" + ",end_date" + ",reserve_profits" + " FROM auditor_historic_reserve_summary" + " WHERE row_id > $1" + " ORDER BY row_id ASC" + " LIMIT $2"); + PREPARE (ctx, + "auditor_historic_reserve_summary_select_dec", + "SELECT" + " row_id" + ",start_date" + ",end_date" + ",reserve_profits" + " FROM auditor_historic_reserve_summary" + " WHERE row_id < $1" + " ORDER BY row_id DESC" + " LIMIT $2"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + limit > 0 + ? "auditor_historic_reserve_summary_select_inc" + : "auditor_historic_reserve_summary_select_dec", + params, + &historic_reserve_revenue_cb, + &hrc); + if (0 >= qs) + return qs; + return hrc.qs; +} diff --git a/src/auditordb/select_pending_deposits.c b/src/auditordb/select_pending_deposits.c @@ -0,0 +1,183 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/select_pending_deposits.c + * @brief Implementation of the select_pending_deposits function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_pending_deposits.h" +#include "pg_helper.h" + + +/** + * Closure for #wire_missing_cb(). + */ +struct WireMissingContext +{ + + /** + * Function to call for each pending deposit. + */ + TALER_AUDITORDB_WireMissingCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_select_purse_expired(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct WireMissingContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +wire_missing_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct WireMissingContext *eic = cls; + struct AUDITORDB_PostgresContext *ctx = eic->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t row_id; + uint64_t batch_deposit_serial_id; + struct TALER_Amount total_amount; + struct TALER_FullPaytoHashP wire_target_h_payto; + struct GNUNET_TIME_Timestamp deadline; + bool suppressed; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &row_id), + GNUNET_PQ_result_spec_uint64 ("batch_deposit_serial_id", + &batch_deposit_serial_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("total_amount", + &total_amount), + GNUNET_PQ_result_spec_auto_from_type ("wire_target_h_payto", + &wire_target_h_payto), + GNUNET_PQ_result_spec_timestamp ("deadline", + &deadline), + GNUNET_PQ_result_spec_bool ("suppressed", + &suppressed), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + eic->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + eic->cb (eic->cb_cls, + row_id, + batch_deposit_serial_id, + &total_amount, + &wire_target_h_payto, + deadline, + suppressed); + } + eic->qs = num_results; +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_select_pending_deposits (struct AUDITORDB_PostgresContext *ctx, + struct GNUNET_TIME_Absolute deadline, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_WireMissingCallback cb, + void *cb_cls) +{ + uint64_t ulimit = (limit < 0) ? -limit : limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&deadline), + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_bool (return_suppressed), + GNUNET_PQ_query_param_end + }; + struct WireMissingContext eic = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_select_pending_deposits_asc", + "SELECT" + " row_id" + ",total_amount" + ",wire_target_h_payto" + ",batch_deposit_serial_id" + ",deadline" + ",suppressed" + " FROM auditor_pending_deposits" + " WHERE deadline<$1" + " AND (row_id > $2)" + " AND ($4 OR NOT suppressed)" + " ORDER BY row_id ASC" + " LIMIT $3;"); + PREPARE (ctx, + "auditor_select_pending_deposits_desc", + "SELECT" + " row_id" + ",total_amount" + ",wire_target_h_payto" + ",batch_deposit_serial_id" + ",deadline" + ",suppressed" + " FROM auditor_pending_deposits" + " WHERE deadline<$1" + " AND (row_id < $2)" + " AND ($4 OR NOT suppressed)" + " ORDER BY row_id DESC" + " LIMIT $3;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "auditor_select_pending_deposits", + params, + &wire_missing_cb, + &eic); + if (0 > qs) + return qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != eic.qs); + return eic.qs; +} diff --git a/src/auditordb/select_purse_expired.c b/src/auditordb/select_purse_expired.c @@ -0,0 +1,144 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/select_purse_expired.c + * @brief Implementation of the select_purse_expired function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse_expired.h" +#include "pg_helper.h" + + +/** + * Closure for #purse_expired_cb(). + */ +struct PurseExpiredContext +{ + + /** + * Function to call for each expired purse. + */ + TALER_AUDITORDB_ExpiredPurseCallback cb; + + /** + * Closure for @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct AUDITORDB_PostgresContext *ctx; + + /** + * Query status to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #AUDITORDB_select_purse_expired(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct PurseExpiredContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +purse_expired_cb (struct AUDITORDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PurseExpiredContext *eic = cls; + struct AUDITORDB_PostgresContext *ctx = eic->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_PurseContractPublicKeyP purse_pub; + struct GNUNET_TIME_Timestamp expiration_date; + struct TALER_Amount balance; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &purse_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + &balance), + GNUNET_PQ_result_spec_timestamp ("expiration_date", + &expiration_date), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + eic->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + eic->qs = i + 1; + if (GNUNET_OK != + eic->cb (eic->cb_cls, + &purse_pub, + &balance, + expiration_date)) + break; + } +} + + +enum GNUNET_DB_QueryStatus +AUDITORDB_select_purse_expired (struct AUDITORDB_PostgresContext *ctx, + TALER_AUDITORDB_ExpiredPurseCallback cb, + void *cb_cls) +{ + struct GNUNET_TIME_Timestamp now + = GNUNET_TIME_timestamp_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_end + }; + struct PurseExpiredContext eic = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "auditor_select_expired_purses", + "SELECT" + " purse_pub" + ",expiration_date" + ",balance" + " FROM auditor_purses" + " WHERE expiration_date<$1;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "auditor_select_expired_purses", + params, + &purse_expired_cb, + &eic); + if (qs > 0) + return eic.qs; + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + return qs; +} diff --git a/src/auditordb/select_reserve_in_inconsistency.c b/src/auditordb/select_reserve_in_inconsistency.c @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/select_reserve_in_inconsistency.c + * @brief Implementation of the select_reserve_in_inconsistency function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_reserve_in_inconsistency.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_select_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + uint64_t bank_row_id, + struct TALER_AUDITORDB_ReserveInInconsistency *dc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&bank_row_id), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("row_id", + &dc->serial_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_exchange_expected", + &dc->amount_exchange_expected), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_wired", + &dc->amount_wired), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &dc->reserve_pub), + GNUNET_PQ_result_spec_absolute_time ("timestamp", + &dc->timestamp), + GNUNET_PQ_result_spec_string ("account", + &dc->account.full_payto), + GNUNET_PQ_result_spec_string ("diagnostic", + &dc->diagnostic), + GNUNET_PQ_result_spec_bool ("suppressed", + &dc->suppressed), + GNUNET_PQ_result_spec_end + }; + + dc->bank_row_id = bank_row_id; + PREPARE (ctx, + "select_reserve_in_inconsistency", + "SELECT" + " row_id" + ",amount_exchange_expected" + ",amount_wired" + ",reserve_pub" + ",timestamp" + ",account" + ",diagnostic" + ",suppressed" + " FROM auditor_reserve_in_inconsistency" + " WHERE (bank_row_id = $1)" + ); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "select_reserve_in_inconsistency", + params, + rs); +} diff --git a/src/auditordb/template.c b/src/auditordb/template.c @@ -0,0 +1,26 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/template.c + * @brief Implementation of the template function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "template.h" +#include "pg_helper.h" diff --git a/src/auditordb/update_auditor_progress.c b/src/auditordb/update_auditor_progress.c @@ -0,0 +1,97 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_auditor_progress.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_auditor_progress.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_update_auditor_progress (struct AUDITORDB_PostgresContext *ctx, + const char *progress_key, + uint64_t progress_offset, + ...) +{ + unsigned int cnt = 1; + va_list ap; + + va_start (ap, + progress_offset); + while (NULL != va_arg (ap, + const char *)) + { + cnt++; + (void) va_arg (ap, + uint64_t); + } + va_end (ap); + { + const char *keys[cnt]; + uint64_t offsets[cnt]; + unsigned int off = 1; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_array_ptrs_string (cnt, + keys, + ctx->conn), + GNUNET_PQ_query_param_array_uint64 (cnt, + offsets, + ctx->conn), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + keys[0] = progress_key; + offsets[0] = progress_offset; + + va_start (ap, + progress_offset); + while (off < cnt) + { + keys[off] = va_arg (ap, + const char *); + offsets[off] = va_arg (ap, + uint64_t); + off++; + } + GNUNET_assert (NULL == va_arg (ap, + const char *)); + va_end (ap); + + PREPARE (ctx, + "auditor_progress_update", + "UPDATE auditor_progress" + " SET progress_offset=data.off" + " FROM (" + " SELECT *" + " FROM UNNEST (CAST($1 AS TEXT[])," + " CAST($2 AS INT8[]))" + " AS t(key,off)" + " ) AS data" + " WHERE auditor_progress.progress_key=data.key;"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_progress_update", + params); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; + } +} diff --git a/src/auditordb/update_balance.c b/src/auditordb/update_balance.c @@ -0,0 +1,98 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/update_balance.c + * @brief Implementation of the update_balance function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_balance.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_update_balance (struct AUDITORDB_PostgresContext *ctx, + const char *balance_key, + const struct TALER_Amount *balance_amount, + ...) +{ + unsigned int cnt = 1; + va_list ap; + + va_start (ap, + balance_amount); + while (NULL != va_arg (ap, + const char *)) + { + cnt++; + (void) va_arg (ap, + const struct TALER_Amount *); + } + va_end (ap); + { + const char *keys[cnt]; + struct TALER_Amount amounts[cnt]; + unsigned int off = 1; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_array_ptrs_string (cnt, + keys, + ctx->conn), + TALER_PQ_query_param_array_amount (cnt, + amounts, + ctx->conn), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + keys[0] = balance_key; + amounts[0] = *balance_amount; + + va_start (ap, + balance_amount); + while (off < cnt) + { + keys[off] = va_arg (ap, + const char *); + amounts[off] = *va_arg (ap, + const struct TALER_Amount *); + off++; + } + GNUNET_assert (NULL == va_arg (ap, + const char *)); + va_end (ap); + + PREPARE (ctx, + "auditor_balance_update", + "UPDATE auditor_balances" + " SET balance_value.val=data.val" + " ,balance_value.frac=data.frac" + " FROM (" + " SELECT *" + " FROM UNNEST (CAST($1 AS TEXT[])," + " CAST($2 AS taler_amount[]))" + " AS t(key,val,frac)" + " ) AS data" + " WHERE auditor_balances.balance_key=data.key;"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_balance_update", + params); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; + } +} diff --git a/src/auditordb/update_denomination_balance.c b/src/auditordb/update_denomination_balance.c @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_denomination_balance.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_denomination_balance.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_update_denomination_balance (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + const struct TALER_AUDITORDB_DenominationCirculationData *dcd) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + &dcd->denom_balance), + TALER_PQ_query_param_amount (ctx->conn, + &dcd->denom_loss), + GNUNET_PQ_query_param_uint64 (&dcd->num_issued), + TALER_PQ_query_param_amount (ctx->conn, + &dcd->denom_risk), + TALER_PQ_query_param_amount (ctx->conn, + &dcd->recoup_loss), + GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_denomination_pending_update", + "UPDATE auditor_denomination_pending SET" + " denom_balance=$1" + ",denom_loss=$2" + ",num_issued=$3" + ",denom_risk=$4" + ",recoup_loss=$5" + " WHERE denom_pub_hash=$6"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_denomination_pending_update", + params); +} diff --git a/src/auditordb/update_generic_suppressed.c b/src/auditordb/update_generic_suppressed.c @@ -0,0 +1,87 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#include "taler/platform.h" +#include "taler/taler_pq_lib.h" +#include "pg_helper.h" +#include "update_generic_suppressed.h" + +struct Preparations +{ + /** + * Database reconnect counter. + */ + unsigned long long cnt; + + /** + * Which DB did we do prepare for. + */ + struct AUDITORDB_PostgresContext *ctx; + +}; + + +enum GNUNET_DB_QueryStatus +AUDITORDB_update_generic_suppressed (struct AUDITORDB_PostgresContext *ctx, + enum TALER_AUDITORDB_DeletableSuppressableTables table, + uint64_t row_id, + bool suppressed) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&row_id), + GNUNET_PQ_query_param_bool (suppressed), + GNUNET_PQ_query_param_end + }; + static struct Preparations preps[ + TALER_AUDITORDB_DELETABLESUPPRESSABLE_TABLES_MAX]; + + struct Preparations *prep = &preps[table]; + const char *table_name = AUDITORDB_get_deletable_suppressable_table_name (table); + char statement_name[256]; + + GNUNET_snprintf (statement_name, + sizeof (statement_name), + "update_%s", + table_name); + if ( (ctx != prep->ctx) || + (prep->cnt < ctx->prep_gen) ) + { + char sql[256]; + struct GNUNET_PQ_PreparedStatement ps[] = { + GNUNET_PQ_make_prepare (statement_name, + sql), + GNUNET_PQ_PREPARED_STATEMENT_END + }; + + GNUNET_snprintf (sql, + sizeof (sql), + "UPDATE %s SET" + " suppressed=$2" + " WHERE row_id=$1", + table_name); + if (GNUNET_OK != + GNUNET_PQ_prepare_statements (ctx->conn, + ps)) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + prep->ctx = ctx; + prep->cnt = ctx->prep_gen; + } + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + statement_name, + params); +} diff --git a/src/auditordb/update_purse_info.c b/src/auditordb/update_purse_info.c @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/auditordb/update_purse_info.c + * @brief Implementation of the update_purse_info function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_purse_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_update_purse_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_Amount *balance) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + TALER_PQ_query_param_amount (ctx->conn, + balance), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_purses_update", + "UPDATE auditor_purses" + " SET balance=$2" + " WHERE purse_pub=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_purses_update", + params); +} diff --git a/src/auditordb/update_reserve_info.c b/src/auditordb/update_reserve_info.c @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_reserve_info.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_reserve_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_update_reserve_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_AUDITORDB_ReserveFeeBalance *rfb, + struct GNUNET_TIME_Timestamp expiration_date) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + &rfb->reserve_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->reserve_loss), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->withdraw_fee_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->purse_fee_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->open_fee_balance), + TALER_PQ_query_param_amount (ctx->conn, + &rfb->history_fee_balance), + GNUNET_PQ_query_param_timestamp (&expiration_date), + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_update_reserve_info", + "UPDATE auditor_reserves SET" + " reserve_balance=$1" + ",reserve_loss=$2" + ",withdraw_fee_balance=$3" + ",purse_fee_balance=$4" + ",open_fee_balance=$5" + ",history_fee_balance=$6" + ",expiration_date=$7" + " WHERE reserve_pub=$8"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_update_reserve_info", + params); +} diff --git a/src/auditordb/update_wire_fee_summary.c b/src/auditordb/update_wire_fee_summary.c @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_wire_fee_summary.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_wire_fee_summary.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +AUDITORDB_update_wire_fee_summary (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_Amount *wire_fee_balance) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + wire_fee_balance), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "auditor_wire_fee_balance_update", + "UPDATE auditor_wire_fee_balance SET" + " wire_fee_balance=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "auditor_wire_fee_balance_update", + params); +} diff --git a/src/exchangedb/abort_shard.c b/src/exchangedb/abort_shard.c @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/abort_shard.c + * @brief Implementation of the abort_shard function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "abort_shard.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_abort_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + uint64_t start_row, + uint64_t end_row) +{ + 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 + }; + + PREPARE (ctx, + "abort_shard", + "UPDATE work_shards" + " SET last_attempt=0" + " WHERE job_name=$1" + " AND start_row=$2" + " AND end_row=$3;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "abort_shard", + params); +} diff --git a/src/exchangedb/activate_signing_key.c b/src/exchangedb/activate_signing_key.c @@ -0,0 +1,56 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/activate_signing_key.c + * @brief Implementation of the activate_signing_key function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "activate_signing_key.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_activate_signing_key (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_EXCHANGEDB_SignkeyMetaData *meta, + const struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam iparams[] = { + GNUNET_PQ_query_param_auto_from_type (exchange_pub), + GNUNET_PQ_query_param_timestamp (&meta->start), + GNUNET_PQ_query_param_timestamp (&meta->expire_sign), + GNUNET_PQ_query_param_timestamp (&meta->expire_legal), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_signkey", + "INSERT INTO exchange_sign_keys " + "(exchange_pub" + ",valid_from" + ",expire_sign" + ",expire_legal" + ",master_sig" + ") VALUES " + "($1, $2, $3, $4, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_signkey", + iparams); +} diff --git a/src/exchangedb/add_denomination_key.c b/src/exchangedb/add_denomination_key.c @@ -0,0 +1,84 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/add_denomination_key.c + * @brief Implementation of the add_denomination_key function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "add_denomination_key.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_add_denomination_key (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta, + const struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam iparams[] = { + GNUNET_PQ_query_param_auto_from_type (h_denom_pub), + TALER_PQ_query_param_denom_pub (denom_pub), + GNUNET_PQ_query_param_auto_from_type (master_sig), + 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), + TALER_PQ_query_param_amount (ctx->conn, + &meta->value), + TALER_PQ_query_param_amount (ctx->conn, + &meta->fees.withdraw), + TALER_PQ_query_param_amount (ctx->conn, + &meta->fees.deposit), + TALER_PQ_query_param_amount (ctx->conn, + &meta->fees.refresh), + TALER_PQ_query_param_amount (ctx->conn, + &meta->fees.refund), + GNUNET_PQ_query_param_uint32 (&meta->age_mask.bits), + GNUNET_PQ_query_param_end + }; + + /* Sanity check: ensure fees match coin currency */ + GNUNET_assert (GNUNET_YES == + TALER_denom_fee_check_currency (meta->value.currency, + &meta->fees)); + PREPARE (ctx, + "denomination_insert", + "INSERT INTO denominations " + "(denom_pub_hash" + ",denom_pub" + ",master_sig" + ",valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" /* value of this denom */ + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ",age_mask" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," + " $11, $12, $13);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "denomination_insert", + iparams); +} diff --git a/src/exchangedb/add_policy_fulfillment_proof.c b/src/exchangedb/add_policy_fulfillment_proof.c @@ -0,0 +1,157 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/add_policy_fulfillment_proof.c + * @brief Implementation of the add_policy_fulfillment_proof function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "add_policy_fulfillment_proof.h" +#include "pg_helper.h" + + +/** + * 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); +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_add_policy_fulfillment_proof (struct EXCHANGEDB_PostgresContext *ctx, + struct TALER_PolicyFulfillmentTransactionData *fulfillment) +{ + enum GNUNET_DB_QueryStatus qs; + size_t count = fulfillment->details_count; + /* FIXME[Oec]: this seems to be prone to VLA attacks */ + struct GNUNET_HashCode hcs[GNUNET_NZL (count)]; + + /* Create the sorted policy_hash_codes */ + { + size_t idx[GNUNET_NZL (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), + TALER_PQ_query_param_array_hash_code (count, hcs, ctx->conn), + 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 + }; + + PREPARE (ctx, + "insert_proof_into_policy_fulfillments", + "INSERT INTO policy_fulfillments" + "(fulfillment_timestamp" + ",fulfillment_proof" + ",h_fulfillment_proof" + ",policy_hash_codes" + ") VALUES ($1, $2::TEXT::JSON, $3, $4)" + " ON CONFLICT DO NOTHING;"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->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 (ctx->conn, + &pos->commitment), + TALER_PQ_query_param_amount (ctx->conn, + &pos->accumulated_total), + TALER_PQ_query_param_amount (ctx->conn, + &pos->policy_fee), + TALER_PQ_query_param_amount (ctx->conn, + &pos->transferable_amount), + GNUNET_PQ_query_param_auto_from_type (&pos->fulfillment_state), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "update_policy_details", + "UPDATE policy_details SET" + " deadline=$2" + ",commitment=$3" + ",accumulated_total=$4" + ",fee=$5" + ",transferable=$6" + ",fulfillment_state=$7" + " WHERE policy_hash_code=$1;"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "update_policy_details", + params); + if (qs < 0) + return qs; + } + } + + /* + * FIXME[oec]-#7999: When all policies of a deposit are fulfilled, + * unblock it and trigger a wire-transfer. + */ + + return qs; +} diff --git a/src/exchangedb/aggregate.c b/src/exchangedb/aggregate.c @@ -0,0 +1,203 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/aggregate.c + * @brief Implementation of the aggregate function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_compute_shard.h" +#include "pg_event_notify.h" +#include "aggregate.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_aggregate (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_Amount *total) +{ + uint64_t deposit_shard = EXCHANGEDB_compute_shard (merchant_pub); + struct GNUNET_TIME_Absolute now = {0}; + 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; + 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 (), + ctx->aggregator_shift); + PREPARE (ctx, + "aggregate", + "WITH bdep AS (" /* restrict to our merchant and account and mark as done */ + " UPDATE batch_deposits" + " SET done=TRUE" + " WHERE NOT (done OR policy_blocked)" /* only actually executable deposits */ + " AND refund_deadline<$1" + " AND shard=$5" /* only for efficiency, merchant_pub is what we really filter by */ + " AND merchant_pub=$2" /* filter by target merchant */ + " AND wire_target_h_payto=$3" /* merchant could have a 2nd bank account */ + " RETURNING" + " batch_deposit_serial_id)" + " ,cdep AS (" + " SELECT" + " coin_deposit_serial_id" + " ,batch_deposit_serial_id" + " ,coin_pub" + " ,amount_with_fee AS amount" + " FROM coin_deposits" + " WHERE batch_deposit_serial_id IN (SELECT batch_deposit_serial_id FROM bdep))" + " ,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? */ + " SELECT" + " amount_with_fee AS refund" + " ,coin_pub" + " ,batch_deposit_serial_id" /* theoretically, coin could be in multiple refunded transactions */ + " FROM refunds" + " WHERE coin_pub IN (SELECT coin_pub FROM cdep)" + " AND batch_deposit_serial_id IN (SELECT batch_deposit_serial_id FROM bdep))" + " ,ref_by_coin AS (" /* total up refunds by coin */ + " SELECT" + " SUM((ref.refund).val) AS sum_refund_val" + " ,SUM((ref.refund).frac) AS sum_refund_frac" + " ,coin_pub" + " ,batch_deposit_serial_id" /* theoretically, coin could be in multiple refunded transactions */ + " FROM ref" + " GROUP BY coin_pub, batch_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" + " ,batch_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" + " cdep.coin_pub" + " FROM norm_ref_by_coin norm" + " JOIN cdep" + " ON (norm.coin_pub = cdep.coin_pub" + " AND norm.batch_deposit_serial_id = cdep.batch_deposit_serial_id" + " AND norm.norm_refund_val = (cdep.amount).val" + " AND norm.norm_refund_frac = (cdep.amount).frac))" + " ,fees AS (" /* find deposit fees for not fully refunded deposits */ + " SELECT" + " denom.fee_deposit AS fee" + " ,cs.batch_deposit_serial_id" /* ensures we get the fee for each coin, not once per denomination */ + " FROM cdep cs" + " 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? */ + " USING (coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " WHERE coin_pub NOT IN (SELECT coin_pub FROM fully_refunded_coins))" + " ,dummy AS (" /* add deposits to aggregation_tracking */ + " INSERT INTO aggregation_tracking" + " (batch_deposit_serial_id" + " ,wtid_raw)" + " SELECT batch_deposit_serial_id,$4" + " FROM bdep)" + "SELECT" /* calculate totals (deposits, refunds and fees) */ + " CAST(COALESCE(SUM((cdep.amount).val),0) AS INT8) AS sum_deposit_value" + /* cast needed, otherwise we get NUMBER */ + " ,COALESCE(SUM((cdep.amount).frac),0) AS sum_deposit_fraction" /* SUM over INT returns INT8 */ + " ,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 cdep " + " FULL OUTER JOIN ref ON (FALSE)" /* We just want all sums */ + " FULL OUTER JOIN fees ON (FALSE);"); + + { + 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_uint64 (&deposit_shard), + GNUNET_PQ_query_param_end + }; + 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 + }; + + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "aggregate", + params, + rs); + } + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return qs; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + total)); + return qs; + } + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + &sum_deposit)); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + &sum_refund)); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->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; +} diff --git a/src/exchangedb/batch_ensure_coin_known.c b/src/exchangedb/batch_ensure_coin_known.c @@ -0,0 +1,459 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/batch_ensure_coin_known.c + * @brief Implementation of the batch_ensure_coin_known function for Postgres + * @author Christian Grothoff + * + * FIXME-#9373: use the array support for postgres to simplify this code! + * + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_exchangedb_plugin.h" +#include "taler/taler_pq_lib.h" +#include "batch_ensure_coin_known.h" +#include "pg_helper.h" + + +static enum GNUNET_DB_QueryStatus +insert1 (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo coin[1], + struct TALER_EXCHANGEDB_CoinInfo result[1]) +{ + enum GNUNET_DB_QueryStatus qs; + bool is_denom_pub_hash_null = false; + bool is_age_hash_null = false; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash), + GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment), + TALER_PQ_query_param_denom_sig (&coin[0].denom_sig), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("existed", + &result[0].existed), + GNUNET_PQ_result_spec_uint64 ("known_coin_id", + &result[0].known_coin_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &result[0].denom_hash), + &is_denom_pub_hash_null), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &result[0].h_age_commitment), + &is_age_hash_null), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "batch1_known_coin", + "SELECT" + " existed1 AS existed" + ",known_coin_id1 AS known_coin_id" + ",denom_pub_hash1 AS denom_hash" + ",age_commitment_hash1 AS h_age_commitment" + " FROM exchange_do_batch1_known_coin" + " ($1, $2, $3, $4);" + ); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "batch1_known_coin", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + return qs; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); /* should be impossible */ + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; /* continued below */ + } + + if ( (! is_denom_pub_hash_null) && + (0 != GNUNET_memcmp (&result[0].denom_hash, + &coin->denom_pub_hash)) ) + { + GNUNET_break_op (0); + result[0].denom_conflict = true; + } + + if ( (! is_denom_pub_hash_null) && + (0 != GNUNET_memcmp (&result[0].denom_hash, + &coin[0].denom_pub_hash)) ) + { + GNUNET_break_op (0); + result[0].denom_conflict = true; + } + + result[0].age_conflict = TALER_AgeCommitmentHashP_NoConflict; + + if (is_age_hash_null != coin[0].no_age_commitment) + { + if (is_age_hash_null) + { + GNUNET_break_op (0); + result[0].age_conflict = TALER_AgeCommitmentHashP_NullExpected; + } + else + { + GNUNET_break_op (0); + result[0].age_conflict = TALER_AgeCommitmentHashP_ValueExpected; + } + } + else if ( (! is_age_hash_null) && + (0 != GNUNET_memcmp (&result[0].h_age_commitment, + &coin[0].h_age_commitment)) ) + { + GNUNET_break_op (0); + result[0].age_conflict = TALER_AgeCommitmentHashP_ValueDiffers; + } + + return qs; +} + + +static enum GNUNET_DB_QueryStatus +insert2 (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo coin[2], + struct TALER_EXCHANGEDB_CoinInfo result[2]) +{ + enum GNUNET_DB_QueryStatus qs; + bool is_denom_pub_hash_null[2] = {false, false}; + bool is_age_hash_null[2] = {false, false}; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash), + GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment), + TALER_PQ_query_param_denom_sig (&coin[0].denom_sig), + + GNUNET_PQ_query_param_auto_from_type (&coin[1].coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin[1].denom_pub_hash), + GNUNET_PQ_query_param_auto_from_type (&coin[1].h_age_commitment), + TALER_PQ_query_param_denom_sig (&coin[0].denom_sig), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("existed", + &result[0].existed), + GNUNET_PQ_result_spec_uint64 ("known_coin_id", + &result[0].known_coin_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &result[0].denom_hash), + &is_denom_pub_hash_null[0]), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &result[0].h_age_commitment), + &is_age_hash_null[0]), + GNUNET_PQ_result_spec_bool ("existed2", + &result[1].existed), + GNUNET_PQ_result_spec_uint64 ("known_coin_id2", + &result[1].known_coin_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash2", + &result[1].denom_hash), + &is_denom_pub_hash_null[1]), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash2", + &result[1].h_age_commitment), + &is_age_hash_null[1]), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "batch2_known_coin", + "SELECT" + " existed1 AS existed" + ",known_coin_id1 AS known_coin_id" + ",denom_pub_hash1 AS denom_hash" + ",age_commitment_hash1 AS h_age_commitment" + ",existed2 AS existed2" + ",known_coin_id2 AS known_coin_id2" + ",denom_pub_hash2 AS denom_hash2" + ",age_commitment_hash2 AS h_age_commitment2" + " FROM exchange_do_batch2_known_coin" + " ($1, $2, $3, $4, $5, $6, $7, $8);" + ); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "batch2_known_coin", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + return qs; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); /* should be impossible */ + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; /* continued below */ + } + + for (int i = 0; i < 2; i++) + { + if ( (! is_denom_pub_hash_null[i]) && + (0 != GNUNET_memcmp (&result[i].denom_hash, + &coin[i].denom_pub_hash)) ) + { + GNUNET_break_op (0); + result[i].denom_conflict = true; + } + + result[i].age_conflict = TALER_AgeCommitmentHashP_NoConflict; + + if (is_age_hash_null[i] != coin[i].no_age_commitment) + { + if (is_age_hash_null[i]) + { + GNUNET_break_op (0); + result[i].age_conflict = TALER_AgeCommitmentHashP_NullExpected; + } + else + { + GNUNET_break_op (0); + result[i].age_conflict = TALER_AgeCommitmentHashP_ValueExpected; + } + } + else if ( (! is_age_hash_null[i]) && + (0 != GNUNET_memcmp (&result[i].h_age_commitment, + &coin[i].h_age_commitment)) ) + { + GNUNET_break_op (0); + result[i].age_conflict = TALER_AgeCommitmentHashP_ValueDiffers; + } + } + + return qs; +} + + +static enum GNUNET_DB_QueryStatus +insert4 (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo coin[4], + struct TALER_EXCHANGEDB_CoinInfo result[4]) +{ + enum GNUNET_DB_QueryStatus qs; + bool is_denom_pub_hash_null[4] = {false, false, false, false}; + bool is_age_hash_null[4] = {false, false, false, false}; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&coin[0].coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin[0].denom_pub_hash), + GNUNET_PQ_query_param_auto_from_type (&coin[0].h_age_commitment), + TALER_PQ_query_param_denom_sig (&coin[0].denom_sig), + + GNUNET_PQ_query_param_auto_from_type (&coin[1].coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin[1].denom_pub_hash), + GNUNET_PQ_query_param_auto_from_type (&coin[1].h_age_commitment), + TALER_PQ_query_param_denom_sig (&coin[0].denom_sig), + + GNUNET_PQ_query_param_auto_from_type (&coin[2].coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin[2].denom_pub_hash), + GNUNET_PQ_query_param_auto_from_type (&coin[2].h_age_commitment), + TALER_PQ_query_param_denom_sig (&coin[2].denom_sig), + + GNUNET_PQ_query_param_auto_from_type (&coin[3].coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin[3].denom_pub_hash), + GNUNET_PQ_query_param_auto_from_type (&coin[3].h_age_commitment), + TALER_PQ_query_param_denom_sig (&coin[3].denom_sig), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("existed", + &result[0].existed), + GNUNET_PQ_result_spec_uint64 ("known_coin_id", + &result[0].known_coin_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &result[0].denom_hash), + &is_denom_pub_hash_null[0]), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &result[0].h_age_commitment), + &is_age_hash_null[0]), + GNUNET_PQ_result_spec_bool ("existed2", + &result[1].existed), + GNUNET_PQ_result_spec_uint64 ("known_coin_id2", + &result[1].known_coin_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash2", + &result[1].denom_hash), + &is_denom_pub_hash_null[1]), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash2", + &result[1].h_age_commitment), + &is_age_hash_null[1]), + GNUNET_PQ_result_spec_bool ("existed3", + &result[2].existed), + GNUNET_PQ_result_spec_uint64 ("known_coin_id3", + &result[2].known_coin_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash3", + &result[2].denom_hash), + &is_denom_pub_hash_null[2]), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash3", + &result[2].h_age_commitment), + &is_age_hash_null[2]), + GNUNET_PQ_result_spec_bool ("existed4", + &result[3].existed), + GNUNET_PQ_result_spec_uint64 ("known_coin_id4", + &result[3].known_coin_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash4", + &result[3].denom_hash), + &is_denom_pub_hash_null[3]), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash4", + &result[3].h_age_commitment), + &is_age_hash_null[3]), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "batch4_known_coin", + "SELECT" + " existed1 AS existed" + ",known_coin_id1 AS known_coin_id" + ",denom_pub_hash1 AS denom_hash" + ",age_commitment_hash1 AS h_age_commitment" + ",existed2 AS existed2" + ",known_coin_id2 AS known_coin_id2" + ",denom_pub_hash2 AS denom_hash2" + ",age_commitment_hash2 AS h_age_commitment2" + ",existed3 AS existed3" + ",known_coin_id3 AS known_coin_id3" + ",denom_pub_hash3 AS denom_hash3" + ",age_commitment_hash3 AS h_age_commitment3" + ",existed4 AS existed4" + ",known_coin_id4 AS known_coin_id4" + ",denom_pub_hash4 AS denom_hash4" + ",age_commitment_hash4 AS h_age_commitment4" + " FROM exchange_do_batch2_known_coin" + " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);" + ); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "batch4_known_coin", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + return qs; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); /* should be impossible */ + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; /* continued below */ + } + + for (int i = 0; i < 4; i++) + { + if ( (! is_denom_pub_hash_null[i]) && + (0 != GNUNET_memcmp (&result[i].denom_hash, + &coin[i].denom_pub_hash)) ) + { + GNUNET_break_op (0); + result[i].denom_conflict = true; + } + + result[i].age_conflict = TALER_AgeCommitmentHashP_NoConflict; + + if (is_age_hash_null[i] != coin[i].no_age_commitment) + { + if (is_age_hash_null[i]) + { + GNUNET_break_op (0); + result[i].age_conflict = TALER_AgeCommitmentHashP_NullExpected; + } + else + { + GNUNET_break_op (0); + result[i].age_conflict = TALER_AgeCommitmentHashP_ValueExpected; + } + } + else if ( (! is_age_hash_null[i]) && + (0 != GNUNET_memcmp (&result[i].h_age_commitment, + &coin[i].h_age_commitment)) ) + { + GNUNET_break_op (0); + result[i].age_conflict = TALER_AgeCommitmentHashP_ValueDiffers; + } + } + + return qs; +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_batch_ensure_coin_known (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo *coin, + struct TALER_EXCHANGEDB_CoinInfo *result, + unsigned int coin_length, + unsigned int batch_size) +{ + enum GNUNET_DB_QueryStatus qs = 0; + unsigned int i = 0; + + while ( (qs >= 0) && + (i < coin_length) ) + { + unsigned int bs = GNUNET_MIN (batch_size, + coin_length - i); + if (bs >= 4) + { + qs = insert4 (ctx, + &coin[i], + &result[i]); + i += 4; + continue; + } + switch (bs) + { + case 3: + case 2: + qs = insert2 (ctx, + &coin[i], + &result[i]); + i += 2; + break; + case 1: + qs = insert1 (ctx, + &coin[i], + &result[i]); + i += 1; + break; + case 0: + GNUNET_assert (0); + break; + } + } /* end while */ + if (qs < 0) + return qs; + return i; +} diff --git a/src/exchangedb/begin_revolving_shard.c b/src/exchangedb/begin_revolving_shard.c @@ -0,0 +1,259 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/begin_revolving_shard.c + * @brief Implementation of the begin_revolving_shard function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "begin_revolving_shard.h" +#include "pg_commit.h" +#include "pg_helper.h" +#include "pg_start.h" +#include "pg_rollback.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_begin_revolving_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + uint32_t shard_size, + uint32_t shard_limit, + uint32_t *start_row, + uint32_t *end_row) +{ + GNUNET_assert (shard_limit <= 1U + (uint32_t) INT_MAX); + GNUNET_assert (shard_limit > 0); + GNUNET_assert (shard_size > 0); + for (unsigned int retries = 0; retries<3; retries++) + { + if (GNUNET_OK != + EXCHANGEDB_start (ctx, + "begin_revolving_shard")) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + + /* First, find last 'end_row' */ + { + enum GNUNET_DB_QueryStatus qs; + uint32_t last_end; + 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_uint32 ("end_row", + &last_end), + GNUNET_PQ_result_spec_end + }; + /* Used in #postgres_begin_revolving_shard() */ + PREPARE (ctx, + "get_last_revolving_shard", + "SELECT" + " end_row" + " FROM revolving_work_shards" + " WHERE job_name=$1" + " ORDER BY end_row DESC" + " LIMIT 1;"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_last_revolving_shard", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + *start_row = 1U + last_end; + break; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + *start_row = 0; /* base-case: no shards yet */ + break; /* continued below */ + } + } /* get_last_shard */ + + if (*start_row < shard_limit) + { + /* Claim fresh shard */ + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_TIME_Absolute now; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (job_name), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_uint32 (start_row), + GNUNET_PQ_query_param_uint32 (end_row), + GNUNET_PQ_query_param_end + }; + + *end_row = GNUNET_MIN (shard_limit, + *start_row + shard_size - 1); + now = GNUNET_TIME_absolute_get (); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Trying to claim shard %llu-%llu\n", + (unsigned long long) *start_row, + (unsigned long long) *end_row); + + /* Used in #postgres_claim_revolving_shard() */ + PREPARE (ctx, + "create_revolving_shard", + "INSERT INTO revolving_work_shards" + "(job_name" + ",last_attempt" + ",start_row" + ",end_row" + ",active" + ") VALUES " + "($1, $2, $3, $4, TRUE);"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "create_revolving_shard", + params); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + /* continued below (with commit) */ + break; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + /* someone else got this shard already, + try again */ + EXCHANGEDB_rollback (ctx); + continue; + } + } /* end create fresh reovlving shard */ + else + { + /* claim oldest existing shard */ + 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_uint32 ("start_row", + start_row), + GNUNET_PQ_result_spec_uint32 ("end_row", + end_row), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "get_open_revolving_shard", + "SELECT" + " start_row" + ",end_row" + " FROM revolving_work_shards" + " WHERE job_name=$1" + " AND active=FALSE" + " ORDER BY last_attempt ASC" + " LIMIT 1;"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_open_revolving_shard", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + /* no open shards available */ + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + { + enum GNUNET_DB_QueryStatus qsz; + struct GNUNET_TIME_Timestamp now; + struct GNUNET_PQ_QueryParam iparams[] = { + GNUNET_PQ_query_param_string (job_name), + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_uint32 (start_row), + GNUNET_PQ_query_param_uint32 (end_row), + GNUNET_PQ_query_param_end + }; + + now = GNUNET_TIME_timestamp_get (); + PREPARE (ctx, + "reclaim_revolving_shard", + "UPDATE revolving_work_shards" + " SET last_attempt=$2" + " ,active=TRUE" + " WHERE job_name=$1" + " AND start_row=$3" + " AND end_row=$4"); + qsz = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "reclaim_revolving_shard", + iparams); + switch (qsz) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; /* continue with commit */ + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); /* logic error, should be impossible */ + EXCHANGEDB_rollback (ctx); + return GNUNET_DB_STATUS_HARD_ERROR; + } + } + break; /* continue with commit */ + } + } /* end claim oldest existing shard */ + + /* commit */ + { + enum GNUNET_DB_QueryStatus qs; + + qs = EXCHANGEDB_commit (ctx); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + EXCHANGEDB_rollback (ctx); + 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; +} diff --git a/src/exchangedb/begin_shard.c b/src/exchangedb/begin_shard.c @@ -0,0 +1,264 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/begin_shard.c + * @brief Implementation of the begin_shard function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "begin_shard.h" +#include "pg_helper.h" +#include "pg_start.h" +#include "pg_rollback.h" +#include "pg_commit.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_begin_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + struct GNUNET_TIME_Relative delay, + uint64_t shard_size, + uint64_t *start_row, + uint64_t *end_row) +{ + for (unsigned int retries = 0; retries<10; retries++) + { + if (GNUNET_OK != + EXCHANGEDB_start (ctx, + "begin_shard")) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + + { + 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 + }; + + past = GNUNET_TIME_absolute_get (); + PREPARE (ctx, + "get_open_shard", + "SELECT" + " start_row" + ",end_row" + " FROM work_shards" + " WHERE job_name=$1" + " AND completed=FALSE" + " AND last_attempt<$2" + " ORDER BY last_attempt ASC" + " LIMIT 1;"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_open_shard", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Serialization error on getting open shard\n"); + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + { + enum GNUNET_DB_QueryStatus qsz; + struct GNUNET_TIME_Absolute now; + struct GNUNET_PQ_QueryParam iparams[] = { + GNUNET_PQ_query_param_string (job_name), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_uint64 (start_row), + GNUNET_PQ_query_param_uint64 (end_row), + GNUNET_PQ_query_param_end + }; + + now = GNUNET_TIME_relative_to_absolute (delay); + PREPARE (ctx, + "reclaim_shard", + "UPDATE work_shards" + " SET last_attempt=$2" + " WHERE job_name=$1" + " AND start_row=$3" + " AND end_row=$4"); + qsz = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "reclaim_shard", + iparams); + switch (qsz) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qsz; + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Serialization error on claiming open shard\n"); + EXCHANGEDB_rollback (ctx); + 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 */ + EXCHANGEDB_rollback (ctx); + 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 + }; + + PREPARE (ctx, + "get_last_shard", + "SELECT" + " end_row" + " FROM work_shards" + " WHERE job_name=$1" + " ORDER BY end_row DESC" + " LIMIT 1;"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_last_shard", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Serialization error on getting last shard\n"); + EXCHANGEDB_rollback (ctx); + 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; + struct GNUNET_TIME_Absolute now; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (job_name), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_uint64 (start_row), + GNUNET_PQ_query_param_uint64 (end_row), + GNUNET_PQ_query_param_end + }; + + now = GNUNET_TIME_relative_to_absolute (delay); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Trying to claim shard (%llu-%llu]\n", + (unsigned long long) *start_row, + (unsigned long long) *end_row); + + PREPARE (ctx, + "claim_next_shard", + "INSERT INTO work_shards" + "(job_name" + ",last_attempt" + ",start_row" + ",end_row" + ") VALUES " + "($1, $2, $3, $4);"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "claim_next_shard", + params); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Serialization error on claiming next shard\n"); + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + /* continued below */ + break; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + /* someone else got this shard already, + try again */ + EXCHANGEDB_rollback (ctx); + continue; + } + } /* claim_next_shard */ + + /* commit */ +commit: + { + enum GNUNET_DB_QueryStatus qs; + + qs = EXCHANGEDB_commit (ctx); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Serialization error on commit for beginning shard\n"); + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Claimed new shard\n"); + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } + } + } /* retry 'for' loop */ + return GNUNET_DB_STATUS_SOFT_ERROR; +} diff --git a/src/exchangedb/clear_aml_lock.c b/src/exchangedb/clear_aml_lock.c @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/clear_aml_lock.c + * @brief Implementation of the clear_aml_lock function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "clear_aml_lock.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_clear_aml_lock (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "clear_aml_lock", + "UPDATE kyc_targets" + " SET aml_program_lock_timeout=NULL" + " WHERE h_normalized_payto=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "clear_aml_lock", + params); +} diff --git a/src/exchangedb/commit.c b/src/exchangedb/commit.c @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/commit.c + * @brief Implementation of the commit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "commit.h" +#include "pg_helper.h" + + +/** + * Commit the current transaction of a database connection. + * + * @param cls the `struct EXCHANGEDB_PostgresContext` with the plugin-specific state + * @return final transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_commit (struct EXCHANGEDB_PostgresContext *ctx) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + GNUNET_break (NULL != ctx->transaction_name); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Committing transaction `%s'\n", + ctx->transaction_name); + PREPARE (ctx, + "do_commit", + "COMMIT"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "do_commit", + params); + ctx->transaction_name = NULL; + return qs; +} diff --git a/src/exchangedb/complete_shard.c b/src/exchangedb/complete_shard.c @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/complete_shard.c + * @brief Implementation of the complete_shard function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "complete_shard.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_complete_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + uint64_t start_row, + uint64_t end_row) +{ + 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 + }; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Completing shard %llu-%llu\n", + (unsigned long long) start_row, + (unsigned long long) end_row); + PREPARE (ctx, + "complete_shard", + "UPDATE work_shards" + " SET completed=TRUE" + " WHERE job_name=$1" + " AND start_row=$2" + " AND end_row=$3"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "complete_shard", + params); +} diff --git a/src/exchangedb/compute_shard.c b/src/exchangedb/compute_shard.c @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/compute_shard.c + * @brief Implementation of the compute_shard function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "compute_shard.h" +#include "pg_helper.h" + + +uint64_t +EXCHANGEDB_compute_shard (const struct TALER_MerchantPublicKeyP *merchant_pub) +{ + uint32_t res; + + GNUNET_assert (GNUNET_YES == + GNUNET_CRYPTO_hkdf_gnunet ( + &res, + sizeof (res), + merchant_pub, + sizeof (*merchant_pub), + "VOID", + 4)); + /* 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; +} diff --git a/src/exchangedb/count_known_coins.c b/src/exchangedb/count_known_coins.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/count_known_coins.c + * @brief Implementation of the count_known_coins function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "count_known_coins.h" +#include "pg_helper.h" + +long long +EXCHANGEDB_count_known_coins (struct EXCHANGEDB_PostgresContext *ctx, + const struct + TALER_DenominationHashP *denom_pub_hash) +{ + 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; + + + PREPARE (ctx, + "count_known_coins", + "SELECT" + " COUNT(*) AS count" + " FROM known_coins" + " WHERE denominations_serial=" + " (SELECT denominations_serial" + " FROM denominations" + " WHERE denom_pub_hash=$1);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "count_known_coins", + params, + rs); + if (0 > qs) + return (long long) qs; + return (long long) count; +} diff --git a/src/exchangedb/create_aggregation_transient.c b/src/exchangedb/create_aggregation_transient.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/create_aggregation_transient.c + * @brief Implementation of the create_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "create_aggregation_transient.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_create_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const char *exchange_account_section, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_WireTransferIdentifierRawP *wtid, + uint64_t kyc_requirement_row, + const struct TALER_Amount *total) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + total), + GNUNET_PQ_query_param_auto_from_type (merchant_pub), + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_uint64 (&kyc_requirement_row), + GNUNET_PQ_query_param_string (exchange_account_section), + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "create_aggregation_transient", + "INSERT INTO aggregation_transient" + " (amount" + " ,merchant_pub" + " ,wire_target_h_payto" + " ,legitimization_requirement_serial_id" + " ,exchange_account_section" + " ,wtid_raw)" + " VALUES ($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "create_aggregation_transient", + params); +} diff --git a/src/exchangedb/create_tables.c b/src/exchangedb/create_tables.c @@ -0,0 +1,81 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/create_tables.c + * @brief Implementation of the create_tables function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "create_tables.h" +#include "pg_helper.h" + + +enum GNUNET_GenericReturnValue +EXCHANGEDB_create_tables (struct EXCHANGEDB_PostgresContext *ctx, + bool support_partitions, + uint32_t num_partitions) +{ + struct GNUNET_PQ_Context *conn; + enum GNUNET_GenericReturnValue ret; + struct GNUNET_PQ_QueryParam params[] = { + support_partitions + ? GNUNET_PQ_query_param_uint32 (&num_partitions) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_try_execute ("SET search_path TO exchange;"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + conn = GNUNET_PQ_connect_with_cfg (ctx->cfg, + "exchangedb-postgres", + "exchange-", + es, + NULL); + if (NULL == conn) + return GNUNET_SYSERR; + ret = GNUNET_PQ_exec_sql (conn, + "procedures"); + GNUNET_break (GNUNET_OK == ret); + if (GNUNET_OK == ret) + { + struct GNUNET_PQ_Context *tconn; + + tconn = ctx->conn; + ctx->prep_gen++; + ctx->conn = conn; + PREPARE (ctx, + "create_tables", + "SELECT" + " exchange_do_create_tables" + " ($1::INTEGER);"); + ctx->conn = tconn; + if (0 > + GNUNET_PQ_eval_prepared_non_select (conn, + "create_tables", + params)) + { + GNUNET_break (0); + ret = GNUNET_SYSERR; + } + } + GNUNET_PQ_disconnect (conn); + return ret; +} diff --git a/src/exchangedb/delete_aggregation_transient.c b/src/exchangedb/delete_aggregation_transient.c @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/delete_aggregation_transient.c + * @brief Implementation of the delete_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "delete_aggregation_transient.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_delete_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const struct TALER_WireTransferIdentifierRawP *wtid) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "delete_aggregation_transient", + "DELETE FROM aggregation_transient" + " WHERE wire_target_h_payto=$1" + " AND wtid_raw=$2"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "delete_aggregation_transient", + params); +} diff --git a/src/exchangedb/delete_shard_locks.c b/src/exchangedb/delete_shard_locks.c @@ -0,0 +1,40 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/delete_shard_locks.c + * @brief Implementation of the delete_shard_locks function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "delete_shard_locks.h" +#include "pg_helper.h" + + +enum GNUNET_GenericReturnValue +EXCHANGEDB_delete_shard_locks (struct EXCHANGEDB_PostgresContext *ctx) +{ + 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 + }; + + return GNUNET_PQ_exec_statements (ctx->conn, + es); +} diff --git a/src/exchangedb/disable_rules.c b/src/exchangedb/disable_rules.c @@ -0,0 +1,59 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/disable_rules.c + * @brief Implementation of the disable_rules function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "disable_rules.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_disable_rules (struct EXCHANGEDB_PostgresContext *ctx, + const char *schema) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (schema), + GNUNET_PQ_query_param_end + }; + bool found; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("out_found", + &found), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "call_exchange_drop_customization", + "SELECT out_found" + " FROM exchange_drop_customization" + " ($1);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_exchange_drop_customization", + params, + rs); + if (qs < 0) + return qs; + if (found) + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; +} diff --git a/src/exchangedb/do_check_deposit_idempotent.c b/src/exchangedb/do_check_deposit_idempotent.c @@ -0,0 +1,111 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_do_deposit.c + * @brief Implementation of the do_deposit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_check_deposit_idempotent.h" +#include "pg_helper.h" +#include "pg_compute_shard.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_check_deposit_idempotent (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_BatchDeposit *bd, + struct GNUNET_TIME_Timestamp *exchange_timestamp, + bool *is_idempotent) +{ + uint64_t deposit_shard = EXCHANGEDB_compute_shard (&bd->merchant_pub); + const struct TALER_CoinSpendPublicKeyP *coin_pubs[GNUNET_NZL (bd->num_cdis)]; + const struct TALER_CoinSpendSignatureP *coin_sigs[GNUNET_NZL (bd->num_cdis)]; + struct TALER_Amount amounts_with_fee[GNUNET_NZL (bd->num_cdis)]; + struct TALER_NormalizedPaytoHashP h_normalized_payto; + struct GNUNET_PQ_QueryParam params[] = { + /* data for batch_deposits */ + GNUNET_PQ_query_param_uint64 (&deposit_shard), + GNUNET_PQ_query_param_auto_from_type (&bd->merchant_pub), + GNUNET_PQ_query_param_timestamp (&bd->wallet_timestamp), + GNUNET_PQ_query_param_timestamp (exchange_timestamp), + GNUNET_PQ_query_param_timestamp (&bd->refund_deadline), + GNUNET_PQ_query_param_timestamp (&bd->wire_deadline), + GNUNET_PQ_query_param_auto_from_type (&bd->h_contract_terms), + (bd->no_wallet_data_hash) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (&bd->wallet_data_hash), + GNUNET_PQ_query_param_auto_from_type (&bd->wire_salt), + GNUNET_PQ_query_param_auto_from_type (&bd->wire_target_h_payto), + (0 == bd->policy_details_serial_id) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_uint64 (&bd->policy_details_serial_id), + GNUNET_PQ_query_param_bool (bd->policy_blocked), + /* arrays for coin_deposits */ + GNUNET_PQ_query_param_array_ptrs_auto_from_type (bd->num_cdis, + coin_pubs, + ctx->conn), + GNUNET_PQ_query_param_array_ptrs_auto_from_type (bd->num_cdis, + coin_sigs, + ctx->conn), + TALER_PQ_query_param_array_amount (bd->num_cdis, + amounts_with_fee, + ctx->conn), + GNUNET_PQ_query_param_end + }; + bool no_time; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_timestamp ("exchange_timestamp", + exchange_timestamp), + &no_time), + GNUNET_PQ_result_spec_bool ("is_idempotent", + is_idempotent), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + TALER_full_payto_normalize_and_hash (bd->receiver_wire_account, + &h_normalized_payto); + for (unsigned int i = 0; i < bd->num_cdis; i++) + { + const struct TALER_EXCHANGEDB_CoinDepositInformation *cdi + = &bd->cdis[i]; + + amounts_with_fee[i] = cdi->amount_with_fee; + coin_pubs[i] = &cdi->coin.coin_pub; + coin_sigs[i] = &cdi->csig; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Do deposit %u = %s\n", + i, + TALER_B2S (&cdi->coin.coin_pub)); + } + PREPARE (ctx, + "call_check_deposit_idempotent", + "SELECT " + " out_exchange_timestamp AS exchange_timestamp" + ",out_is_idempotent AS is_idempotent" + " FROM exchange_do_check_deposit_idempotent" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_check_deposit_idempotent", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; +} diff --git a/src/exchangedb/do_deposit.c b/src/exchangedb/do_deposit.c @@ -0,0 +1,173 @@ +/* + This file is part of TALER + Copyright (C) 2022-2026 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_deposit.c + * @brief Implementation of the do_deposit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_deposit.h" +#include "pg_helper.h" +#include "pg_compute_shard.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_BatchDeposit *bd, + const struct TALER_Amount deposit_fees[], + struct GNUNET_TIME_Timestamp *exchange_timestamp, + struct TALER_Amount *accumulated_total_without_fee, + bool *balance_ok, + uint32_t *bad_balance_index, + bool *ctr_conflict) +{ + uint64_t deposit_shard = EXCHANGEDB_compute_shard (&bd->merchant_pub); + const struct TALER_CoinSpendPublicKeyP *coin_pubs[GNUNET_NZL (bd->num_cdis)]; + const struct TALER_CoinSpendSignatureP *coin_sigs[GNUNET_NZL (bd->num_cdis)]; + struct TALER_Amount amounts_with_fee[GNUNET_NZL (bd->num_cdis)]; + struct TALER_Amount total_amount; + struct TALER_Amount total_without_fee; + struct TALER_NormalizedPaytoHashP h_normalized_payto; + struct GNUNET_PQ_QueryParam params[] = { + /* data for batch_deposits */ + GNUNET_PQ_query_param_uint64 (&deposit_shard), + GNUNET_PQ_query_param_auto_from_type (&bd->merchant_pub), + GNUNET_PQ_query_param_auto_from_type (&bd->merchant_sig), + GNUNET_PQ_query_param_timestamp (&bd->wallet_timestamp), + GNUNET_PQ_query_param_timestamp (exchange_timestamp), + GNUNET_PQ_query_param_timestamp (&bd->refund_deadline), + GNUNET_PQ_query_param_timestamp (&bd->wire_deadline), + GNUNET_PQ_query_param_auto_from_type (&bd->h_contract_terms), + (bd->no_wallet_data_hash) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (&bd->wallet_data_hash), + GNUNET_PQ_query_param_auto_from_type (&bd->wire_salt), + GNUNET_PQ_query_param_auto_from_type (&bd->wire_target_h_payto), + GNUNET_PQ_query_param_auto_from_type (&h_normalized_payto), + (0 == bd->policy_details_serial_id) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_uint64 (&bd->policy_details_serial_id), + GNUNET_PQ_query_param_bool (bd->policy_blocked), + /* to create entry in wire_targets */ + GNUNET_PQ_query_param_string (bd->receiver_wire_account.full_payto), + /* arrays for coin_deposits */ + GNUNET_PQ_query_param_array_ptrs_auto_from_type (bd->num_cdis, + coin_pubs, + ctx->conn), + GNUNET_PQ_query_param_array_ptrs_auto_from_type (bd->num_cdis, + coin_sigs, + ctx->conn), + TALER_PQ_query_param_array_amount (bd->num_cdis, + amounts_with_fee, + ctx->conn), + TALER_PQ_query_param_array_amount (bd->num_cdis, + deposit_fees, + ctx->conn), + TALER_PQ_query_param_amount (ctx->conn, + &total_amount), + TALER_PQ_query_param_amount (ctx->conn, + &total_without_fee), + GNUNET_PQ_query_param_bool (TALER_payto_is_wallet ( + bd->receiver_wire_account.full_payto)), + NULL == bd->extra_wire_subject_metadata + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (bd->extra_wire_subject_metadata), + GNUNET_PQ_query_param_end + }; + bool no_time; + bool no_amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_timestamp ("exchange_timestamp", + exchange_timestamp), + &no_time), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_RESULT_SPEC_AMOUNT ("accumulated_total_without_fee", + accumulated_total_without_fee), + &no_amount), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint32 ("insufficient_balance_coin_index", + bad_balance_index), + balance_ok), + GNUNET_PQ_result_spec_bool ("conflicted", + ctr_conflict), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + GNUNET_assert (0 < bd->num_cdis); + TALER_full_payto_normalize_and_hash (bd->receiver_wire_account, + &h_normalized_payto); + for (unsigned int i = 0; i < bd->num_cdis; i++) + { + const struct TALER_EXCHANGEDB_CoinDepositInformation *cdi + = &bd->cdis[i]; + + if (0 == i) + { + total_amount = cdi->amount_with_fee; + total_without_fee = cdi->amount_with_fee; + } + else + { + GNUNET_assert (0 <= + TALER_amount_add (&total_amount, + &total_amount, + &cdi->amount_with_fee)); + GNUNET_assert (0 <= + TALER_amount_add (&total_without_fee, + &total_without_fee, + &cdi->amount_with_fee)); + } + GNUNET_assert (0 <= + TALER_amount_subtract ( + &total_without_fee, + &total_without_fee, + &deposit_fees[i])); + + amounts_with_fee[i] = cdi->amount_with_fee; + coin_pubs[i] = &cdi->coin.coin_pub; + coin_sigs[i] = &cdi->csig; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Do deposit %u = %s\n", + i, + TALER_B2S (&cdi->coin.coin_pub)); + } + PREPARE (ctx, + "call_deposit", + "SELECT " + " out_exchange_timestamp AS exchange_timestamp" + ",out_accumulated_total_without_fee AS accumulated_total_without_fee" + ",out_insufficient_balance_coin_index AS insufficient_balance_coin_index" + ",out_conflict AS conflicted" + " FROM exchange_do_deposit" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10" + ",$11,$12,$13,$14,$15,$16,$17,$18,$19,$20" + ",$21,$22,$23);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_deposit", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + if (no_amount) + memset (accumulated_total_without_fee, + 0, + sizeof (struct TALER_Amount)); + return qs; +} diff --git a/src/exchangedb/do_purse_delete.c b/src/exchangedb/do_purse_delete.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_purse_delete.c + * @brief Implementation of the do_purse_delete function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_purse_delete.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_purse_delete (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig, + bool *decided, + bool *found) +{ + struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_auto_from_type (purse_sig), + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("decided", + decided), + GNUNET_PQ_result_spec_bool ("found", + found), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "call_purse_delete", + "SELECT " + " out_decided AS decided" + ",out_found AS found" + " FROM exchange_do_purse_delete" + " ($1,$2,$3);"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_purse_delete", + params, + rs); +} diff --git a/src/exchangedb/do_purse_deposit.c b/src/exchangedb/do_purse_deposit.c @@ -0,0 +1,88 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_purse_deposit.c + * @brief Implementation of the do_purse_deposit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_purse_deposit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_purse_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendSignatureP *coin_sig, + const struct TALER_Amount *amount_minus_fee, + bool *balance_ok, + bool *too_late, + bool *conflict) +{ + struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get (); + struct GNUNET_TIME_Timestamp reserve_expiration; + uint64_t partner_id = 0; /* FIXME #7271: WAD support... */ + struct GNUNET_PQ_QueryParam params[] = { + (0 == partner_id) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_uint64 (&partner_id), + GNUNET_PQ_query_param_auto_from_type (purse_pub), + TALER_PQ_query_param_amount ( + ctx->conn, + amount), + GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_auto_from_type (coin_sig), + TALER_PQ_query_param_amount ( + ctx->conn, + amount_minus_fee), + GNUNET_PQ_query_param_timestamp (&reserve_expiration), + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("balance_ok", + balance_ok), + GNUNET_PQ_result_spec_bool ("too_late", + too_late), + GNUNET_PQ_result_spec_bool ("conflict", + conflict), + GNUNET_PQ_result_spec_end + }; + + reserve_expiration + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), + ctx->legal_reserve_expiration_time)); + + PREPARE (ctx, + "call_purse_deposit", + "SELECT " + " out_balance_ok AS balance_ok" + ",out_conflict AS conflict" + ",out_late AS too_late" + " FROM exchange_do_purse_deposit" + " ($1,$2,$3,$4,$5,$6,$7,$8);"); + + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_purse_deposit", + params, + rs); +} diff --git a/src/exchangedb/do_purse_merge.c b/src/exchangedb/do_purse_merge.c @@ -0,0 +1,89 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_purse_merge.c + * @brief Implementation of the do_purse_merge function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_purse_merge.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_purse_merge (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergeSignatureP *merge_sig, + const struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_ReserveSignatureP *reserve_sig, + const char *partner_url, + const struct TALER_ReservePublicKeyP *reserve_pub, + bool *no_partner, + bool *no_balance, + bool *in_conflict) +{ + struct TALER_NormalizedPaytoHashP h_payto; + struct GNUNET_TIME_Timestamp expiration + = GNUNET_TIME_relative_to_timestamp (ctx->legal_reserve_expiration_time); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_auto_from_type (merge_sig), + GNUNET_PQ_query_param_timestamp (&merge_timestamp), + GNUNET_PQ_query_param_auto_from_type (reserve_sig), + (NULL == partner_url) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (partner_url), + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_auto_from_type (&h_payto), + GNUNET_PQ_query_param_timestamp (&expiration), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("no_partner", + no_partner), + GNUNET_PQ_result_spec_bool ("no_balance", + no_balance), + GNUNET_PQ_result_spec_bool ("conflict", + in_conflict), + GNUNET_PQ_result_spec_end + }; + + { + struct TALER_NormalizedPayto payto_uri; + + payto_uri = TALER_reserve_make_payto (ctx->exchange_url, + reserve_pub); + TALER_normalized_payto_hash (payto_uri, + &h_payto); + GNUNET_free (payto_uri.normalized_payto); + } + PREPARE (ctx, + "call_purse_merge", + "SELECT" + " out_no_partner AS no_partner" + ",out_no_balance AS no_balance" + ",out_conflict AS conflict" + " FROM exchange_do_purse_merge" + " ($1, $2, $3, $4, $5, $6, $7, $8);"); + + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_purse_merge", + params, + rs); +} diff --git a/src/exchangedb/do_recoup.c b/src/exchangedb/do_recoup.c @@ -0,0 +1,83 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_recoup.c + * @brief Implementation of the do_recoup function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_recoup.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_recoup (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t withdraw_id, + const union GNUNET_CRYPTO_BlindingSecretP *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 GNUNET_TIME_Timestamp reserve_gc + = GNUNET_TIME_relative_to_timestamp (ctx->legal_reserve_expiration_time); + struct GNUNET_TIME_Timestamp reserve_expiration + = GNUNET_TIME_relative_to_timestamp (ctx->idle_reserve_expiration_time); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_uint64 (&withdraw_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 + }; + + + PREPARE (ctx, + "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" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9);"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_recoup", + params, + rs); +} diff --git a/src/exchangedb/do_recoup_refresh.c b/src/exchangedb/do_recoup_refresh.c @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_recoup_refresh.c + * @brief Implementation of the do_recoup_refresh function for Postgres + * @author Christian Grothoff + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_recoup_refresh.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_recoup_refresh (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *old_coin_pub, + uint64_t refresh_id, + const union GNUNET_CRYPTO_BlindingSecretP *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 GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (old_coin_pub), + GNUNET_PQ_query_param_uint64 (&refresh_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 (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 + }; + + + PREPARE (ctx, + "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" + " ($1,$2,$3,$4,$5,$6,$7);"); + + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_recoup_refresh", + params, + rs); +} diff --git a/src/exchangedb/do_refresh.c b/src/exchangedb/do_refresh.c @@ -0,0 +1,140 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_refresh.c + * @brief Implementation of the do_refresh function for Postgres + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_exchangedb_plugin.h" +#include "taler/taler_pq_lib.h" +#include "do_refresh.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_refresh (struct EXCHANGEDB_PostgresContext *ctx, + struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh, + const struct GNUNET_TIME_Timestamp *timestamp, + bool *found, + uint32_t *noreveal_index, + bool *zombie_required, + bool *nonce_reuse, + bool *balance_ok, + struct TALER_Amount *coin_balance) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&refresh->rc), + GNUNET_PQ_query_param_timestamp (timestamp), + GNUNET_PQ_query_param_auto_from_type (&refresh->refresh_seed), /* 3 */ + (refresh->is_v27_refresh) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_array_auto_from_type (refresh->num_coins, + refresh->transfer_pubs, + ctx->conn), + GNUNET_PQ_query_param_auto_from_type (&refresh->planchets_h), + TALER_PQ_query_param_amount (ctx->conn, /* 6 */ + &refresh->amount_with_fee), + (refresh->no_blinding_seed) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (&refresh->blinding_seed), + (0 < refresh->num_cs_r_values) + ? TALER_PQ_query_param_array_cs_r_pub (refresh->num_cs_r_values, + refresh->cs_r_values, + ctx->conn) + : GNUNET_PQ_query_param_null (), + (0 < refresh->num_cs_r_values) + ? GNUNET_PQ_query_param_uint64 (&refresh->cs_r_choices) /* 9 */ + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_auto_from_type (&refresh->selected_h), + TALER_PQ_query_param_array_blinded_denom_sig (refresh->num_coins, + refresh->denom_sigs, + ctx->conn), + GNUNET_PQ_query_param_array_uint64 (refresh->num_coins, /* 12 */ + refresh->denom_serials, + ctx->conn), + 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_uint32 (&refresh->noreveal_index), /* 15 */ + GNUNET_PQ_query_param_bool (*zombie_required), + GNUNET_PQ_query_param_end + }; + bool coin_found; + bool no_noreveal_index; + bool no_coin_balance; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("coin_found", + &coin_found), + GNUNET_PQ_result_spec_bool ("balance_ok", + balance_ok), + GNUNET_PQ_result_spec_bool ("zombie_required", + zombie_required), + GNUNET_PQ_result_spec_bool ("nonce_reuse", + nonce_reuse), + GNUNET_PQ_result_spec_bool ("found", + found), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint32 ("noreveal_index", + noreveal_index), + &no_noreveal_index), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_RESULT_SPEC_AMOUNT ("coin_balance", + coin_balance), + &no_coin_balance), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "call_refresh", + "SELECT " + " out_coin_found AS coin_found" + ",out_balance_ok AS balance_ok" + ",out_zombie_bad AS zombie_required" + ",out_nonce_reuse AS nonce_reuse" + ",out_idempotent AS found" + ",out_noreveal_index AS noreveal_index" + ",out_coin_balance AS coin_balance" + " FROM exchange_do_refresh" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_refresh", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + if (0 > qs) + { + GNUNET_break (0); + return qs; + } + if (! coin_found) + { + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + if (*found && no_noreveal_index) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (! balance_ok && no_coin_balance) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} diff --git a/src/exchangedb/do_refund.c b/src/exchangedb/do_refund.c @@ -0,0 +1,91 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_refund.c + * @brief Implementation of the do_refund function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_refund.h" +#include "pg_helper.h" +#include "pg_compute_shard.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_refund (struct EXCHANGEDB_PostgresContext *ctx, + 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) +{ + uint64_t deposit_shard = EXCHANGEDB_compute_shard (&refund->details.merchant_pub); + struct TALER_Amount amount_without_fee; + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + &refund->details.refund_amount), + TALER_PQ_query_param_amount (ctx->conn, + &amount_without_fee), + TALER_PQ_query_param_amount (ctx->conn, + 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; + } + PREPARE (ctx, + "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" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_refund", + params, + rs); +} diff --git a/src/exchangedb/do_reserve_open.c b/src/exchangedb/do_reserve_open.c @@ -0,0 +1,99 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_do_reserve_open.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_reserve_open.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_reserve_open (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *total_paid, + const struct TALER_Amount *reserve_payment, + uint32_t min_purse_limit, + const struct TALER_ReserveSignatureP *reserve_sig, + struct GNUNET_TIME_Timestamp desired_expiration, + struct GNUNET_TIME_Timestamp now, + const struct TALER_Amount *open_fee, + bool *no_funds, + struct TALER_Amount *reserve_balance, + struct TALER_Amount *open_cost, + struct GNUNET_TIME_Timestamp *final_expiration) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + TALER_PQ_query_param_amount ( + ctx->conn, + total_paid), + TALER_PQ_query_param_amount ( + ctx->conn, + reserve_payment), + GNUNET_PQ_query_param_uint32 (&min_purse_limit), + GNUNET_PQ_query_param_uint32 (&ctx->def_purse_limit), + GNUNET_PQ_query_param_auto_from_type (reserve_sig), + GNUNET_PQ_query_param_timestamp (&desired_expiration), + GNUNET_PQ_query_param_relative_time (&ctx->legal_reserve_expiration_time), + GNUNET_PQ_query_param_timestamp (&now), + TALER_PQ_query_param_amount (ctx->conn, + open_fee), + GNUNET_PQ_query_param_end + }; + bool no_reserve = true; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_amount ("out_open_cost", + ctx->currency, + open_cost), + TALER_PQ_result_spec_amount ("out_reserve_balance", + ctx->currency, + reserve_balance), + GNUNET_PQ_result_spec_timestamp ("out_final_expiration", + final_expiration), + GNUNET_PQ_result_spec_bool ("out_no_reserve", + &no_reserve), + GNUNET_PQ_result_spec_bool ("out_no_funds", + no_funds), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "do_reserve_open", + "SELECT " + " out_open_cost" + ",out_final_expiration" + ",out_no_funds" + ",out_no_reserve" + ",out_reserve_balance" + " FROM exchange_do_reserve_open" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "do_reserve_open", + params, + rs); + if (qs <= 0) + return qs; + if (no_reserve) + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + return qs; +} diff --git a/src/exchangedb/do_reserve_purse.c b/src/exchangedb/do_reserve_purse.c @@ -0,0 +1,120 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_reserve_purse.c + * @brief Implementation of the do_reserve_purse function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "do_reserve_purse.h" +#include "pg_helper.h" + + +/** + * Function called insert request to merge a purse into a reserve by the + * respective purse merge key. The purse must not have been merged into a + * different reserve. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to merge + * @param merge_sig signature affirming the merge + * @param merge_timestamp time of the merge + * @param reserve_sig signature of the reserve affirming the merge + * @param purse_fee amount to charge the reserve for the purse creation, NULL to use the quota + * @param reserve_pub public key of the reserve to credit + * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already + * @param[out] no_reserve set to true if @a reserve_pub is not a known reserve + * @param[out] insufficient_funds set to true if @a reserve_pub has insufficient capacity to create another purse + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_reserve_purse (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergeSignatureP *merge_sig, + const struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_ReserveSignatureP *reserve_sig, + const struct TALER_Amount *purse_fee, + const struct TALER_ReservePublicKeyP *reserve_pub, + bool *in_conflict, + bool *no_reserve, + bool *insufficient_funds) +{ + struct TALER_Amount zero_fee; + struct TALER_NormalizedPaytoHashP h_payto; + struct GNUNET_TIME_Timestamp reserve_expiration + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), + ctx->idle_reserve_expiration_time)); + struct GNUNET_TIME_Timestamp reserve_gc + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), + ctx->legal_reserve_expiration_time)); + + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_auto_from_type (merge_sig), + GNUNET_PQ_query_param_timestamp (&merge_timestamp), + GNUNET_PQ_query_param_timestamp (&reserve_expiration), + GNUNET_PQ_query_param_timestamp (&reserve_gc), + GNUNET_PQ_query_param_auto_from_type (reserve_sig), + GNUNET_PQ_query_param_bool (NULL == purse_fee), + TALER_PQ_query_param_amount (ctx->conn, + NULL == purse_fee + ? &zero_fee + : purse_fee), + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_auto_from_type (&h_payto), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("insufficient_funds", + insufficient_funds), + GNUNET_PQ_result_spec_bool ("conflict", + in_conflict), + GNUNET_PQ_result_spec_bool ("no_reserve", + no_reserve), + GNUNET_PQ_result_spec_end + }; + + { + struct TALER_NormalizedPayto payto_uri; + + payto_uri = TALER_reserve_make_payto (ctx->exchange_url, + reserve_pub); + TALER_normalized_payto_hash (payto_uri, + &h_payto); + GNUNET_free (payto_uri.normalized_payto); + } + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + &zero_fee)); + PREPARE (ctx, + "call_reserve_purse", + "SELECT" + " out_no_funds AS insufficient_funds" + ",out_no_reserve AS no_reserve" + ",out_conflict AS conflict" + " FROM exchange_do_reserve_purse" + " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);"); + + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_reserve_purse", + params, + rs); +} diff --git a/src/exchangedb/do_withdraw.c b/src/exchangedb/do_withdraw.c @@ -0,0 +1,142 @@ +/* + This file is part of TALER + Copyright (C) 2023-2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/do_withdraw.c + * @brief Implementation of the do_withdraw function for Postgres + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_exchangedb_plugin.h" +#include "taler/taler_pq_lib.h" +#include "do_withdraw.h" +#include "pg_helper.h" +#include <gnunet/gnunet_time_lib.h> + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_withdraw (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_Withdraw *withdraw, + const struct GNUNET_TIME_Timestamp *timestamp, + bool *balance_ok, + struct TALER_Amount *reserve_balance, + bool *age_ok, + uint16_t *required_age, + uint32_t *reserve_birthday, + bool *idempotent, + uint16_t *noreveal_index, + bool *nonce_reuse) +{ + struct GNUNET_TIME_Timestamp gc; + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + &withdraw->amount_with_fee), + GNUNET_PQ_query_param_auto_from_type (&withdraw->reserve_pub), + GNUNET_PQ_query_param_auto_from_type (&withdraw->reserve_sig), + GNUNET_PQ_query_param_timestamp (timestamp), + GNUNET_PQ_query_param_timestamp (&gc), + GNUNET_PQ_query_param_auto_from_type (&withdraw->planchets_h), + (withdraw->age_proof_required) + ? GNUNET_PQ_query_param_uint16 (&withdraw->max_age) + : GNUNET_PQ_query_param_null (), + (withdraw->age_proof_required) + ? GNUNET_PQ_query_param_uint16 (&withdraw->noreveal_index) + : GNUNET_PQ_query_param_null (), + (withdraw->age_proof_required) + ? GNUNET_PQ_query_param_auto_from_type (&withdraw->selected_h) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_array_uint64 (withdraw->num_coins, + withdraw->denom_serials, + ctx->conn), + TALER_PQ_query_param_array_blinded_denom_sig (withdraw->num_coins, + withdraw->denom_sigs, + ctx->conn), + (withdraw->no_blinding_seed) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (&withdraw->blinding_seed), + (withdraw->no_blinding_seed) + ? GNUNET_PQ_query_param_null () + : TALER_PQ_query_param_array_cs_r_pub (withdraw->num_cs_r_values, + withdraw->cs_r_values, + ctx->conn), + (withdraw->no_blinding_seed) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_uint64 (&withdraw->cs_r_choices), + GNUNET_PQ_query_param_end + }; + bool reserve_found; + bool no_noreveal_index; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("out_reserve_found", + &reserve_found), + GNUNET_PQ_result_spec_bool ("out_balance_ok", + balance_ok), + TALER_PQ_RESULT_SPEC_AMOUNT ("out_reserve_balance", + reserve_balance), + GNUNET_PQ_result_spec_bool ("out_age_ok", + age_ok), + GNUNET_PQ_result_spec_uint16 ("out_required_age", + required_age), + GNUNET_PQ_result_spec_uint32 ("out_reserve_birthday", + reserve_birthday), + GNUNET_PQ_result_spec_bool ("out_idempotent", + idempotent), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint16 ("out_noreveal_index", + noreveal_index), + &no_noreveal_index), + GNUNET_PQ_result_spec_bool ("out_nonce_reuse", + nonce_reuse), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + GNUNET_assert ((! withdraw->no_blinding_seed) || + (0 == withdraw->num_cs_r_values)); + + gc = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (timestamp->abs_time, + ctx->legal_reserve_expiration_time)); + PREPARE (ctx, + "call_withdraw", + "SELECT " + " out_reserve_found" + ",out_balance_ok" + ",out_reserve_balance" + ",out_age_ok" + ",out_required_age" + ",out_reserve_birthday" + ",out_idempotent" + ",out_noreveal_index" + ",out_nonce_reuse" + " FROM exchange_do_withdraw" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_withdraw", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + + if (0 > qs) + return qs; + if (! reserve_found) + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + if ((withdraw->age_proof_required) && + (idempotent && no_noreveal_index)) + GNUNET_break (0); + return qs; +} diff --git a/src/exchangedb/drain_kyc_alert.c b/src/exchangedb/drain_kyc_alert.c @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/drain_kyc_alert.c + * @brief Implementation of the drain_kyc_alert function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "drain_kyc_alert.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_drain_kyc_alert (struct EXCHANGEDB_PostgresContext *ctx, + uint32_t trigger_type, + struct TALER_NormalizedPaytoHashP *h_payto) +{ + 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 + }; + + PREPARE (ctx, + "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)" + " RETURNING h_payto;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "drain_kyc_alert", + params, + rs); +} diff --git a/src/exchangedb/drop_tables.c b/src/exchangedb/drop_tables.c @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/drop_tables.c + * @brief Implementation of the drop_tables function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "drop_tables.h" +#include "pg_helper.h" + + +/** + * Drop all Taler tables. This should only be used by testcases. + * + * @param cls the `struct EXCHANGEDB_PostgresContext` with the plugin-specific state + * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_drop_tables (struct EXCHANGEDB_PostgresContext *ctx) +{ + struct GNUNET_PQ_Context *conn; + enum GNUNET_GenericReturnValue ret; + + if (NULL != ctx->conn) + { + GNUNET_PQ_disconnect (ctx->conn); + ctx->conn = NULL; + } + conn = GNUNET_PQ_connect_with_cfg (ctx->cfg, + "exchangedb-postgres", + NULL, + NULL, + NULL); + if (NULL == conn) + return GNUNET_SYSERR; + ret = GNUNET_PQ_exec_sql (conn, + "drop"); + GNUNET_PQ_disconnect (conn); + return ret; +} diff --git a/src/exchangedb/enable_rules.c b/src/exchangedb/enable_rules.c @@ -0,0 +1,76 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/enable_rules.c + * @brief Implementation of the enable_rules function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "enable_rules.h" +#include "pg_helper.h" + + +enum GNUNET_GenericReturnValue +EXCHANGEDB_enable_rules (struct EXCHANGEDB_PostgresContext *ctx, + const char *schema) +{ + struct GNUNET_PQ_Context *conn; + enum GNUNET_GenericReturnValue ret; + char *sp; + + GNUNET_asprintf (&sp, + "SET search_path TO %s,exchange;", + schema); + { + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_try_execute (sp), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + char *schemadash; + + GNUNET_asprintf (&schemadash, + "%s-", + schema); + conn = GNUNET_PQ_connect_with_cfg (ctx->cfg, + "exchangedb-postgres", + schemadash, + es, + NULL); + GNUNET_free (schemadash); + } + GNUNET_free (sp); + if (NULL == conn) + return GNUNET_SYSERR; + { + char *procfile; + + GNUNET_asprintf (&procfile, + "%s-procedures", + schema); + ret = GNUNET_PQ_exec_sql (conn, + procfile); + /* $SCHEMA-procedures MAY not exist, so only check for hard error */ + GNUNET_break (GNUNET_SYSERR != ret); + if (GNUNET_NO == ret) + ret = GNUNET_OK; + GNUNET_free (procfile); + } + GNUNET_PQ_disconnect (conn); + return ret; +} diff --git a/src/exchangedb/ensure_coin_known.c b/src/exchangedb/ensure_coin_known.c @@ -0,0 +1,168 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/ensure_coin_known.c + * @brief Implementation of the ensure_coin_known function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_exchangedb_plugin.h" +#include "taler/taler_pq_lib.h" +#include "ensure_coin_known.h" +#include "pg_helper.h" + + +enum TALER_EXCHANGEDB_CoinKnownStatus +EXCHANGEDB_ensure_coin_known (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo *coin, + uint64_t *known_coin_id, + struct TALER_DenominationHashP *denom_hash, + struct TALER_AgeCommitmentHashP *h_age_commitment) +{ + enum GNUNET_DB_QueryStatus qs; + bool existed; + bool no_denom_pub_hash; + bool no_age_commitment_hash; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin->denom_pub_hash), + coin->no_age_commitment + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (&coin->h_age_commitment), + TALER_PQ_query_param_denom_sig (&coin->denom_sig), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + 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), + &no_denom_pub_hash), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + h_age_commitment), + &no_age_commitment_hash), + GNUNET_PQ_result_spec_end + }; + + /* + See also: + https://stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql/37543015#37543015 + */ + PREPARE (ctx, + "insert_known_coin", + "WITH dd" + " (denominations_serial" + " ,coin" + " ) AS (" + " SELECT " + " denominations_serial" + " ,coin" + " 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" + " ,age_commitment_hash" + " ,denom_sig" + " ,remaining" + " ) SELECT " + " $1" + " ,denominations_serial" + " ,$3" + " ,$4" + " ,coin" + " FROM dd" + " ON CONFLICT DO NOTHING" /* CONFLICT on (coin_pub) */ + " RETURNING " + " known_coin_id" + " ) " + "SELECT " + " FALSE AS existed" + " ,known_coin_id" + " ,NULL AS denom_pub_hash" + " ,NULL AS age_commitment_hash" + " FROM ins " + "UNION ALL " + "SELECT " + " TRUE AS existed" + " ,known_coin_id" + " ,denom_pub_hash" + " ,kc.age_commitment_hash" + " FROM input_rows" + " JOIN known_coins kc USING (coin_pub)" + " JOIN denominations USING (denominations_serial)" + " LIMIT 1"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "insert_known_coin", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return TALER_EXCHANGEDB_CKS_HARD_FAIL; + case GNUNET_DB_STATUS_SOFT_ERROR: + return TALER_EXCHANGEDB_CKS_SOFT_FAIL; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); /* should be impossible */ + return TALER_EXCHANGEDB_CKS_HARD_FAIL; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + if (! existed) + return TALER_EXCHANGEDB_CKS_ADDED; + break; /* continued below */ + } + + if ( (! no_denom_pub_hash) && + (0 != GNUNET_memcmp (denom_hash, + &coin->denom_pub_hash)) ) + { + GNUNET_break_op (0); + return TALER_EXCHANGEDB_CKS_DENOM_CONFLICT; + } + + if (no_age_commitment_hash != coin->no_age_commitment) + { + if (no_age_commitment_hash) + { + GNUNET_break_op (0); + return TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NULL; + } + else + { + GNUNET_break_op (0); + return TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NON_NULL; + } + } + else if ( (! no_age_commitment_hash) && + (0 != GNUNET_memcmp (h_age_commitment, + &coin->h_age_commitment)) ) + { + GNUNET_break_op (0); + return TALER_EXCHANGEDB_CKS_AGE_CONFLICT_VALUE_DIFFERS; + } + + return TALER_EXCHANGEDB_CKS_PRESENT; +} diff --git a/src/exchangedb/event_listen.c b/src/exchangedb/event_listen.c @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/event_listen.c + * @brief Implementation of the event_listen function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "event_listen.h" +#include "pg_helper.h" + +/** + * Register callback to be invoked on events of type @a es. + * + * @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 + */ +struct GNUNET_DB_EventHandler * +EXCHANGEDB_event_listen (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Relative timeout, + const struct GNUNET_DB_EventHeaderP *es, + GNUNET_DB_EventCallback cb, + void *cb_cls) +{ + return GNUNET_PQ_event_listen (ctx->conn, + es, + timeout, + cb, + cb_cls); +} diff --git a/src/exchangedb/event_listen_cancel.c b/src/exchangedb/event_listen_cancel.c @@ -0,0 +1,36 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/event_listen_cancel.c + * @brief Implementation of the event_listen_cancel function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "event_listen_cancel.h" +#include "pg_helper.h" + + +void +EXCHANGEDB_event_listen_cancel (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_DB_EventHandler *eh) + +{ + (void) cls; + GNUNET_PQ_event_listen_cancel (eh); +} diff --git a/src/exchangedb/event_notify.c b/src/exchangedb/event_notify.c @@ -0,0 +1,39 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/event_notify.c + * @brief Implementation of the event_notify function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "event_notify.h" +#include "pg_helper.h" + + +void +EXCHANGEDB_event_notify (struct EXCHANGEDB_PostgresContext *ctx, + const struct GNUNET_DB_EventHeaderP *es, + const void *extra, + size_t extra_size) +{ + GNUNET_PQ_event_notify (ctx->conn, + es, + extra, + extra_size); +} diff --git a/src/exchangedb/expire_purse.c b/src/exchangedb/expire_purse.c @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/expire_purse.c + * @brief Implementation of the expire_purse function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "expire_purse.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_expire_purse (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Absolute start_time, + struct GNUNET_TIME_Absolute end_time) +{ + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&start_time), + GNUNET_PQ_query_param_absolute_time (&end_time), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_end + }; + bool found = false; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("found", + &found), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + + PREPARE (ctx, + "call_expire_purse", + "SELECT " + " out_found AS found" + " FROM exchange_do_expire_purse" + " ($1,$2,$3);"); + + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->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; +} diff --git a/src/exchangedb/find_aggregation_transient.c b/src/exchangedb/find_aggregation_transient.c @@ -0,0 +1,70 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/find_aggregation_transient.c + * @brief Implementation of the find_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "find_aggregation_transient.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_find_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct TALER_FullPayto *payto_uri, + struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_MerchantPublicKeyP *merchant_pub, + struct TALER_Amount *total) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + 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->full_payto), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + total), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "find_transient_aggregations", + "SELECT" + " atr.amount" + " ,atr.wtid_raw" + " ,atr.merchant_pub" + " ,wt.payto_uri" + " FROM wire_targets wt" + " JOIN aggregation_transient atr" + " USING (wire_target_h_payto)" + " WHERE wt.h_normalized_payto=$1" + " LIMIT 1;"); /* Note: there should really be only 1 match */ + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "find_transient_aggregations", + params, + rs); +} diff --git a/src/exchangedb/gc.c b/src/exchangedb/gc.c @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/gc.c + * @brief Implementation of the gc function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "gc.h" +#include "pg_helper.h" + + +enum GNUNET_GenericReturnValue +EXCHANGEDB_gc (struct EXCHANGEDB_PostgresContext *ctx) +{ + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); + struct GNUNET_TIME_Absolute long_ago; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&long_ago), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_Context *conn; + enum GNUNET_GenericReturnValue ret; + + /* Keep wire fees for 10 years, that should always + be enough _and_ they are tiny so it does not + matter to make this tight */ + long_ago = GNUNET_TIME_absolute_subtract ( + now, + GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_YEARS, + 10)); + { + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_try_execute ("SET search_path TO exchange;"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + struct GNUNET_PQ_PreparedStatement ps[] = { + GNUNET_PQ_make_prepare ("run_gc", + "CALL" + " exchange_do_gc" + " ($1,$2);"), + GNUNET_PQ_PREPARED_STATEMENT_END + }; + + conn = GNUNET_PQ_connect_with_cfg (ctx->cfg, + "exchangedb-postgres", + NULL, + es, + ps); + } + if (NULL == conn) + return GNUNET_SYSERR; + ret = GNUNET_OK; + if (0 > GNUNET_PQ_eval_prepared_non_select (conn, + "run_gc", + params)) + ret = GNUNET_SYSERR; + GNUNET_PQ_disconnect (conn); + return ret; +} diff --git a/src/exchangedb/get_coin_denomination.c b/src/exchangedb/get_coin_denomination.c @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_coin_denomination.c + * @brief Implementation of the get_coin_denomination function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_coin_denomination.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_coin_denomination (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + uint64_t *known_coin_id, + struct TALER_DenominationHashP *denom_hash) +{ + 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), + GNUNET_PQ_result_spec_uint64 ("known_coin_id", + known_coin_id), + GNUNET_PQ_result_spec_end + }; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Getting coin denomination of coin %s\n", + TALER_B2S (coin_pub)); + + /* Used in #postgres_get_coin_denomination() to fetch + the denomination public key hash for + a coin known to the exchange. */ + PREPARE (ctx, + "get_coin_denomination", + "SELECT" + " denominations.denom_pub_hash" + ",known_coin_id" + " FROM known_coins" + " JOIN denominations USING (denominations_serial)" + " WHERE coin_pub=$1" + " FOR SHARE;"); + + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_coin_denomination", + params, + rs); +} diff --git a/src/exchangedb/get_coin_transactions.c b/src/exchangedb/get_coin_transactions.c @@ -0,0 +1,1188 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_coin_transactions.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_exchangedb_plugin.h" +#include "taler/taler_pq_lib.h" +#include "get_coin_transactions.h" +#include "pg_helper.h" +#include "pg_start_read_committed.h" +#include "pg_commit.h" +#include "pg_rollback.h" +#include "plugin_exchangedb_common.h" + +/** + * How often do we re-try when encountering DB serialization issues? + * (We are read-only, so can only happen due to concurrent insert, + * which should be very rare.) + */ +#define RETRIES 3 + +/** + * Closure for callbacks called from #EXCHANGEDB_get_coin_transactions() + */ +struct CoinHistoryContext +{ + /** + * Head of the coin's history list. + */ + struct TALER_EXCHANGEDB_TransactionList *head; + + /** + * Public key of the coin we are building the history for. + */ + const struct TALER_CoinSpendPublicKeyP *coin_pub; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Our current offset in the coin history. + */ + uint64_t chid; + + /** + * Set to 'true' if the transaction failed. + */ + bool failed; + +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_coin_deposit (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_EXCHANGEDB_DepositListEntry *deposit; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + deposit = GNUNET_new (struct TALER_EXCHANGEDB_DepositListEntry); + { + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &deposit->amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + &deposit->deposit_fee), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &deposit->h_denom_pub), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &deposit->h_age_commitment), + &deposit->no_age_commitment), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("wallet_data_hash", + &deposit->wallet_data_hash), + &deposit->no_wallet_data_hash), + GNUNET_PQ_result_spec_timestamp ("wallet_timestamp", + &deposit->timestamp), + GNUNET_PQ_result_spec_timestamp ("refund_deadline", + &deposit->refund_deadline), + GNUNET_PQ_result_spec_timestamp ("wire_deadline", + &deposit->wire_deadline), + GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", + &deposit->merchant_pub), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &deposit->h_contract_terms), + GNUNET_PQ_result_spec_auto_from_type ("wire_salt", + &deposit->wire_salt), + GNUNET_PQ_result_spec_string ("payto_uri", + &deposit->receiver_wire_account.full_payto + ), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &deposit->csig), + GNUNET_PQ_result_spec_uint64 ("coin_deposit_serial_id", + &serial_id), + GNUNET_PQ_result_spec_auto_from_type ("done", + &deposit->done), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (deposit); + chc->failed = true; + return; + } + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_DEPOSIT; + tl->details.deposit = deposit; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_coin_purse_deposit (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_EXCHANGEDB_PurseDepositListEntry *deposit; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + deposit = GNUNET_new (struct TALER_EXCHANGEDB_PurseDepositListEntry); + { + bool not_finished; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &deposit->amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + &deposit->deposit_fee), + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &deposit->purse_pub), + GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id", + &serial_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("partner_base_url", + &deposit->exchange_base_url), + NULL), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &deposit->coin_sig), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &deposit->h_age_commitment), + &deposit->no_age_commitment), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_bool ("refunded", + &deposit->refunded), + &not_finished), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &deposit->h_denom_pub), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (deposit); + chc->failed = true; + return; + } + if (not_finished) + deposit->refunded = false; + /* double-check for all-zeros age commitment */ + if (! deposit->no_age_commitment) + deposit->no_age_commitment + = GNUNET_is_zero (&deposit->h_age_commitment); + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_PURSE_DEPOSIT; + tl->details.purse_deposit = deposit; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_coin_melt (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_MeltListEntry *melt; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + melt = GNUNET_new (struct TALER_EXCHANGEDB_MeltListEntry); + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("rc", + &melt->rc), + /* oldcoin_index not needed */ + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &melt->h_denom_pub), + GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig", + &melt->coin_sig), + GNUNET_PQ_result_spec_auto_from_type ("refresh_seed", + &melt->refresh_seed), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("blinding_seed", + &melt->blinding_seed), + &melt->no_blinding_seed), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &melt->amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh", + &melt->melt_fee), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &melt->h_age_commitment), + &melt->no_age_commitment), + GNUNET_PQ_result_spec_uint64 ("refresh_id", + &serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (melt); + chc->failed = true; + return; + } + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_MELT; + tl->details.melt = melt; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_coin_refund (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_RefundListEntry *refund; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + refund = GNUNET_new (struct TALER_EXCHANGEDB_RefundListEntry); + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", + &refund->merchant_pub), + GNUNET_PQ_result_spec_auto_from_type ("merchant_sig", + &refund->merchant_sig), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &refund->h_contract_terms), + GNUNET_PQ_result_spec_uint64 ("rtransaction_id", + &refund->rtransaction_id), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &refund->refund_amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund", + &refund->refund_fee), + GNUNET_PQ_result_spec_uint64 ("refund_serial_id", + &serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (refund); + chc->failed = true; + return; + } + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_REFUND; + tl->details.refund = refund; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_coin_purse_decision (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_PurseRefundListEntry *prefund; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + prefund = GNUNET_new (struct TALER_EXCHANGEDB_PurseRefundListEntry); + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &prefund->purse_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &prefund->refund_amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund", + &prefund->refund_fee), + GNUNET_PQ_result_spec_uint64 ("purse_decision_serial_id", + &serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (prefund); + chc->failed = true; + return; + } + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_PURSE_REFUND; + tl->details.purse_refund = prefund; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_old_coin_recoup (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_RecoupRefreshListEntry *recoup; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + recoup = GNUNET_new (struct TALER_EXCHANGEDB_RecoupRefreshListEntry); + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", + &recoup->coin.coin_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &recoup->coin_sig), + GNUNET_PQ_result_spec_auto_from_type ("coin_blind", + &recoup->coin_blind), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &recoup->value), + GNUNET_PQ_result_spec_timestamp ("recoup_timestamp", + &recoup->timestamp), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &recoup->coin.denom_pub_hash), + TALER_PQ_result_spec_denom_sig ("denom_sig", + &recoup->coin.denom_sig), + GNUNET_PQ_result_spec_uint64 ("recoup_refresh_uuid", + &serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (recoup); + chc->failed = true; + return; + } + recoup->old_coin_pub = *chc->coin_pub; + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_RECOUP_REFRESH_RECEIVER; + tl->details.old_coin_recoup = recoup; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_coin_recoup (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_RecoupListEntry *recoup; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + recoup = GNUNET_new (struct TALER_EXCHANGEDB_RecoupListEntry); + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &recoup->reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &recoup->coin_sig), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &recoup->h_denom_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_blind", + &recoup->coin_blind), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &recoup->value), + GNUNET_PQ_result_spec_timestamp ("recoup_timestamp", + &recoup->timestamp), + GNUNET_PQ_result_spec_uint64 ("recoup_uuid", + &serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (recoup); + chc->failed = true; + return; + } + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_RECOUP_WITHDRAW; + tl->details.recoup = recoup; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_coin_recoup_refresh (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_RecoupRefreshListEntry *recoup; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + recoup = GNUNET_new (struct TALER_EXCHANGEDB_RecoupRefreshListEntry); + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub", + &recoup->old_coin_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &recoup->coin_sig), + GNUNET_PQ_result_spec_auto_from_type ("coin_blind", + &recoup->coin_blind), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &recoup->value), + GNUNET_PQ_result_spec_timestamp ("recoup_timestamp", + &recoup->timestamp), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &recoup->coin.denom_pub_hash), + TALER_PQ_result_spec_denom_sig ("denom_sig", + &recoup->coin.denom_sig), + GNUNET_PQ_result_spec_uint64 ("recoup_refresh_uuid", + &serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (recoup); + chc->failed = true; + return; + } + recoup->coin.coin_pub = *chc->coin_pub; + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_RECOUP_REFRESH; + tl->details.recoup_refresh = recoup; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct CoinHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +add_coin_reserve_open (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_ReserveOpenListEntry *role; + struct TALER_EXCHANGEDB_TransactionList *tl; + uint64_t serial_id; + + role = GNUNET_new (struct TALER_EXCHANGEDB_ReserveOpenListEntry); + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", + &role->reserve_sig), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &role->coin_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ("contribution", + &role->coin_contribution), + GNUNET_PQ_result_spec_uint64 ("reserve_open_deposit_uuid", + &serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + GNUNET_free (role); + chc->failed = true; + return; + } + } + tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); + tl->next = chc->head; + tl->type = TALER_EXCHANGEDB_TT_RESERVE_OPEN; + tl->details.reserve_open = role; + tl->serial_id = serial_id; + tl->coin_history_id = chc->chid; + chc->head = tl; + } +} + + +/** + * Work we need to do. + */ +struct Work +{ + /** + * Name of the table. + */ + const char *table; + + /** + * SQL prepared statement name. + */ + const char *statement; + + /** + * Function to call to handle the result(s). + */ + GNUNET_PQ_PostgresResultHandler cb; +}; + + +/** + * We found a coin history entry. Lookup details + * from the respective table and store in @a cls. + * + * @param[in,out] cls a `struct CoinHistoryContext` + * @param result a coin history entry result set + * @param num_results total number of results in @a results + */ +static void +handle_history_entry (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinHistoryContext *chc = cls; + struct EXCHANGEDB_PostgresContext *ctx = chc->ctx; + static const struct Work work[] = { + [TALER_EXCHANGEDB_TT_DEPOSIT] = + { "coin_deposits", + "get_deposit_with_coin_pub", + &add_coin_deposit }, + [TALER_EXCHANGEDB_TT_MELT] = + { "refresh", + "get_refresh_by_coin", + &add_coin_melt }, + [TALER_EXCHANGEDB_TT_PURSE_DEPOSIT] = + { "purse_deposits", + "get_purse_deposit_by_coin_pub", + &add_coin_purse_deposit }, + [TALER_EXCHANGEDB_TT_PURSE_REFUND] = + { "purse_decision", + "get_purse_decision_by_coin_pub", + &add_coin_purse_decision }, + [TALER_EXCHANGEDB_TT_REFUND] = + { "refunds", + "get_refunds_by_coin", + &add_coin_refund }, + [TALER_EXCHANGEDB_TT_RECOUP_WITHDRAW] = + { "recoup", + "recoup_by_coin", + &add_coin_recoup }, + [TALER_EXCHANGEDB_TT_RECOUP_REFRESH] = + { "recoup_refresh::NEW", + "recoup_by_refreshed_coin", + &add_coin_recoup_refresh }, + [TALER_EXCHANGEDB_TT_RECOUP_REFRESH_RECEIVER] = + { "recoup_refresh::OLD", + "recoup_by_old_coin", + &add_old_coin_recoup }, + [TALER_EXCHANGEDB_TT_RESERVE_OPEN] = + { "reserves_open_deposits", + "reserve_open_by_coin", + &add_coin_reserve_open }, + { NULL, NULL, NULL } + }; + char *table_name; + uint64_t serial_id; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("table_name", + &table_name), + GNUNET_PQ_result_spec_uint64 ("serial_id", + &serial_id), + GNUNET_PQ_result_spec_uint64 ("coin_history_serial_id", + &chc->chid), + GNUNET_PQ_result_spec_end + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (chc->coin_pub), + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + + for (unsigned int i = 0; i<num_results; i++) + { + enum GNUNET_DB_QueryStatus qs; + bool found = false; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + chc->failed = true; + return; + } + + for (unsigned int s = 0; + NULL != work[s].statement; + s++) + { + if (0 != strcmp (table_name, + work[s].table)) + continue; + found = true; + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + work[s].statement, + params, + work[s].cb, + chc); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Coin %s had %d transactions at %llu in table %s\n", + TALER_B2S (chc->coin_pub), + (int) qs, + (unsigned long long) serial_id, + table_name); + if (0 > qs) + chc->failed = true; + break; + } + if (! found) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Coin history includes unsupported table `%s`\n", + table_name); + chc->failed = true; + } + GNUNET_PQ_cleanup_result (rs); + if (chc->failed) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_coin_transactions (struct EXCHANGEDB_PostgresContext *ctx, + bool begin_transaction, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + uint64_t start_off, + uint64_t etag_in, + uint64_t *etag_out, + struct TALER_Amount *balance, + struct TALER_DenominationHashP *h_denom_pub, + struct TALER_EXCHANGEDB_TransactionList **tlp) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_QueryParam lparams[] = { + GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_uint64 (&start_off), + GNUNET_PQ_query_param_end + }; + struct CoinHistoryContext chc = { + .head = NULL, + .coin_pub = coin_pub, + .ctx = ctx + }; + + *tlp = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Getting transactions for coin %s\n", + TALER_B2S (coin_pub)); + PREPARE (ctx, + "get_coin_history_etag_balance", + "SELECT" + " ch.coin_history_serial_id" + ",kc.remaining" + ",denom.denom_pub_hash" + " FROM coin_history ch" + " JOIN known_coins kc" + " USING (coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " WHERE coin_pub=$1" + " ORDER BY coin_history_serial_id DESC" + " LIMIT 1;"); + PREPARE (ctx, + "get_coin_history", + "SELECT" + " table_name" + ",serial_id" + ",coin_history_serial_id" + " FROM coin_history" + " WHERE coin_pub=$1" + " AND coin_history_serial_id > $2" + " ORDER BY coin_history_serial_id DESC;"); + PREPARE (ctx, + "get_deposit_with_coin_pub", + "SELECT" + " cdep.amount_with_fee" + ",denoms.fee_deposit" + ",denoms.denom_pub_hash" + ",kc.age_commitment_hash" + ",bdep.wallet_timestamp" + ",bdep.refund_deadline" + ",bdep.wire_deadline" + ",bdep.merchant_pub" + ",bdep.h_contract_terms" + ",bdep.wallet_data_hash" + ",bdep.wire_salt" + ",wt.payto_uri" + ",cdep.coin_sig" + ",cdep.coin_deposit_serial_id" + ",bdep.done" + " FROM coin_deposits cdep" + " JOIN batch_deposits bdep" + " USING (batch_deposit_serial_id)" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " JOIN known_coins kc" + " ON (kc.coin_pub = cdep.coin_pub)" + " JOIN denominations denoms" + " USING (denominations_serial)" + " WHERE cdep.coin_pub=$1" + " AND cdep.coin_deposit_serial_id=$2;"); + PREPARE (ctx, + "get_refresh_by_coin", + "SELECT" + " rc" + ",refresh_seed" + ",blinding_seed" + ",old_coin_sig" + ",amount_with_fee" + ",denoms.denom_pub_hash" + ",denoms.fee_refresh" + ",kc.age_commitment_hash" + ",refresh_id" + " FROM refresh" + " JOIN known_coins kc" + " ON (refresh.old_coin_pub = kc.coin_pub)" + " JOIN denominations denoms" + " USING (denominations_serial)" + " WHERE old_coin_pub=$1" + " AND refresh_id=$2;"); + PREPARE (ctx, + "get_purse_deposit_by_coin_pub", + "SELECT" + " partner_base_url" + ",pd.amount_with_fee" + ",denoms.fee_deposit" + ",denoms.denom_pub_hash" + ",pd.purse_pub" + ",kc.age_commitment_hash" + ",pd.coin_sig" + ",pd.purse_deposit_serial_id" + ",pdes.refunded" + " FROM purse_deposits pd" + " LEFT JOIN partners" + " USING (partner_serial_id)" + " JOIN purse_requests pr" + " USING (purse_pub)" + " LEFT JOIN purse_decision pdes" + " USING (purse_pub)" + " JOIN known_coins kc" + " ON (pd.coin_pub = kc.coin_pub)" + " JOIN denominations denoms" + " USING (denominations_serial)" + " WHERE pd.purse_deposit_serial_id=$2" + " AND pd.coin_pub=$1;"); + PREPARE (ctx, + "get_purse_decision_by_coin_pub", + "SELECT" + " pdes.purse_pub" + ",pd.amount_with_fee" + ",denom.fee_refund" + ",pdes.purse_decision_serial_id" + " FROM purse_decision pdes" + " JOIN purse_deposits pd" + " USING (purse_pub)" + " JOIN known_coins kc" + " ON (pd.coin_pub = kc.coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " WHERE pd.coin_pub=$1" + " AND pdes.purse_decision_serial_id=$2" + " AND pdes.refunded;"); + PREPARE (ctx, + "get_refunds_by_coin", + "SELECT" + " bdep.merchant_pub" + ",ref.merchant_sig" + ",bdep.h_contract_terms" + ",ref.rtransaction_id" + ",ref.amount_with_fee" + ",denom.fee_refund" + ",ref.refund_serial_id" + " FROM refunds ref" + " JOIN coin_deposits cdep" + " ON (ref.coin_pub = cdep.coin_pub AND ref.batch_deposit_serial_id = cdep.batch_deposit_serial_id)" + " JOIN batch_deposits bdep" + " ON (ref.batch_deposit_serial_id = bdep.batch_deposit_serial_id)" + " JOIN known_coins kc" + " ON (ref.coin_pub = kc.coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " WHERE ref.coin_pub=$1" + " AND ref.refund_serial_id=$2;"); + PREPARE (ctx, + "recoup_by_old_coin", + "SELECT" + " coins.coin_pub" + ",rr.coin_sig" + ",rr.coin_blind" + ",rr.amount" + ",rr.recoup_timestamp" + ",denoms.denom_pub_hash" + ",coins.denom_sig" + ",rr.recoup_refresh_uuid" + " FROM recoup_refresh rr" + " JOIN known_coins coins" + " USING (coin_pub)" + " JOIN denominations denoms" + " USING (denominations_serial)" + " WHERE recoup_refresh_uuid=$2" + " AND refresh_id IN" + " (SELECT refresh_id" + " FROM refresh" + " WHERE refresh.old_coin_pub=$1);"); + PREPARE (ctx, + "recoup_by_coin", + "SELECT" + " res.reserve_pub" + ",denoms.denom_pub_hash" + ",rcp.coin_sig" + ",rcp.coin_blind" + ",rcp.amount" + ",rcp.recoup_timestamp" + ",rcp.recoup_uuid" + " FROM recoup rcp" + " JOIN withdraw ro" + " USING (withdraw_id)" + " JOIN reserves res" + " USING (reserve_pub)" + " JOIN known_coins coins" + " USING (coin_pub)" + " JOIN denominations denoms" + " ON (denoms.denominations_serial = coins.denominations_serial)" + " WHERE rcp.recoup_uuid=$2" + " AND coins.coin_pub=$1;"); + /* Used to obtain recoup transactions + for a refreshed coin */ + PREPARE (ctx, + "recoup_by_refreshed_coin", + "SELECT" + " old_coins.coin_pub AS old_coin_pub" + ",rr.coin_sig" + ",rr.coin_blind" + ",rr.amount" + ",rr.recoup_timestamp" + ",denoms.denom_pub_hash" + ",coins.denom_sig" + ",recoup_refresh_uuid" + " FROM recoup_refresh rr" + " JOIN refresh rfc" + " ON (rr.refresh_id = rfc.refresh_id)" + " JOIN known_coins old_coins" + " ON (rfc.old_coin_pub = old_coins.coin_pub)" + " JOIN known_coins coins" + " ON (rr.coin_pub = coins.coin_pub)" + " JOIN denominations denoms" + " ON (denoms.denominations_serial = coins.denominations_serial)" + " WHERE rr.recoup_refresh_uuid=$2" + " AND coins.coin_pub=$1;"); + PREPARE (ctx, + "reserve_open_by_coin", + "SELECT" + " reserve_open_deposit_uuid" + ",coin_sig" + ",reserve_sig" + ",contribution" + " FROM reserves_open_deposits" + " WHERE coin_pub=$1" + " AND reserve_open_deposit_uuid=$2;"); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + " --- landed here 1\n"); + for (unsigned int i = 0; i<RETRIES; i++) + { + enum GNUNET_DB_QueryStatus qs; + uint64_t end; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("coin_history_serial_id", + &end), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + h_denom_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("remaining", + balance), + GNUNET_PQ_result_spec_end + }; + + if (begin_transaction) + { + if (GNUNET_OK != + EXCHANGEDB_start_read_committed (ctx, + "get-coin-transactions")) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + } + /* First only check the last item, to see if + we even need to iterate */ + qs = GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "get_coin_history_etag_balance", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + if (begin_transaction) + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + if (begin_transaction) + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + if (begin_transaction) + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + *etag_out = end; + if (end == etag_in) + return qs; + } + /* We indeed need to iterate over the history */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Current ETag for coin %s is %llu\n", + TALER_B2S (coin_pub), + (unsigned long long) end); + + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "get_coin_history", + lparams, + &handle_history_entry, + &chc); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + if (begin_transaction) + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + if (begin_transaction) + EXCHANGEDB_rollback (ctx); + continue; + default: + break; + } + if (chc.failed) + { + if (begin_transaction) + EXCHANGEDB_rollback (ctx); + TEH_COMMON_free_coin_transaction_list (ctx, + chc.head); + return GNUNET_DB_STATUS_SOFT_ERROR; + } + if (! begin_transaction) + { + *tlp = chc.head; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } + qs = EXCHANGEDB_commit (ctx); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + TEH_COMMON_free_coin_transaction_list (ctx, + chc.head); + chc.head = NULL; + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + TEH_COMMON_free_coin_transaction_list (ctx, + chc.head); + chc.head = NULL; + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + *tlp = chc.head; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + " --- landed here 2\n"); + return GNUNET_DB_STATUS_SOFT_ERROR; +} diff --git a/src/exchangedb/get_denomination_by_serial.c b/src/exchangedb/get_denomination_by_serial.c @@ -0,0 +1,88 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_denomination_by_serial.c + * @brief Implementation of the get_denomination_by_serial function for Postgres + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_denomination_by_serial.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_denomination_by_serial (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t denom_serial, + struct TALER_EXCHANGEDB_DenominationKeyInformation *issue) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&denom_serial), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &issue->signature), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &issue->denom_hash), + 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), + GNUNET_PQ_result_spec_uint32 ("age_mask", + &issue->age_mask.bits), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "denomination_get_by_serial", + "SELECT" + " master_sig" + ",denom_pub_hash" + ",valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" /* value of this denom */ + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ",age_mask" + " FROM denominations" + " WHERE denominations_serial=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "denomination_get_by_serial", + params, + rs); +} diff --git a/src/exchangedb/get_denomination_info.c b/src/exchangedb/get_denomination_info.c @@ -0,0 +1,97 @@ +/* + This file is part of TALER + Copyright (C) 2022,2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_denomination_info.c + * @brief Implementation of the get_denomination_info function for Postgres + * @author Christian Grothoff + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_denomination_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_denomination_info (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + uint64_t *denom_serial, + struct TALER_EXCHANGEDB_DenominationKeyInformation *issue) +{ + enum GNUNET_DB_QueryStatus qs; + uint64_t serial; + 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 ("denominations_serial", + &serial), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &issue->signature), + 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), + GNUNET_PQ_result_spec_uint32 ("age_mask", + &issue->age_mask.bits), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "denomination_get", + "SELECT" + " denominations_serial" + ",master_sig" + ",valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" /* value of this denom */ + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ",age_mask" + " FROM denominations" + " WHERE denom_pub_hash=$1;"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "denomination_get", + params, + rs); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + return qs; + issue->denom_hash = *denom_pub_hash; + if (NULL != denom_serial) + *denom_serial = serial; + return qs; +} diff --git a/src/exchangedb/get_denomination_revocation.c b/src/exchangedb/get_denomination_revocation.c @@ -0,0 +1,61 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_denomination_revocation.c + * @brief Implementation of the get_denomination_revocation function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_denomination_revocation.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_denomination_revocation (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + struct TALER_MasterSignatureP *master_sig, + uint64_t *rowid) +{ + 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_auto_from_type ("master_sig", + master_sig), + GNUNET_PQ_result_spec_uint64 ("denom_revocations_serial_id", + rowid), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "denomination_revocation_get", + "SELECT" + " master_sig" + ",denom_revocations_serial_id" + " FROM denomination_revocations" + " WHERE denominations_serial=" + " (SELECT denominations_serial" + " FROM denominations" + " WHERE denom_pub_hash=$1);"); + + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "denomination_revocation_get", + params, + rs); +} diff --git a/src/exchangedb/get_drain_profit.c b/src/exchangedb/get_drain_profit.c @@ -0,0 +1,74 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_drain_profit.c + * @brief Implementation of the get_drain_profit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_drain_profit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_drain_profit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_WireTransferIdentifierRawP *wtid, + uint64_t *serial, + char **account_section, + struct TALER_FullPayto *payto_uri, + struct GNUNET_TIME_Timestamp *request_timestamp, + struct TALER_Amount *amount, + struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("profit_drain_serial_id", + serial), + GNUNET_PQ_result_spec_string ("account_section", + account_section), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri->full_payto), + GNUNET_PQ_result_spec_timestamp ("trigger_date", + request_timestamp), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + amount), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + master_sig), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "get_profit_drain", + "SELECT" + " profit_drain_serial_id" + ",account_section" + ",payto_uri" + ",trigger_date" + ",amount" + ",master_sig" + " FROM profit_drains" + " WHERE wtid=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_profit_drain", + params, + rs); +} diff --git a/src/exchangedb/get_expired_reserves.c b/src/exchangedb/get_expired_reserves.c @@ -0,0 +1,171 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_expired_reserves.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_expired_reserves.h" +#include "pg_helper.h" + + +/** + * Closure for #reserve_expired_cb(). + */ +struct ExpiredReserveContext +{ + /** + * Function to call for each expired reserve. + */ + TALER_EXCHANGEDB_ReserveExpiredCallback rec; + + /** + * Closure to give to @e rec. + */ + void *rec_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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 +reserve_expired_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ExpiredReserveContext *erc = cls; + struct EXCHANGEDB_PostgresContext *ctx = erc->ctx; + enum GNUNET_GenericReturnValue ret = GNUNET_OK; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_TIME_Timestamp exp_date; + struct TALER_FullPayto account_details; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_Amount remaining_balance; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_timestamp ("expiration_date", + &exp_date), + GNUNET_PQ_result_spec_string ("account_details", + &account_details.full_payto), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + TALER_PQ_result_spec_amount ("current_balance", + ctx->currency, + &remaining_balance), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ret = GNUNET_SYSERR; + break; + } + ret = erc->rec (erc->rec_cls, + &reserve_pub, + &remaining_balance, + account_details, + exp_date, + 0); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } + erc->status = ret; +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_expired_reserves (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp now, + TALER_EXCHANGEDB_ReserveExpiredCallback rec, + void *rec_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_end + }; + struct ExpiredReserveContext ectx = { + .rec = rec, + .rec_cls = rec_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "get_expired_reserves", + "WITH ed AS MATERIALIZED ( " + " SELECT expiration_date" + " ,wire_source_h_payto" + " ,current_balance" + " ,r.reserve_pub" + " FROM reserves r" + " JOIN reserves_in" + " USING (reserve_pub)" + " WHERE expiration_date <= $1 " + " AND ((current_balance).val != 0 OR (current_balance).frac != 0) " + " ORDER BY expiration_date ASC " + " LIMIT 1 " + ") " + "SELECT" + " wt.payto_uri AS account_details" + " ,ed.expiration_date" + " ,ed.reserve_pub" + " ,ed.current_balance" + " FROM wire_targets wt" + " JOIN ed" + " ON (ed.wire_source_h_payto=wt.wire_target_h_payto);"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "get_expired_reserves", + params, + &reserve_expired_cb, + &ectx); + switch (ectx.status) + { + case GNUNET_SYSERR: + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_NO: + return GNUNET_DB_STATUS_SOFT_ERROR; + case GNUNET_OK: + break; + } + return qs; +} diff --git a/src/exchangedb/get_extension_manifest.c b/src/exchangedb/get_extension_manifest.c @@ -0,0 +1,66 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_extension_manifest.c + * @brief Implementation of the get_extension_manifest function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_extension_manifest.h" +#include "pg_helper.h" + +/** + * Function called to get the manifest of an extension + * (age-restriction, policy_extension_...) + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param extension_name the name of the extension + * @param[out] manifest JSON object of the manifest as string + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_extension_manifest (struct EXCHANGEDB_PostgresContext *ctx, + const char *extension_name, + char **manifest) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (extension_name), + GNUNET_PQ_query_param_end + }; + bool is_null; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("manifest", + manifest), + &is_null), + GNUNET_PQ_result_spec_end + }; + + *manifest = NULL; + PREPARE (ctx, + "get_extension_manifest", + "SELECT" + " manifest" + " FROM extensions" + " WHERE name=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_extension_manifest", + params, + rs); +} diff --git a/src/exchangedb/get_global_fee.c b/src/exchangedb/get_global_fee.c @@ -0,0 +1,85 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_global_fee.c + * @brief Implementation of the get_global_fee function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_global_fee.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_global_fee (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp date, + struct GNUNET_TIME_Timestamp *start_date, + struct GNUNET_TIME_Timestamp *end_date, + struct TALER_GlobalFeeSet *fees, + struct GNUNET_TIME_Relative *purse_timeout, + struct GNUNET_TIME_Relative *history_expiration, + uint32_t *purse_account_limit, + struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_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 + }; + + PREPARE (ctx, + "get_global_fee", + "SELECT " + " start_date" + ",end_date" + ",history_fee" + ",account_fee" + ",purse_fee" + ",purse_timeout" + ",history_expiration" + ",purse_account_limit" + ",master_sig" + " FROM global_fee" + " WHERE start_date <= $1" + " AND end_date > $1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_global_fee", + params, + rs); +} diff --git a/src/exchangedb/get_global_fees.c b/src/exchangedb/get_global_fees.c @@ -0,0 +1,164 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_global_fees.c + * @brief Implementation of the get_global_fees function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_global_fees.h" +#include "pg_helper.h" + + +/** + * 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 EXCHANGEDB_PostgresContext *ctx; + + /** + * 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 (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct GlobalFeeContext *gctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = gctx->ctx; + + 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); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_global_fees (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_GlobalFeeCallback cb, + void *cb_cls) +{ + struct GNUNET_TIME_Timestamp date + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_subtract ( + GNUNET_TIME_absolute_get (), + GNUNET_TIME_UNIT_YEARS)); + 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, + .ctx = ctx, + .status = GNUNET_OK + }; + + PREPARE (ctx, + "get_global_fees", + "SELECT " + " start_date" + ",end_date" + ",history_fee" + ",account_fee" + ",purse_fee" + ",purse_timeout" + ",history_expiration" + ",purse_account_limit" + ",master_sig" + " FROM global_fee" + " WHERE start_date >= $1"); + return GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "get_global_fees", + params, + &global_fees_cb, + &gctx); +} diff --git a/src/exchangedb/get_known_coin.c b/src/exchangedb/get_known_coin.c @@ -0,0 +1,66 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_known_coin.c + * @brief Implementation of the get_known_coin function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_known_coin.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_known_coin (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct TALER_CoinPublicInfo *coin_info) +{ + 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", + &coin_info->denom_pub_hash), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &coin_info->h_age_commitment), + &coin_info->no_age_commitment), + TALER_PQ_result_spec_denom_sig ("denom_sig", + &coin_info->denom_sig), + GNUNET_PQ_result_spec_end + }; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Getting known coin data for coin %s\n", + TALER_B2S (coin_pub)); + coin_info->coin_pub = *coin_pub; + PREPARE (ctx, + "get_known_coin", + "SELECT" + " denominations.denom_pub_hash" + ",age_commitment_hash" + ",denom_sig" + " FROM known_coins" + " JOIN denominations USING (denominations_serial)" + " WHERE coin_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_known_coin", + params, + rs); +} diff --git a/src/exchangedb/get_kyc_rules.c b/src/exchangedb/get_kyc_rules.c @@ -0,0 +1,125 @@ +/* + This file is part of TALER + Copyright (C) 2022-2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_kyc_rules.c + * @brief Implementation of the get_kyc_rules function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_kyc_rules.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_kyc_rules (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, + bool *no_account_pub, + union TALER_AccountPublicKeyP *account_pub, + bool *no_reserve_pub, + struct TALER_ReservePublicKeyP *reserve_pub, + json_t **jrules) +{ + struct GNUNET_TIME_Timestamp now + = GNUNET_TIME_timestamp_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_timestamp (&now), + NULL != merchant_pub + ? GNUNET_PQ_query_param_auto_from_type (merchant_pub) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("target_pub", + account_pub), + no_account_pub), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + reserve_pub), + no_reserve_pub), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("jnew_rules", + jrules), + NULL), + GNUNET_PQ_result_spec_end + }; + + *jrules = NULL; + *no_account_pub = true; + *no_reserve_pub = true; + memset (account_pub, + 0, + sizeof (*account_pub)); + memset (reserve_pub, + 0, + sizeof (*reserve_pub)); + PREPARE (ctx, + "get_kyc_rules", + "SELECT" + " out_target_pub AS target_pub" + " ,out_jnew_rules::TEXT AS jnew_rules" + " ,out_reserve_pub AS reserve_pub" + " FROM exchange_do_get_kyc_rules ($1,$2,$3);"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "get_kyc_rules", + params, + rs); +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_kyc_rules2 (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + json_t **jrules) +{ + struct GNUNET_TIME_Timestamp now + = GNUNET_TIME_timestamp_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("jnew_rules", + jrules), + NULL), + GNUNET_PQ_result_spec_end + }; + + *jrules = NULL; + PREPARE (ctx, + "get_kyc_rules2", + "SELECT" + " jnew_rules::TEXT" + " FROM legitimization_outcomes" + " WHERE h_payto=$1" + " AND expiration_time >= $2" + " AND is_active" + " ORDER BY expiration_time DESC" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "get_kyc_rules2", + params, + rs); +} diff --git a/src/exchangedb/get_old_coin_by_h_blind.c b/src/exchangedb/get_old_coin_by_h_blind.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_old_coin_by_h_blind.c + * @brief Implementation of the get_old_coin_by_h_blind function for Postgres + * @author Christian Grothoff + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_old_coin_by_h_blind.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_old_coin_by_h_blind (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_BlindedCoinHashP *h_blind_ev, + struct TALER_CoinSpendPublicKeyP *old_coin_pub, + uint64_t *refresh_id) +{ + 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), + GNUNET_PQ_result_spec_uint64 ("refresh_id", + refresh_id), + GNUNET_PQ_result_spec_end + }; + + /* Used in #postgres_get_old_coin_by_h_blind() */ + PREPARE (ctx, + "old_coin_by_h_blind", + "SELECT" + " okc.coin_pub AS old_coin_pub" + ",refresh_id" + " FROM refresh " + " JOIN known_coins okc ON (refresh.old_coin_pub = okc.coin_pub)" + " WHERE $1=ANY(h_blind_evs)" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "old_coin_by_h_blind", + params, + rs); +} diff --git a/src/exchangedb/get_pending_kyc_requirement_process.c b/src/exchangedb/get_pending_kyc_requirement_process.c @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_pending_kyc_requirement_process.c + * @brief Implementation of the get_pending_kyc_requirement_process function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_pending_kyc_requirement_process.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_pending_kyc_requirement_process (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_name, + char **redirect_url) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (provider_name), + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("redirect_url", + redirect_url), + NULL), + GNUNET_PQ_result_spec_end + }; + + *redirect_url = NULL; + PREPARE (ctx, + "get_pending_kyc_requirement_process", + "SELECT" + " redirect_url" + " FROM legitimization_processes" + " WHERE provider_name=$1" + " AND h_payto=$2" + " AND NOT finished" + " ORDER BY start_time DESC" + " LIMIT 1"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "get_pending_kyc_requirement_process", + params, + rs); +} diff --git a/src/exchangedb/get_policy_details.c b/src/exchangedb/get_policy_details.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_policy_details.c + * @brief Implementation of the get_policy_details function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_policy_details.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_policy_details (struct EXCHANGEDB_PostgresContext *ctx, + const struct GNUNET_HashCode *hc, + struct TALER_PolicyDetails *details) +{ + 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 (ctx->conn, + "get_policy_details", + params, + rs); +} diff --git a/src/exchangedb/get_purse_deposit.c b/src/exchangedb/get_purse_deposit.c @@ -0,0 +1,82 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_purse_deposit.c + * @brief Implementation of the get_purse_deposit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_purse_deposit.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_purse_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct TALER_Amount *amount, + struct TALER_DenominationHashP *h_denom_pub, + struct TALER_AgeCommitmentHashP *phac, + struct TALER_CoinSpendSignatureP *coin_sig, + char **partner_url) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_end + }; + bool is_null; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + h_denom_pub), + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + phac), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + coin_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + amount), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("partner_base_url", + partner_url), + &is_null), + GNUNET_PQ_result_spec_end + }; + + *partner_url = NULL; + PREPARE (ctx, + "select_purse_deposit_by_coin_pub", + "SELECT " + " coin_sig" + ",amount_with_fee" + ",denom_pub_hash" + ",age_commitment_hash" + ",partner_base_url" + " FROM purse_deposits" + " LEFT JOIN partners" + " USING (partner_serial_id)" + " JOIN known_coins kc" + " USING (coin_pub)" + " JOIN denominations" + " USING (denominations_serial)" + " WHERE purse_pub=$1" + " AND coin_pub=$2;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "select_purse_deposit_by_coin_pub", + params, + rs); +} diff --git a/src/exchangedb/get_purse_request.c b/src/exchangedb/get_purse_request.c @@ -0,0 +1,77 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_template.c + * @brief Implementation of the template function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_purse_request.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_purse_request (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseMergePublicKeyP *merge_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) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("merge_pub", + merge_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 + }; + + PREPARE (ctx, + "get_purse_request", + "SELECT " + " merge_pub" + ",purse_expiration" + ",h_contract_terms" + ",age_limit" + ",amount_with_fee" + ",balance" + ",purse_sig" + " FROM purse_requests" + " WHERE purse_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_purse_request", + params, + rs); +} diff --git a/src/exchangedb/get_ready_deposit.c b/src/exchangedb/get_ready_deposit.c @@ -0,0 +1,80 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_ready_deposit.c + * @brief Implementation of the get_ready_deposit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_ready_deposit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_ready_deposit (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t start_shard_row, + uint64_t end_shard_row, + struct TALER_MerchantPublicKeyP *merchant_pub, + struct TALER_FullPayto *payto_uri, + char **extra_wire_subject_metadata) +{ + struct GNUNET_TIME_Absolute now + = GNUNET_TIME_absolute_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_uint64 (&start_shard_row), + GNUNET_PQ_query_param_uint64 (&end_shard_row), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", + merchant_pub), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri->full_payto), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("extra_wire_subject_metadata", + extra_wire_subject_metadata), + NULL), + GNUNET_PQ_result_spec_end + }; + const char *query = "deposits_get_ready"; + + *extra_wire_subject_metadata = NULL; + PREPARE (ctx, + query, + "SELECT" + " wts.payto_uri" + ",bdep.merchant_pub" + ",bdep.extra_wire_subject_metadata" + " FROM batch_deposits bdep" + " JOIN wire_targets wts" + " USING (wire_target_h_payto)" + " WHERE NOT (bdep.done OR bdep.policy_blocked)" + " AND bdep.wire_deadline<=$1" + " AND bdep.shard >= $2" + " AND bdep.shard <= $3" + " ORDER BY " + " bdep.wire_deadline ASC" + " ,bdep.shard ASC" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + query, + params, + rs); +} diff --git a/src/exchangedb/get_refresh.c b/src/exchangedb/get_refresh.c @@ -0,0 +1,207 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_refresh.c + * @brief Implementation of the get_refresh function for Postgres + * @author get_refresh + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_refresh.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_refresh (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_RefreshCommitmentP *rc, + struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (rc), + GNUNET_PQ_query_param_end + }; + bool no_cs_r_values; + bool no_cs_r_choices; + bool no_transfer_pubs; + size_t num_denom_sigs; + size_t num_transfer_pubs; + struct TALER_BlindedDenominationSignature *denom_sigs = NULL; + struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values = NULL; + struct TALER_TransferPublicKeyP *transfer_pubs = NULL; + uint64_t *denom_serials = NULL; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &refresh->amount_with_fee), + GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub", + &refresh->coin.coin_pub), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &refresh->coin.h_age_commitment), + &refresh->coin.no_age_commitment), + GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig", + &refresh->coin_sig), + GNUNET_PQ_result_spec_auto_from_type ("refresh_seed", + &refresh->refresh_seed), + GNUNET_PQ_result_spec_uint32 ("noreveal_index", + &refresh->noreveal_index), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("blinding_seed", + &refresh->blinding_seed), + &refresh->no_blinding_seed), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_array_cs_r_pub (ctx->conn, + "cs_r_values", + &refresh->num_cs_r_values, + &cs_r_values), + &no_cs_r_values), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ("cs_r_choices", + &refresh->cs_r_choices), + &no_cs_r_choices), + GNUNET_PQ_result_spec_auto_from_type ("planchets_h", + &refresh->planchets_h), + GNUNET_PQ_result_spec_auto_from_type ("selected_h", + &refresh->selected_h), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_array_fixed_size (ctx->conn, + "transfer_pubs", + sizeof(*transfer_pubs), + &num_transfer_pubs, + (void **) &transfer_pubs), + &no_transfer_pubs), + GNUNET_PQ_result_spec_array_uint64 (ctx->conn, + "denom_serials", + &refresh->num_coins, + &denom_serials), + TALER_PQ_result_spec_array_blinded_denom_sig (ctx->conn, + "denom_sigs", + &num_denom_sigs, + &denom_sigs), + GNUNET_PQ_result_spec_bool ("revealed", + &refresh->revealed), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + memset (&refresh->coin.denom_sig, + 0, + sizeof (refresh->coin.denom_sig)); + PREPARE (ctx, + "get_refresh", + "SELECT" + " amount_with_fee" + ",old_coin_pub" + ",kc.age_commitment_hash AS age_commitment_hash" + ",old_coin_sig" + ",refresh_seed" + ",noreveal_index" + ",blinding_seed" + ",cs_r_values" + ",cs_r_choices" + ",planchets_h" + ",transfer_pubs" + ",selected_h" + ",denom_serials" + ",denom_sigs" + ",revealed" + " FROM refresh" + " JOIN known_coins kc" + " ON (old_coin_pub = kc.coin_pub)" + " WHERE rc = $1;" + ); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_refresh", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + if (0 > qs) + { + GNUNET_break (0); + GNUNET_PQ_cleanup_result (rs); + return qs; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + GNUNET_PQ_cleanup_result (rs); + return qs; + } + if (refresh->num_coins != num_denom_sigs) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "got inconsistent number of entries in refresh from DB: " + "num_coins=%ld, num_denom_sigs=%ld\n", + refresh->num_coins, + num_denom_sigs); + GNUNET_PQ_cleanup_result (rs); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (no_transfer_pubs) + { + refresh->is_v27_refresh = true; + refresh->transfer_pubs = NULL; + } + else + { + if (num_transfer_pubs != refresh->num_coins) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "got inconsistent number of transfer_pubs in refresh from DB: " + "num_coins=%ld, num_transfer_pubs=%ld\n", + refresh->num_coins, + num_transfer_pubs); + GNUNET_PQ_cleanup_result (rs); + return GNUNET_DB_STATUS_HARD_ERROR; + } + refresh->is_v27_refresh = false; + refresh->transfer_pubs = transfer_pubs; + } + if (refresh->no_blinding_seed != no_cs_r_values) + { + GNUNET_break (0); + GNUNET_PQ_cleanup_result (rs); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (no_cs_r_choices != no_cs_r_values) + { + GNUNET_break (0); + GNUNET_PQ_cleanup_result (rs); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (no_cs_r_values) + { + refresh->cs_r_values = NULL; + refresh->num_cs_r_values = 0; + } + if (refresh->coin.no_age_commitment) + memset (&refresh->coin.h_age_commitment, + 0, + sizeof(refresh->coin.h_age_commitment)); + refresh->rc = *rc; + /* move the result arrays */ + refresh->denom_sigs = denom_sigs; + refresh->denom_serials = denom_serials; + refresh->cs_r_values = cs_r_values; + transfer_pubs = NULL; + denom_sigs = NULL; + denom_serials = NULL; + cs_r_values = NULL; + GNUNET_PQ_cleanup_result (rs); + return qs; +} diff --git a/src/exchangedb/get_reserve_balance.c b/src/exchangedb/get_reserve_balance.c @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_reserve_balance.c + * @brief Implementation of the get_reserve_balance function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_reserve_balance.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_reserve_balance (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_Amount *balance, + struct TALER_FullPayto *origin_account) +{ + 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", + ctx->currency, + balance), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("payto_uri", + &origin_account->full_payto), + NULL), + GNUNET_PQ_result_spec_end + }; + + origin_account->full_payto = NULL; + PREPARE (ctx, + "get_reserve_balance", + "SELECT" + " r.current_balance" + " ,wt.payto_uri" + " FROM reserves r" + " LEFT JOIN reserves_in ri" + " USING (reserve_pub)" + " LEFT JOIN wire_targets wt" + " ON (wt.wire_target_h_payto = ri.wire_source_h_payto)" + " WHERE r.reserve_pub=$1" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_reserve_balance", + params, + rs); +} diff --git a/src/exchangedb/get_reserve_by_h_planchets.c b/src/exchangedb/get_reserve_by_h_planchets.c @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2022,2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_reserve_by_h_planchets.c + * @brief Implementation of the get_reserve_by_h_planchets function for Postgres + * @author Christian Grothoff + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_reserve_by_h_planchets.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_reserve_by_h_planchets (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_HashBlindedPlanchetsP *h_planchets, + struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t *withdraw_serial_id) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_planchets), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + reserve_pub), + GNUNET_PQ_result_spec_uint64 ("withdraw_id", + withdraw_serial_id), + GNUNET_PQ_result_spec_end + }; + /* Used in #postgres_get_reserve_by_h_planchets() */ + PREPARE (ctx, + "reserve_by_h_planchets", + "SELECT" + " reserve_pub" + ",withdraw_id" + " FROM withdraw" + " WHERE planchets_h=$1" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "reserve_by_h_planchets", + params, + rs); +} diff --git a/src/exchangedb/get_reserve_history.c b/src/exchangedb/get_reserve_history.c @@ -0,0 +1,998 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_reserve_history.c + * @brief Obtain (parts of) the history of a reserve. + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_reserve_history.h" +#include "pg_start_read_committed.h" +#include "pg_commit.h" +#include "pg_rollback.h" +#include "plugin_exchangedb_common.h" +#include "pg_helper.h" + +/** + * How often do we re-try when encountering DB serialization issues? + * (We are read-only, so can only happen due to concurrent insert, + * which should be very rare.) + */ +#define RETRIES 3 + + +/** + * Closure for callbacks invoked via #EXCHANGEDB_get_reserve_history(). + */ +struct ReserveHistoryContext +{ + + /** + * Which reserve are we building the history for? + */ + const struct TALER_ReservePublicKeyP *reserve_pub; + + /** + * Where we build the history. + */ + struct TALER_EXCHANGEDB_ReserveHistory *rh; + + /** + * Tail of @e rh list. + */ + struct TALER_EXCHANGEDB_ReserveHistory *rh_tail; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Sum of all credit transactions. + */ + struct TALER_Amount balance_in; + + /** + * Sum of all debit transactions. + */ + struct TALER_Amount balance_out; + + /** + * Current reserve_history_serial_id being processed, + * set before each sub-table callback. + */ + uint64_t current_history_offset; + + /** + * Set to true on serious internal errors during + * the callbacks. + */ + bool failed; +}; + + +/** + * Append and return a fresh element to the reserve + * history kept in @a rhc. + * + * @param rhc where the history is kept + * @return the fresh element that was added + */ +static struct TALER_EXCHANGEDB_ReserveHistory * +append_rh (struct ReserveHistoryContext *rhc) +{ + struct TALER_EXCHANGEDB_ReserveHistory *tail; + + tail = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory); + tail->history_offset = rhc->current_history_offset; + if (NULL != rhc->rh_tail) + { + rhc->rh_tail->next = tail; + rhc->rh_tail = tail; + } + else + { + rhc->rh_tail = tail; + rhc->rh = tail; + } + return tail; +} + + +/** + * Add bank transfers to result set for #EXCHANGEDB_get_reserve_history. + * + * @param cls a `struct ReserveHistoryContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +add_bank_to_exchange (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveHistoryContext *rhc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rhc->ctx; + + while (0 < num_results) + { + struct TALER_EXCHANGEDB_BankTransfer *bt; + struct TALER_EXCHANGEDB_ReserveHistory *tail; + + bt = GNUNET_new (struct TALER_EXCHANGEDB_BankTransfer); + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("wire_reference", + &bt->wire_reference), + TALER_PQ_RESULT_SPEC_AMOUNT ("credit", + &bt->amount), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &bt->execution_date), + GNUNET_PQ_result_spec_string ("sender_account_details", + &bt->sender_account_details.full_payto), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + --num_results)) + { + GNUNET_break (0); + GNUNET_free (bt); + rhc->failed = true; + return; + } + } + GNUNET_assert (0 <= + TALER_amount_add (&rhc->balance_in, + &rhc->balance_in, + &bt->amount)); + bt->reserve_pub = *rhc->reserve_pub; + tail = append_rh (rhc); + tail->type = TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE; + tail->details.bank = bt; + } /* end of 'while (0 < rows)' */ +} + + +/** + * Add coin withdrawals to result set for #EXCHANGEDB_get_reserve_history. + * + * @param cls a `struct ReserveHistoryContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +add_withdraw (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveHistoryContext *rhc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rhc->ctx; + + while (0 < num_results) + { + struct TALER_EXCHANGEDB_Withdraw *wd; + struct TALER_EXCHANGEDB_ReserveHistory *tail; + + wd = GNUNET_new (struct TALER_EXCHANGEDB_Withdraw); + { + bool no_noreveal_index; + bool no_max_age; + bool no_selected_h; + size_t num_denom_hs; + size_t num_denom_serials; + uint64_t *my_denom_serials = NULL; + struct TALER_DenominationHashP *my_denom_pub_hashes = NULL; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("planchets_h", + &wd->planchets_h), + GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", + &wd->reserve_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &wd->amount_with_fee), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint16 ("max_age", + &wd->max_age), + &no_max_age), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint16 ("noreveal_index", + &wd->noreveal_index), + &no_noreveal_index), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("blinding_seed", + &wd->blinding_seed), + &wd->no_blinding_seed), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("selected_h", + &wd->selected_h), + &no_selected_h), + TALER_PQ_result_spec_array_denom_hash (ctx->conn, + "denom_pub_hashes", + &num_denom_hs, + &my_denom_pub_hashes), + GNUNET_PQ_result_spec_array_uint64 (ctx->conn, + "denom_serials", + &num_denom_serials, + &my_denom_serials), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + --num_results)) + { + GNUNET_break (0); + GNUNET_free (wd); + rhc->failed = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + + if (num_denom_hs != num_denom_serials) + { + GNUNET_break (0); + GNUNET_free (wd); + rhc->failed = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + + if ((no_noreveal_index != no_max_age) || + (no_noreveal_index != no_selected_h)) + { + GNUNET_break (0); + GNUNET_free (wd); + rhc->failed = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + wd->age_proof_required = ! no_max_age; + wd->num_coins = num_denom_serials; + wd->reserve_pub = *rhc->reserve_pub; + wd->denom_serials = my_denom_serials; + wd->denom_pub_hashes = my_denom_pub_hashes; + /* prevent cleanup from destroying our actual result */ + my_denom_serials = NULL; + my_denom_pub_hashes = NULL; + GNUNET_PQ_cleanup_result (rs); + } + + tail = append_rh (rhc); + tail->type = TALER_EXCHANGEDB_RO_WITHDRAW_COINS; + tail->details.withdraw = wd; + } +} + + +/** + * Add recoups to result set for #EXCHANGEDB_get_reserve_history. + * + * @param cls a `struct ReserveHistoryContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +add_recoup (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveHistoryContext *rhc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rhc->ctx; + + while (0 < num_results) + { + struct TALER_EXCHANGEDB_Recoup *recoup; + struct TALER_EXCHANGEDB_ReserveHistory *tail; + + recoup = GNUNET_new (struct TALER_EXCHANGEDB_Recoup); + { + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &recoup->value), + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", + &recoup->coin.coin_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_blind", + &recoup->coin_blind), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &recoup->coin_sig), + GNUNET_PQ_result_spec_timestamp ("recoup_timestamp", + &recoup->timestamp), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &recoup->coin.denom_pub_hash), + TALER_PQ_result_spec_denom_sig ( + "denom_sig", + &recoup->coin.denom_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + --num_results)) + { + GNUNET_break (0); + GNUNET_free (recoup); + rhc->failed = true; + return; + } + } + GNUNET_assert (0 <= + TALER_amount_add (&rhc->balance_in, + &rhc->balance_in, + &recoup->value)); + recoup->reserve_pub = *rhc->reserve_pub; + tail = append_rh (rhc); + tail->type = TALER_EXCHANGEDB_RO_RECOUP_COIN; + tail->details.recoup = recoup; + } /* end of 'while (0 < rows)' */ +} + + +/** + * Add exchange-to-bank transfers to result set for + * #EXCHANGEDB_get_reserve_history. + * + * @param cls a `struct ReserveHistoryContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +add_exchange_to_bank (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveHistoryContext *rhc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rhc->ctx; + + while (0 < num_results) + { + struct TALER_EXCHANGEDB_ClosingTransfer *closing; + struct TALER_EXCHANGEDB_ReserveHistory *tail; + + closing = GNUNET_new (struct TALER_EXCHANGEDB_ClosingTransfer); + { + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &closing->amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", + &closing->closing_fee), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &closing->execution_date), + GNUNET_PQ_result_spec_string ("receiver_account", + &closing->receiver_account_details. + full_payto), + GNUNET_PQ_result_spec_auto_from_type ("wtid", + &closing->wtid), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + --num_results)) + { + GNUNET_break (0); + GNUNET_free (closing); + rhc->failed = true; + return; + } + } + GNUNET_assert (0 <= + TALER_amount_add (&rhc->balance_out, + &rhc->balance_out, + &closing->amount)); + closing->reserve_pub = *rhc->reserve_pub; + tail = append_rh (rhc); + tail->type = TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK; + tail->details.closing = closing; + } /* end of 'while (0 < rows)' */ +} + + +/** + * Add purse merge transfers to result set for + * #EXCHANGEDB_get_reserve_history. + * + * @param cls a `struct ReserveHistoryContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +add_p2p_merge (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveHistoryContext *rhc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rhc->ctx; + + while (0 < num_results) + { + struct TALER_EXCHANGEDB_PurseMerge *merge; + struct TALER_EXCHANGEDB_ReserveHistory *tail; + + merge = GNUNET_new (struct TALER_EXCHANGEDB_PurseMerge); + { + uint32_t flags32; + struct TALER_Amount balance; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee", + &merge->purse_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + &balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &merge->amount_with_fee), + GNUNET_PQ_result_spec_timestamp ("merge_timestamp", + &merge->merge_timestamp), + GNUNET_PQ_result_spec_timestamp ("purse_expiration", + &merge->purse_expiration), + GNUNET_PQ_result_spec_uint32 ("age_limit", + &merge->min_age), + GNUNET_PQ_result_spec_uint32 ("flags", + &flags32), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &merge->h_contract_terms), + GNUNET_PQ_result_spec_auto_from_type ("merge_pub", + &merge->merge_pub), + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &merge->purse_pub), + GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", + &merge->reserve_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + --num_results)) + { + GNUNET_break (0); + GNUNET_free (merge); + rhc->failed = true; + return; + } + merge->flags = (enum TALER_WalletAccountMergeFlags) flags32; + if ( (! GNUNET_TIME_absolute_is_future ( + merge->merge_timestamp.abs_time)) && + (-1 != TALER_amount_cmp (&balance, + &merge->amount_with_fee)) ) + merge->merged = true; + } + if (merge->merged) + GNUNET_assert (0 <= + TALER_amount_add (&rhc->balance_in, + &rhc->balance_in, + &merge->amount_with_fee)); + GNUNET_assert (0 <= + TALER_amount_add (&rhc->balance_out, + &rhc->balance_out, + &merge->purse_fee)); + merge->reserve_pub = *rhc->reserve_pub; + tail = append_rh (rhc); + tail->type = TALER_EXCHANGEDB_RO_PURSE_MERGE; + tail->details.merge = merge; + } +} + + +/** + * Add paid for history requests to result set for + * #EXCHANGEDB_get_reserve_history. + * + * @param cls a `struct ReserveHistoryContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +add_open_requests (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveHistoryContext *rhc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rhc->ctx; + + while (0 < num_results) + { + struct TALER_EXCHANGEDB_OpenRequest *orq; + struct TALER_EXCHANGEDB_ReserveHistory *tail; + + orq = GNUNET_new (struct TALER_EXCHANGEDB_OpenRequest); + { + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("open_fee", + &orq->open_fee), + GNUNET_PQ_result_spec_timestamp ("request_timestamp", + &orq->request_timestamp), + GNUNET_PQ_result_spec_timestamp ("expiration_date", + &orq->reserve_expiration), + GNUNET_PQ_result_spec_uint32 ("requested_purse_limit", + &orq->purse_limit), + GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", + &orq->reserve_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + --num_results)) + { + GNUNET_break (0); + GNUNET_free (orq); + rhc->failed = true; + return; + } + } + GNUNET_assert (0 <= + TALER_amount_add (&rhc->balance_out, + &rhc->balance_out, + &orq->open_fee)); + orq->reserve_pub = *rhc->reserve_pub; + tail = append_rh (rhc); + tail->type = TALER_EXCHANGEDB_RO_OPEN_REQUEST; + tail->details.open_request = orq; + } +} + + +/** + * Add paid for history requests to result set for + * #EXCHANGEDB_get_reserve_history. + * + * @param cls a `struct ReserveHistoryContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +add_close_requests (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveHistoryContext *rhc = cls; + + while (0 < num_results) + { + struct TALER_EXCHANGEDB_CloseRequest *crq; + struct TALER_EXCHANGEDB_ReserveHistory *tail; + + crq = GNUNET_new (struct TALER_EXCHANGEDB_CloseRequest); + { + struct TALER_FullPayto payto_uri; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_timestamp ("close_timestamp", + &crq->request_timestamp), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri.full_payto), + GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", + &crq->reserve_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + --num_results)) + { + GNUNET_break (0); + GNUNET_free (crq); + rhc->failed = true; + return; + } + TALER_full_payto_hash (payto_uri, + &crq->target_account_h_payto); + GNUNET_free (payto_uri.full_payto); + } + crq->reserve_pub = *rhc->reserve_pub; + tail = append_rh (rhc); + tail->type = TALER_EXCHANGEDB_RO_CLOSE_REQUEST; + tail->details.close_request = crq; + } +} + + +/** + * Add reserve history entries found. + * + * @param cls a `struct ReserveHistoryContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +handle_history_entry (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + static const struct + { + /** + * Table with reserve history entry we are responsible for. + */ + const char *table; + /** + * Name of the prepared statement to run. + */ + const char *statement; + /** + * Function to use to process the results. + */ + GNUNET_PQ_PostgresResultHandler cb; + } work[] = { + /** #TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE */ + { "reserves_in", + "reserves_in_get_transactions", + add_bank_to_exchange }, + /** #TALER_EXCHANGEDB_RO_WITHDRAW_COINS */ + { "withdraw", + "get_withdraw_details", + &add_withdraw }, + /** #TALER_EXCHANGEDB_RO_RECOUP_COIN */ + { "recoup", + "recoup_by_reserve", + &add_recoup }, + /** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */ + { "reserves_close", + "close_by_reserve", + &add_exchange_to_bank }, + /** #TALER_EXCHANGEDB_RO_PURSE_MERGE */ + { "purse_decision", + "merge_by_reserve", + &add_p2p_merge }, + /** #TALER_EXCHANGEDB_RO_OPEN_REQUEST */ + { "reserves_open_requests", + "open_request_by_reserve", + &add_open_requests }, + /** #TALER_EXCHANGEDB_RO_CLOSE_REQUEST */ + { "close_requests", + "close_request_by_reserve", + &add_close_requests }, + /* List terminator */ + { NULL, NULL, NULL } + }; + struct ReserveHistoryContext *rhc = cls; + char *table_name; + uint64_t serial_id; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("table_name", + &table_name), + GNUNET_PQ_result_spec_uint64 ("serial_id", + &serial_id), + GNUNET_PQ_result_spec_uint64 ("reserve_history_serial_id", + &rhc->current_history_offset), + GNUNET_PQ_result_spec_end + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (rhc->reserve_pub), + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + + while (0 < num_results--) + { + enum GNUNET_DB_QueryStatus qs; + bool found = false; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + num_results)) + { + GNUNET_break (0); + rhc->failed = true; + return; + } + + for (unsigned int i = 0; + NULL != work[i].cb; + i++) + { + if (0 != strcmp (table_name, + work[i].table)) + continue; + found = true; + qs = GNUNET_PQ_eval_prepared_multi_select (rhc->ctx->conn, + work[i].statement, + params, + work[i].cb, + rhc); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Reserve %s had %d transactions at %llu in table %s\n", + TALER_B2S (rhc->reserve_pub), + (int) qs, + (unsigned long long) serial_id, + table_name); + if (0 >= qs) + rhc->failed = true; + break; + } + if (! found) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Reserve history includes unsupported table `%s`\n", + table_name); + rhc->failed = true; + } + GNUNET_PQ_cleanup_result (rs); + if (rhc->failed) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_reserve_history (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t start_off, + uint64_t etag_in, + uint64_t *etag_out, + struct TALER_Amount *balance, + struct TALER_EXCHANGEDB_ReserveHistory **rhp) +{ + struct ReserveHistoryContext rhc = { + .ctx = ctx, + .reserve_pub = reserve_pub + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_QueryParam lparams[] = { + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_uint64 (&start_off), + GNUNET_PQ_query_param_end + }; + + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + &rhc.balance_in)); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (ctx->currency, + &rhc.balance_out)); + + *rhp = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Getting transactions for reserve %s\n", + TALER_B2S (reserve_pub)); + PREPARE (ctx, + "get_reserve_history_etag", + "SELECT" + " his.reserve_history_serial_id" + ",r.current_balance" + " FROM reserve_history his" + " JOIN reserves r USING (reserve_pub)" + " WHERE his.reserve_pub=$1" + " ORDER BY reserve_history_serial_id DESC" + " LIMIT 1;"); + PREPARE (ctx, + "get_reserve_history", + "SELECT" + " table_name" + ",serial_id" + ",reserve_history_serial_id" + " FROM reserve_history" + " WHERE reserve_pub=$1" + " AND reserve_history_serial_id > $2" + " ORDER BY reserve_history_serial_id DESC;"); + PREPARE (ctx, + "reserves_in_get_transactions", + "SELECT" + " ri.wire_reference" + ",ri.credit" + ",ri.execution_date" + ",wt.payto_uri AS sender_account_details" + " FROM reserves_in ri" + " JOIN wire_targets wt" + " ON (wire_source_h_payto = wire_target_h_payto)" + " WHERE ri.reserve_pub=$1" + " AND ri.reserve_in_serial_id=$2;"); + PREPARE (ctx, + "get_withdraw_details", + "SELECT" + " planchets_h" + ",amount_with_fee" + ",reserve_sig" + ",max_age" + ",noreveal_index" + ",selected_h" + ",blinding_seed" + ",denom_serials" + ",ARRAY(" + " SELECT denominations.denom_pub_hash FROM (" + " SELECT UNNEST(denom_serials) AS id," + " generate_subscripts(denom_serials, 1) AS nr" /* for order */ + " ) AS denoms" + " LEFT JOIN denominations ON denominations.denominations_serial=denoms.id" + ") AS denom_pub_hashes" + " FROM withdraw " + " WHERE withdraw_id=$2" + " AND reserve_pub=$1;"); + PREPARE (ctx, + "recoup_by_reserve", + "SELECT" + " rec.coin_pub" + ",rec.coin_sig" + ",rec.coin_blind" + ",rec.amount" + ",rec.recoup_timestamp" + ",denom.denom_pub_hash" + ",kc.denom_sig" + " FROM recoup rec" + " JOIN withdraw ro" + " USING (withdraw_id)" + " JOIN reserves res" + " USING (reserve_pub)" + " JOIN known_coins kc" + " USING (coin_pub)" + " JOIN denominations denom" + " ON (denom.denominations_serial = kc.denominations_serial)" + " WHERE rec.recoup_uuid=$2" + " AND res.reserve_pub=$1;"); + PREPARE (ctx, + "close_by_reserve", + "SELECT" + " rc.amount" + ",rc.closing_fee" + ",rc.execution_date" + ",wt.payto_uri AS receiver_account" + ",rc.wtid" + " FROM reserves_close rc" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " WHERE reserve_pub=$1" + " AND close_uuid=$2;"); + PREPARE (ctx, + "merge_by_reserve", + "SELECT" + " pr.amount_with_fee" + ",pr.balance" + ",pr.purse_fee" + ",pr.h_contract_terms" + ",pr.merge_pub" + ",am.reserve_sig" + ",pm.purse_pub" + ",pm.merge_timestamp" + ",pr.purse_expiration" + ",pr.age_limit" + ",pr.flags" + " FROM purse_decision pdes" + " JOIN purse_requests pr" + " ON (pr.purse_pub = pdes.purse_pub)" + " JOIN purse_merges pm" + " ON (pm.purse_pub = pdes.purse_pub)" + " JOIN account_merges am" + " ON (am.purse_pub = pm.purse_pub AND" + " am.reserve_pub = pm.reserve_pub)" + " WHERE pdes.purse_decision_serial_id=$2" + " AND pm.reserve_pub=$1" + " AND COALESCE(pm.partner_serial_id,0)=0" /* must be local! */ + " AND NOT pdes.refunded;"); + PREPARE (ctx, + "open_request_by_reserve", + "SELECT" + " reserve_payment" + ",request_timestamp" + ",expiration_date" + ",requested_purse_limit" + ",reserve_sig" + " FROM reserves_open_requests" + " WHERE reserve_pub=$1" + " AND open_request_uuid=$2;"); + PREPARE (ctx, + "close_request_by_reserve", + "SELECT" + " close_timestamp" + ",payto_uri" + ",reserve_sig" + " FROM close_requests" + " WHERE reserve_pub=$1" + " AND close_request_serial_id=$2;"); + + for (unsigned int i = 0; i<RETRIES; i++) + { + enum GNUNET_DB_QueryStatus qs; + uint64_t end; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("reserve_history_serial_id", + &end), + TALER_PQ_RESULT_SPEC_AMOUNT ("current_balance", + balance), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + EXCHANGEDB_start_read_committed (ctx, + "get-reserve-transactions")) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + /* First only check the last item, to see if + we even need to iterate */ + qs = GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "get_reserve_history_etag", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + EXCHANGEDB_rollback (ctx); + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + *etag_out = end; + if (end == etag_in) + return qs; + } + /* We indeed need to iterate over the history */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Current ETag for reserve %s is %llu\n", + TALER_B2S (reserve_pub), + (unsigned long long) end); + + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "get_reserve_history", + lparams, + &handle_history_entry, + &rhc); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + EXCHANGEDB_rollback (ctx); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + EXCHANGEDB_rollback (ctx); + continue; + default: + break; + } + if (rhc.failed) + { + EXCHANGEDB_rollback (ctx); + TEH_COMMON_free_reserve_history (ctx, + rhc.rh); + return GNUNET_DB_STATUS_SOFT_ERROR; + } + qs = EXCHANGEDB_commit (ctx); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + TEH_COMMON_free_reserve_history (ctx, + rhc.rh); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + TEH_COMMON_free_reserve_history (ctx, + rhc.rh); + rhc.rh = NULL; + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + *rhp = rhc.rh; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } + } + return GNUNET_DB_STATUS_SOFT_ERROR; +} diff --git a/src/exchangedb/get_signature_for_known_coin.c b/src/exchangedb/get_signature_for_known_coin.c @@ -0,0 +1,61 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_signature_for_known_coin.c + * @brief Implementation of the get_signature_for_known_coin function for Postgres + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_signature_for_known_coin.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_signature_for_known_coin (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct TALER_DenominationPublicKey *denom_pub, + struct TALER_DenominationSignature *denom_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_denom_pub ("denom_pub", + denom_pub), + TALER_PQ_result_spec_denom_sig ("denom_sig", + denom_sig), + GNUNET_PQ_result_spec_end + }; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Getting denomination and signature for (potentially) known coin %s\n", + TALER_B2S (coin_pub)); + PREPARE (ctx, + "get_signature_for_known_coin", + "SELECT" + " denominations.denom_pub" + ",denom_sig" + " FROM known_coins" + " JOIN denominations USING (denominations_serial)" + " WHERE coin_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_signature_for_known_coin", + params, + rs); +} diff --git a/src/exchangedb/get_unfinished_close_requests.c b/src/exchangedb/get_unfinished_close_requests.c @@ -0,0 +1,164 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_unfinished_close_requests.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_unfinished_close_requests.h" +#include "pg_helper.h" + + +/** + * Closure for #reserve_close_cb(). + */ +struct CloseReserveContext +{ + /** + * Function to call for each to be closed reserve. + */ + TALER_EXCHANGEDB_ReserveExpiredCallback rec; + + /** + * Closure to give to @e rec. + */ + void *rec_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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 +reserve_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CloseReserveContext *erc = cls; + struct EXCHANGEDB_PostgresContext *ctx = erc->ctx; + enum GNUNET_GenericReturnValue ret = GNUNET_OK; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_TIME_Timestamp exp_date; + struct TALER_FullPayto account_details; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_Amount remaining_balance; + uint64_t close_request_row; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_timestamp ("expiration_date", + &exp_date), + GNUNET_PQ_result_spec_string ("account_details", + &account_details.full_payto), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("close", + &remaining_balance), + GNUNET_PQ_result_spec_uint64 ("close_request_serial_id", + &close_request_row), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ret = GNUNET_SYSERR; + break; + } + ret = erc->rec (erc->rec_cls, + &reserve_pub, + &remaining_balance, + account_details, + exp_date, + close_request_row); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } + erc->status = ret; +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_unfinished_close_requests (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_ReserveExpiredCallback rec, + void *rec_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + struct CloseReserveContext ectx = { + .rec = rec, + .rec_cls = rec_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "get_unfinished_close_requests", + "UPDATE close_requests AS rc" + " SET done=TRUE" + " WHERE NOT done" + " RETURNING" + " reserve_pub" + " ,close_request_serial_id" + " ,close_timestamp AS expiration_date" + " ,close" + " ,(SELECT payto_uri" + " FROM reserves_in ri" + " JOIN wire_targets wt" + " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE ri.reserve_pub=rc.reserve_pub)" + " AS account_details;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "get_unfinished_close_requests", + params, + &reserve_cb, + &ectx); + switch (ectx.status) + { + case GNUNET_SYSERR: + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_NO: + return GNUNET_DB_STATUS_SOFT_ERROR; + case GNUNET_OK: + break; + } + return qs; +} diff --git a/src/exchangedb/get_wire_accounts.c b/src/exchangedb/get_wire_accounts.c @@ -0,0 +1,182 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_wire_accounts.c + * @brief Implementation of the get_wire_accounts function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_wire_accounts.h" +#include "pg_helper.h" + + +/** + * 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. + */ + 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 +get_wire_accounts_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct GetWireAccountsContext *ctx = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_FullPayto payto_uri; + char *conversion_url = NULL; + char *open_banking_gateway = NULL; + char *wire_transfer_gateway = NULL; + json_t *debit_restrictions = NULL; + json_t *credit_restrictions = NULL; + struct TALER_MasterSignatureP master_sig; + char *bank_label = NULL; + int64_t priority; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri.full_payto), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("conversion_url", + &conversion_url), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("open_banking_gateway", + &open_banking_gateway), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("wire_transfer_gateway", + &wire_transfer_gateway), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("bank_label", + &bank_label), + NULL), + GNUNET_PQ_result_spec_int64 ("priority", + &priority), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("debit_restrictions", + &debit_restrictions), + NULL), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("credit_restrictions", + &credit_restrictions), + NULL), + 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; + } + if (NULL == debit_restrictions) + { + debit_restrictions = json_array (); + GNUNET_assert (NULL != debit_restrictions); + } + if (NULL == credit_restrictions) + { + credit_restrictions = json_array (); + GNUNET_assert (NULL != credit_restrictions); + } + ctx->cb (ctx->cb_cls, + payto_uri, + conversion_url, + open_banking_gateway, + wire_transfer_gateway, + debit_restrictions, + credit_restrictions, + &master_sig, + bank_label, + priority); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_wire_accounts (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_WireAccountCallback cb, + void *cb_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; + + PREPARE (ctx, + "get_wire_accounts", + "SELECT" + " payto_uri" + ",conversion_url" + ",open_banking_gateway" + ",wire_transfer_gateway" + ",debit_restrictions::TEXT" + ",credit_restrictions::TEXT" + ",master_sig" + ",bank_label" + ",priority" + " FROM wire_accounts" + " WHERE is_active"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "get_wire_accounts", + params, + &get_wire_accounts_cb, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/get_wire_fee.c b/src/exchangedb/get_wire_fee.c @@ -0,0 +1,76 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_wire_fee.c + * @brief Implementation of the get_wire_fee function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_wire_fee.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_wire_fee (struct EXCHANGEDB_PostgresContext *ctx, + const char *type, + struct GNUNET_TIME_Timestamp date, + uint64_t *rowid, + struct GNUNET_TIME_Timestamp *start_date, + struct GNUNET_TIME_Timestamp *end_date, + struct TALER_WireFeeSet *fees, + struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (type), + GNUNET_PQ_query_param_timestamp (&date), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("wire_fee_serial", + rowid), + 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), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "get_wire_fee", + "SELECT" + " wire_fee_serial" + ",start_date" + ",end_date" + ",wire_fee" + ",closing_fee" + ",master_sig" + " FROM wire_fee" + " WHERE wire_method=$1" + " AND start_date <= $2" + " AND end_date > $2;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_wire_fee", + params, + rs); +} diff --git a/src/exchangedb/get_wire_fees.c b/src/exchangedb/get_wire_fees.c @@ -0,0 +1,146 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_wire_fees.c + * @brief Implementation of the get_wire_fees function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_wire_fees.h" +#include "pg_helper.h" + +/** + * 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 EXCHANGEDB_PostgresContext *ctx; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + + +/** + * Invoke the callback for each result. + * + * @param cls a `struct GetWireFeesContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +get_wire_fees_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct GetWireFeesContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct TALER_MasterSignatureP master_sig; + struct TALER_WireFeeSet fees; + struct GNUNET_TIME_Timestamp start_date; + struct GNUNET_TIME_Timestamp end_date; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee", + &fees.wire), + TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", + &fees.closing), + GNUNET_PQ_result_spec_timestamp ("start_date", + &start_date), + GNUNET_PQ_result_spec_timestamp ("end_date", + &end_date), + 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, + &fees, + start_date, + end_date, + &master_sig); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_wire_fees (struct EXCHANGEDB_PostgresContext *ctx, + const char *wire_method, + TALER_EXCHANGEDB_WireFeeCallback cb, + void *cb_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, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "get_wire_fees", + "SELECT" + " wire_fee" + ",closing_fee" + ",start_date" + ",end_date" + ",master_sig" + " FROM wire_fee" + " WHERE wire_method=$1"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "get_wire_fees", + params, + &get_wire_fees_cb, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/get_wire_hash_for_contract.c b/src/exchangedb/get_wire_hash_for_contract.c @@ -0,0 +1,79 @@ +/* + This file is part of TALER + Copyright (C) 2023, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_wire_hash_for_contract.c + * @brief Implementation of the get_wire_hash_for_contract function for Postgres + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_exchangedb_plugin.h" +#include "taler/taler_pq_lib.h" +#include "get_wire_hash_for_contract.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_wire_hash_for_contract (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_PrivateContractHashP *h_contract_terms, + struct TALER_MerchantWireHashP *h_wire) +{ + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (merchant_pub), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_end + }; + struct TALER_FullPayto payto_uri; + struct TALER_WireSaltP wire_salt; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("wire_salt", + &wire_salt), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri.full_payto), + GNUNET_PQ_result_spec_end + }; + + /* check if the necessary records exist and get them */ + PREPARE (ctx, + "get_wire_hash_for_contract", + "SELECT" + " bdep.wire_salt" + " ,wt.payto_uri" + " FROM coin_deposits" + " JOIN batch_deposits bdep" + " USING (batch_deposit_serial_id)" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " WHERE bdep.merchant_pub=$1" + " AND bdep.h_contract_terms=$2"); + /* NOTE: above query might be more efficient if we computed the shard + from the merchant_pub and included that in the query */ + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_wire_hash_for_contract", + params, + rs); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) + { + TALER_merchant_wire_signature_hash (payto_uri, + &wire_salt, + h_wire); + GNUNET_PQ_cleanup_result (rs); + } + return qs; +} diff --git a/src/exchangedb/get_withdraw.c b/src/exchangedb/get_withdraw.c @@ -0,0 +1,193 @@ +/* + This file is part of TALER + Copyright (C) 2023, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/get_withdraw.c + * @brief Implementation of the get_withdraw function for Postgres + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "get_withdraw.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_withdraw (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_HashBlindedPlanchetsP *wch, + struct TALER_EXCHANGEDB_Withdraw *wd) +{ + enum GNUNET_DB_QueryStatus ret; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (wch), + GNUNET_PQ_query_param_end + }; + struct TALER_BlindedDenominationSignature *my_denom_sigs = NULL; + uint64_t *my_denom_serials = NULL; + struct GNUNET_CRYPTO_CSPublicRPairP *my_cs_r_values = NULL; + size_t num_sigs = 0; + size_t num_coins = 0; + size_t num_cs_r_values = 0; + bool no_noreveal_index; + bool no_max_age; + bool no_selected_h; + bool no_blinding_seed; + bool no_cs_r_values; + bool no_cs_r_choices; + + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("planchets_h", + &wd->planchets_h), + GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", + &wd->reserve_sig), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &wd->reserve_pub), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint16 ("max_age", + &wd->max_age), + &no_max_age), + TALER_PQ_result_spec_amount ("amount_with_fee", + ctx->currency, + &wd->amount_with_fee), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint16 ("noreveal_index", + &wd->noreveal_index), + &no_noreveal_index), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("selected_h", + &wd->selected_h), + &no_selected_h), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("blinding_seed", + &wd->blinding_seed), + &no_blinding_seed), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_array_cs_r_pub ( + ctx->conn, + "cs_r_values", + &num_cs_r_values, + &my_cs_r_values), + &no_cs_r_values), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ("cs_r_choices", + &wd->cs_r_choices), + &no_cs_r_choices), + TALER_PQ_result_spec_array_blinded_denom_sig ( + ctx->conn, + "denom_sigs", + &num_sigs, + &my_denom_sigs), + GNUNET_PQ_result_spec_array_uint64 ( + ctx->conn, + "denom_serials", + &num_coins, + &my_denom_serials), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "get_withdraw", + "SELECT" + " planchets_h" + ",blinding_seed" + ",reserve_sig" + ",reserve_pub" + ",max_age" + ",amount_with_fee" + ",noreveal_index" + ",selected_h" + ",blinding_seed" + ",cs_r_values" + ",cs_r_choices" + ",denom_sigs" + ",denom_serials" + " FROM withdraw" + " WHERE planchets_h=$1;"); + ret = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_withdraw", + params, + rs); + if (0 > ret) + { + GNUNET_break (0); + GNUNET_PQ_cleanup_result (rs); + return ret; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == ret) + { + GNUNET_PQ_cleanup_result (rs); + return ret; + } + + if ((no_max_age != no_noreveal_index) || + (no_max_age != no_selected_h)) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "got inconsistent state for max_age, noreveal_index and planchets_h in DB: " + "no_max_age=%s, no_noreveal_index=%s, no_selected_h=%s\n", + no_max_age ? "true" : "false", + no_noreveal_index ? "true" : "false", + no_selected_h ? "true" : "false"); + GNUNET_PQ_cleanup_result (rs); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (no_blinding_seed != no_cs_r_values) + { + GNUNET_break (0); + GNUNET_PQ_cleanup_result (rs); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (no_cs_r_choices != no_cs_r_values) + { + GNUNET_break (0); + GNUNET_PQ_cleanup_result (rs); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (num_coins != num_sigs) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "got inconsistent number of entries in withdraw from DB: " + "num_coins=%ld, num_sigs=%ld\n", + num_coins, + num_sigs); + GNUNET_PQ_cleanup_result (rs); + return GNUNET_DB_STATUS_HARD_ERROR; + } + wd->age_proof_required = ! no_max_age; + if (no_cs_r_values) + { + wd->cs_r_values = NULL; + wd->num_cs_r_values = 0; + wd->cs_r_choices = 0; + } + wd->denom_sigs = my_denom_sigs; + wd->num_coins = num_coins; + wd->denom_serials = my_denom_serials; + wd->cs_r_values = my_cs_r_values; + wd->num_cs_r_values = num_cs_r_values; + /* ensure cleanup_result does not trash data we care about */ + my_denom_sigs = NULL; + my_denom_serials = NULL; + my_cs_r_values = NULL; + num_sigs = 0; + num_coins = 0; + num_cs_r_values = 0; + GNUNET_PQ_cleanup_result (rs); + return ret; +} diff --git a/src/exchangedb/have_deposit2.c b/src/exchangedb/have_deposit2.c @@ -0,0 +1,115 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/have_deposit2.c + * @brief Implementation of the have_deposit2 function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "have_deposit2.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_have_deposit2 (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant, + struct GNUNET_TIME_Timestamp refund_deadline, + struct TALER_Amount *deposit_fee, + struct GNUNET_TIME_Timestamp *exchange_timestamp) +{ + 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), + 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), + 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.full_payto), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + struct TALER_MerchantWireHashP h_wire2; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Getting deposits for coin %s\n", + TALER_B2S (coin_pub)); + PREPARE (ctx, + "get_deposit", + "SELECT" + " cdep.amount_with_fee" + ",denominations.fee_deposit" + ",bdep.wallet_timestamp" + ",bdep.exchange_timestamp" + ",bdep.refund_deadline" + ",bdep.wire_deadline" + ",bdep.h_contract_terms" + ",bdep.wire_salt" + ",wt.payto_uri AS receiver_wire_account" + " FROM coin_deposits cdep" + " JOIN batch_deposits bdep USING (batch_deposit_serial_id)" + " JOIN known_coins kc ON (kc.coin_pub = cdep.coin_pub)" + " JOIN denominations USING (denominations_serial)" + " JOIN wire_targets wt USING (wire_target_h_payto)" + " WHERE cdep.coin_pub=$1" + " AND bdep.merchant_pub=$3" + " AND bdep.h_contract_terms=$2;"); + /* Note: query might be made more efficient if we computed the 'shard' + from merchant_pub and included that as a constraint on bdep! */ + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->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.full_payto); + /* Now we check that the other information in @a deposit + also matches, and if not report inconsistencies. */ + if ( (GNUNET_TIME_timestamp_cmp (refund_deadline, + !=, + deposit2.refund_deadline)) || + (0 != GNUNET_memcmp (h_wire, + &h_wire2) ) ) + { + /* Inconsistencies detected! Does not match! */ + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; +} diff --git a/src/exchangedb/inject_auditor_triggers.c b/src/exchangedb/inject_auditor_triggers.c @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/inject_auditor_triggers.c + * @brief Implementation of the inject_auditor_triggers function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_gc.h" +#include "pg_helper.h" +#include "inject_auditor_triggers.h" + + +/** + * Function called to inject auditor triggers into the + * database, triggering the real-time auditor upon + * relevant INSERTs. + * + * @param cls closure + * @return #GNUNET_OK on success, + * #GNUNET_SYSERR on DB errors + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_inject_auditor_triggers (struct EXCHANGEDB_PostgresContext *ctx) +{ + struct GNUNET_PQ_Context *conn; + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_try_execute ("SET search_path TO exchange;"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + conn = GNUNET_PQ_connect_with_cfg (ctx->cfg, + "exchangedb-postgres", + "auditor-triggers-", + es, + NULL); + if (NULL == conn) + return GNUNET_SYSERR; + GNUNET_PQ_disconnect (conn); + return GNUNET_OK; +} diff --git a/src/exchangedb/insert_active_legitimization_measure.c b/src/exchangedb/insert_active_legitimization_measure.c @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_active_legitimization_measure.c + * @brief Implementation of the insert_active_legitimization_measure function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_active_legitimization_measure.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_active_legitimization_measure (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AccountAccessTokenP *access_token, + const json_t *jmeasures, + uint64_t *legitimization_measure_serial_id) +{ + struct GNUNET_TIME_Timestamp now + = GNUNET_TIME_timestamp_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (access_token), + GNUNET_PQ_query_param_timestamp (&now), + TALER_PQ_query_param_json (jmeasures), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("out_legitimization_measure_serial_id", + legitimization_measure_serial_id), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "do_insert_active_legitimization_measure", + "SELECT" + " out_legitimization_measure_serial_id" + " FROM exchange_do_insert_active_legitimization_measure" + "($1, $2, $3::TEXT::JSONB);"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "do_insert_active_legitimization_measure", + params, + rs); +} diff --git a/src/exchangedb/insert_aml_decision.c b/src/exchangedb/insert_aml_decision.c @@ -0,0 +1,187 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_aml_decision.c + * @brief Implementation of the insert_aml_decision function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_aml_decision.h" +#include "pg_helper.h" +#include <gnunet/gnunet_pq_lib.h> + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_aml_decision (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp decision_time, + struct GNUNET_TIME_Timestamp expiration_time, + const json_t *properties, + const json_t *new_rules, + bool to_investigate, + const char *new_measure_name, + const json_t *jmeasures, + const char *justification, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + const struct TALER_AmlOfficerSignatureP *decider_sig, + size_t num_events, + const char *events[static num_events], + const char *form_name, + size_t enc_attributes_size, + const void *enc_attributes, + struct GNUNET_HashCode *attributes_hash, + struct GNUNET_TIME_Timestamp attributes_expiration_time, + bool *invalid_officer, + bool *unknown_account, + struct GNUNET_TIME_Timestamp *last_date, + uint64_t *legitimization_measure_serial_id, + bool *is_wallet) +{ + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = *h_payto + }; + struct TALER_FullPaytoHashP h_full_payto; + char *notify_s + = GNUNET_PQ_get_event_notify_channel (&rep.header); + bool account_unknown; + struct GNUNET_PQ_QueryParam params[] = { + /* $1: in_payto_uri */ + NULL == payto_uri.full_payto + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (payto_uri.full_payto), + /* $2: in_h_normalized_payto */ + GNUNET_PQ_query_param_auto_from_type (h_payto), + /* $3: in_h_full_payto */ + NULL == payto_uri.full_payto + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (&h_full_payto), + /* $4: in_decision_time */ + GNUNET_PQ_query_param_timestamp (&decision_time), + /* $5: in_expiration_time*/ + GNUNET_PQ_query_param_timestamp (&expiration_time), + /* $6: in_properties */ + NULL != properties + ? TALER_PQ_query_param_json (properties) + : GNUNET_PQ_query_param_null (), + /* $7: in_kyc_attributes_enc */ + NULL != enc_attributes + ? GNUNET_PQ_query_param_fixed_size (enc_attributes, + enc_attributes_size) + : GNUNET_PQ_query_param_null (), + /* $8: in_kyc_attributes_hash */ + NULL != attributes_hash + ? GNUNET_PQ_query_param_auto_from_type (attributes_hash) + : GNUNET_PQ_query_param_null (), + /* $9: in_kyc_attributes_expiration */ + GNUNET_PQ_query_param_timestamp (&attributes_expiration_time), + /* $10: in_new_rules */ + TALER_PQ_query_param_json (new_rules), + /* $11: in_to_investigate */ + GNUNET_PQ_query_param_bool (to_investigate), + /* $12: in_new_measure_name */ + NULL != new_measure_name + ? GNUNET_PQ_query_param_string (new_measure_name) + : GNUNET_PQ_query_param_null (), + /* $13: in_jmeasures */ + NULL != jmeasures + ? TALER_PQ_query_param_json (jmeasures) + : GNUNET_PQ_query_param_null (), + /* $14: in_justification */ + NULL != justification + ? GNUNET_PQ_query_param_string (justification) + : GNUNET_PQ_query_param_null (), + /* $15: in_decider_pub */ + NULL != decider_pub + ? GNUNET_PQ_query_param_auto_from_type (decider_pub) + : GNUNET_PQ_query_param_null (), + /* $16: in_decider_sig */ + NULL != decider_sig + ? GNUNET_PQ_query_param_auto_from_type (decider_sig) + : GNUNET_PQ_query_param_null (), + /* $17: in_notify_s*/ + GNUNET_PQ_query_param_string (notify_s), + /* $18: ina_events */ + GNUNET_PQ_query_param_array_ptrs_string (num_events, + events, + ctx->conn), + (NULL == form_name) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (form_name), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("out_invalid_officer", + invalid_officer), + GNUNET_PQ_result_spec_bool ("out_account_unknown", + unknown_account), + GNUNET_PQ_result_spec_timestamp ("out_last_date", + last_date), + GNUNET_PQ_result_spec_uint64 ("out_legitimization_measure_serial_id", + legitimization_measure_serial_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_bool ("out_is_wallet", + is_wallet), + &account_unknown), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + *is_wallet = false; + GNUNET_assert ( ( (NULL == decider_pub) && + (NULL == decider_sig) && + (NULL == justification) ) || + ( (NULL != decider_pub) && + (NULL != decider_sig) && + (NULL != justification) ) ); + + if (NULL != payto_uri.full_payto) + TALER_full_payto_hash (payto_uri, + &h_full_payto); + PREPARE (ctx, + "do_insert_aml_decision", + "SELECT" + " out_invalid_officer" + ",out_account_unknown" + ",out_last_date" + ",out_legitimization_measure_serial_id" + ",out_is_wallet" + " FROM exchange_do_insert_aml_decision" + "($1,$2,$3,$4,$5,$6::TEXT::JSONB,$7,$8,$9,$10::TEXT::JSONB" + ",$11,$12,$13::TEXT::JSONB,$14,$15,$16,$17,$18,$19);"); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Inserting LEGI OUTCOME from AML decision with notification on %s\n", + notify_s); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "do_insert_aml_decision", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + GNUNET_free (notify_s); + GNUNET_PQ_event_do_poll (ctx->conn); + if (qs <= 0) + return qs; + if (account_unknown) + { + GNUNET_assert ((*invalid_officer) || (*unknown_account)); + } + return qs; +} diff --git a/src/exchangedb/insert_aml_officer.c b/src/exchangedb/insert_aml_officer.c @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_aml_officer.c + * @brief Implementation of the insert_aml_officer function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_aml_officer.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_aml_officer (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + const struct TALER_MasterSignatureP *master_sig, + const char *decider_name, + bool is_active, + bool read_only, + struct GNUNET_TIME_Timestamp last_change, + struct GNUNET_TIME_Timestamp *previous_change) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (decider_pub), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_string (decider_name), + GNUNET_PQ_query_param_bool (is_active), + GNUNET_PQ_query_param_bool (read_only), + GNUNET_PQ_query_param_timestamp (&last_change), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_timestamp ("out_last_change", + previous_change), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "do_insert_aml_staff", + "SELECT" + " out_last_change" + " FROM exchange_do_insert_aml_officer" + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "do_insert_aml_staff", + params, + rs); +} diff --git a/src/exchangedb/insert_aml_program_failure.c b/src/exchangedb/insert_aml_program_failure.c @@ -0,0 +1,68 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_aml_program_failure.c + * @brief Implementation of the insert_aml_program_failure function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_aml_program_failure.h" +#include "pg_helper.h" +#include "pg_event_notify.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_aml_program_failure (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t process_row, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *error_message, + enum TALER_ErrorCode ec) +{ + uint32_t ec32 = (uint32_t) ec; + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = *h_payto + }; + struct GNUNET_TIME_Timestamp now + = GNUNET_TIME_timestamp_get (); + char *kyc_completed_notify_s + = GNUNET_PQ_get_event_notify_channel (&rep.header); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&process_row), + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_uint32 (&ec32), + GNUNET_PQ_query_param_string (error_message), + GNUNET_PQ_query_param_string (kyc_completed_notify_s), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "insert_aml_program_failure", + "SELECT out_update" + " FROM exchange_do_insert_aml_program_failure" + " ($1, $2, $3, $4, $5, $6);"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_aml_program_failure", + params); + GNUNET_free (kyc_completed_notify_s); + return qs; +} diff --git a/src/exchangedb/insert_auditor.c b/src/exchangedb/insert_auditor.c @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_auditor.c + * @brief Implementation of the insert_auditor function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_auditor.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_auditor (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const char *auditor_url, + const char *auditor_name, + struct GNUNET_TIME_Timestamp start_date) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (auditor_pub), + GNUNET_PQ_query_param_string (auditor_name), + GNUNET_PQ_query_param_string (auditor_url), + GNUNET_PQ_query_param_timestamp (&start_date), + GNUNET_PQ_query_param_end + }; + + /* used in #postgres_insert_auditor() */ + PREPARE (ctx, + "insert_auditor", + "INSERT INTO auditors " + "(auditor_pub" + ",auditor_name" + ",auditor_url" + ",is_active" + ",last_change" + ") VALUES " + "($1, $2, $3, true, $4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_auditor", + params); +} diff --git a/src/exchangedb/insert_auditor_denom_sig.c b/src/exchangedb/insert_auditor_denom_sig.c @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_auditor_denom_sig.c + * @brief Implementation of the insert_auditor_denom_sig function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_auditor_denom_sig.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_auditor_denom_sig (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const struct TALER_AuditorSignatureP *auditor_sig) +{ + 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_auto_from_type (auditor_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "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" + " WHERE denom_pub_hash=$2" + " ON CONFLICT DO NOTHING;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_auditor_denom_sig", + params); +} diff --git a/src/exchangedb/insert_close_request.c b/src/exchangedb/insert_close_request.c @@ -0,0 +1,66 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_close_request.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_close_request.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_close_request (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_FullPayto payto_uri, + const struct TALER_ReserveSignatureP *reserve_sig, + struct GNUNET_TIME_Timestamp request_timestamp, + const struct TALER_Amount *balance, + const struct TALER_Amount *closing_fee) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_timestamp (&request_timestamp), + GNUNET_PQ_query_param_auto_from_type (reserve_sig), + TALER_PQ_query_param_amount (ctx->conn, + balance), + TALER_PQ_query_param_amount (ctx->conn, + closing_fee), + GNUNET_PQ_query_param_string (payto_uri.full_payto), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_account_close", + "INSERT INTO close_requests" + "(reserve_pub" + ",close_timestamp" + ",reserve_sig" + ",close" + ",close_fee" + ",payto_uri" + ")" + "VALUES " + "($1, $2, $3, $4, $5, $6)" + " ON CONFLICT DO NOTHING;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_account_close", + params); +} diff --git a/src/exchangedb/insert_contract.c b/src/exchangedb/insert_contract.c @@ -0,0 +1,91 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_contract.c + * @brief Implementation of the insert_contract function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_contract.h" +#include "pg_select_contract_by_purse.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_contract (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_EncryptedContract *econtract, + bool *in_conflict) +{ + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_auto_from_type (&econtract->contract_pub), + GNUNET_PQ_query_param_fixed_size (econtract->econtract, + econtract->econtract_size), + GNUNET_PQ_query_param_auto_from_type (&econtract->econtract_sig), + GNUNET_PQ_query_param_end + }; + + *in_conflict = false; + /* Used in #postgres_insert_contract() */ + PREPARE (ctx, + "insert_contract", + "INSERT INTO contracts" + " (purse_pub" + " ,pub_ckey" + " ,e_contract" + " ,contract_sig" + " ,purse_expiration" + " ) SELECT " + " $1, $2, $3, $4, purse_expiration" + " FROM purse_requests" + " WHERE purse_pub=$1" + " ON CONFLICT DO NOTHING;"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_contract", + params); + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs) + return qs; + { + struct TALER_EncryptedContract econtract2; + + qs = EXCHANGEDB_select_contract_by_purse (ctx, + purse_pub, + &econtract2); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if ( (0 == GNUNET_memcmp (&econtract->contract_pub, + &econtract2.contract_pub)) && + (econtract2.econtract_size == + econtract->econtract_size) && + (0 == memcmp (econtract2.econtract, + econtract->econtract, + econtract->econtract_size)) ) + { + GNUNET_free (econtract2.econtract); + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + GNUNET_free (econtract2.econtract); + *in_conflict = true; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } +} diff --git a/src/exchangedb/insert_denomination_info.c b/src/exchangedb/insert_denomination_info.c @@ -0,0 +1,99 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_denomination_info.c + * @brief Implementation of the insert_denomination_info function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_denomination_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_denomination_info (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue) +{ + struct TALER_DenominationHashP denom_hash; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&issue->denom_hash), + TALER_PQ_query_param_denom_pub (denom_pub), + GNUNET_PQ_query_param_auto_from_type (&issue->signature), + GNUNET_PQ_query_param_timestamp (&issue->start), + GNUNET_PQ_query_param_timestamp (&issue->expire_withdraw), + GNUNET_PQ_query_param_timestamp (&issue->expire_deposit), + GNUNET_PQ_query_param_timestamp (&issue->expire_legal), + TALER_PQ_query_param_amount (ctx->conn, + &issue->value), + TALER_PQ_query_param_amount (ctx->conn, + &issue->fees.withdraw), + TALER_PQ_query_param_amount (ctx->conn, + &issue->fees.deposit), + TALER_PQ_query_param_amount (ctx->conn, + &issue->fees.refresh), + TALER_PQ_query_param_amount (ctx->conn, + &issue->fees.refund), + GNUNET_PQ_query_param_uint32 (&denom_pub->age_mask.bits), + GNUNET_PQ_query_param_end + }; + + GNUNET_assert (denom_pub->age_mask.bits == + issue->age_mask.bits); + TALER_denom_pub_hash (denom_pub, + &denom_hash); + GNUNET_assert (0 == + GNUNET_memcmp (&denom_hash, + &issue->denom_hash)); + GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( + issue->start.abs_time)); + GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( + issue->expire_withdraw.abs_time)); + GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( + issue->expire_deposit.abs_time)); + GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( + issue->expire_legal.abs_time)); + /* check fees match denomination currency */ + GNUNET_assert (GNUNET_YES == + TALER_denom_fee_check_currency ( + issue->value.currency, + &issue->fees)); + PREPARE (ctx, + "denomination_insert", + "INSERT INTO denominations " + "(denom_pub_hash" + ",denom_pub" + ",master_sig" + ",valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" /* value of this denom */ + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ",age_mask" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," + " $11, $12, $13);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "denomination_insert", + params); +} diff --git a/src/exchangedb/insert_denomination_revocation.c b/src/exchangedb/insert_denomination_revocation.c @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_denomination_revocation.c + * @brief Implementation of the insert_denomination_revocation function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_denomination_revocation.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_denomination_revocation (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + const struct TALER_MasterSignatureP *master_sig) +{ + 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 + }; + + /* Used in #postgres_insert_denomination_revocation() */ + PREPARE (ctx, + "denomination_revocation_insert", + "INSERT INTO denomination_revocations " + "(denominations_serial" + ",master_sig" + ") SELECT denominations_serial,$2" + " FROM denominations" + " WHERE denom_pub_hash=$1;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "denomination_revocation_insert", + params); +} diff --git a/src/exchangedb/insert_drain_profit.c b/src/exchangedb/insert_drain_profit.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_drain_profit.c + * @brief Implementation of the insert_drain_profit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_drain_profit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_drain_profit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_WireTransferIdentifierRawP *wtid, + const char *account_section, + const struct TALER_FullPayto payto_uri, + struct GNUNET_TIME_Timestamp request_timestamp, + const struct TALER_Amount *amount, + const struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_string (account_section), + GNUNET_PQ_query_param_string (payto_uri.full_payto), + GNUNET_PQ_query_param_timestamp (&request_timestamp), + TALER_PQ_query_param_amount (ctx->conn, + amount), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "drain_profit_insert", + "INSERT INTO profit_drains " + "(wtid" + ",account_section" + ",payto_uri" + ",trigger_date" + ",amount" + ",master_sig" + ") VALUES ($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "drain_profit_insert", + params); +} diff --git a/src/exchangedb/insert_global_fee.c b/src/exchangedb/insert_global_fee.c @@ -0,0 +1,136 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_global_fee.c + * @brief Implementation of the insert_global_fee function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_global_fee.h" +#include "pg_helper.h" +#include "pg_get_global_fee.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_global_fee (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + const struct TALER_GlobalFeeSet *fees, + struct GNUNET_TIME_Relative purse_timeout, + struct GNUNET_TIME_Relative history_expiration, + uint32_t purse_account_limit, + const struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&start_date), + GNUNET_PQ_query_param_timestamp (&end_date), + TALER_PQ_query_param_amount (ctx->conn, + &fees->history), + TALER_PQ_query_param_amount (ctx->conn, + &fees->account), + TALER_PQ_query_param_amount (ctx->conn, + &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 = EXCHANGEDB_get_global_fee (ctx, + 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; + } + + /* Used in #postgres_insert_global_fee */ + PREPARE (ctx, + "insert_global_fee", + "INSERT INTO global_fee " + "(start_date" + ",end_date" + ",history_fee" + ",account_fee" + ",purse_fee" + ",purse_timeout" + ",history_expiration" + ",purse_account_limit" + ",master_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_global_fee", + params); +} diff --git a/src/exchangedb/insert_kyc_failure.c b/src/exchangedb/insert_kyc_failure.c @@ -0,0 +1,89 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_kyc_failure.c + * @brief Implementation of the insert_kyc_failure function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_kyc_failure.h" +#include "pg_helper.h" +#include "pg_event_notify.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_kyc_failure (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t process_row, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_name, + const char *provider_account_id, + const char *provider_legitimization_id, + const char *error_message, + enum TALER_ErrorCode ec) +{ + uint32_t ec32 = (uint32_t) ec; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&process_row), + GNUNET_PQ_query_param_auto_from_type (h_payto), + NULL != provider_name + ? GNUNET_PQ_query_param_string (provider_name) + : GNUNET_PQ_query_param_null (), + NULL != provider_account_id + ? GNUNET_PQ_query_param_string (provider_account_id) + : GNUNET_PQ_query_param_null (), + NULL != provider_legitimization_id + ? GNUNET_PQ_query_param_string (provider_legitimization_id) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_uint32 (&ec32), + GNUNET_PQ_query_param_string (error_message), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "insert_kyc_failure", + "UPDATE legitimization_processes" + " SET" + " finished=TRUE" + " ,provider_user_id=$4" + " ,provider_legitimization_id=$5" + " ,error_code=$6" + " ,error_message=$7" + " WHERE h_payto=$2" + " AND legitimization_process_serial_id=$1" + " AND provider_name=$3;"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_kyc_failure", + params); + if (qs > 0) + { + /* FIXME-#9419: might want to do this eventually in the same transaction... */ + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = *h_payto + }; + + EXCHANGEDB_event_notify (ctx, + &rep.header, + NULL, + 0); + } + return qs; +} diff --git a/src/exchangedb/insert_kyc_requirement_process.c b/src/exchangedb/insert_kyc_requirement_process.c @@ -0,0 +1,87 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_kyc_requirement_process.c + * @brief Implementation of the insert_kyc_requirement_process function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_kyc_requirement_process.h" +#include "pg_helper.h" +#include <gnunet/gnunet_pq_lib.h> + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_kyc_requirement_process (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint32_t measure_index, + uint64_t legitimization_measure_serial_id, + const char *provider_name, + const char *provider_account_id, + const char *provider_legitimization_id, + uint64_t *process_row) +{ + struct GNUNET_TIME_Absolute now + = GNUNET_TIME_absolute_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_string (provider_name), + (NULL != provider_account_id) + ? GNUNET_PQ_query_param_string (provider_account_id) + : GNUNET_PQ_query_param_null (), + (NULL != provider_legitimization_id) + ? GNUNET_PQ_query_param_string (provider_legitimization_id) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_uint64 (&legitimization_measure_serial_id), + GNUNET_PQ_query_param_uint32 (&measure_index), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("legitimization_process_serial_id", + process_row), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "insert_kyc_requirement_process", + "INSERT INTO legitimization_processes" + " (h_payto" + " ,start_time" + " ,provider_name" + " ,provider_user_id" + " ,provider_legitimization_id" + " ,legitimization_measure_serial_id" + " ,measure_index" + " ) VALUES " + " ($1, $2, $3, $4, $5, $6, $7)" + " ON CONFLICT (legitimization_measure_serial_id,measure_index)" + " DO UPDATE" + " SET h_payto=$1" + " ,start_time=$2" + " ,provider_name=$3" + " ,provider_user_id=$4" + " ,provider_legitimization_id=$5" + " RETURNING legitimization_process_serial_id"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "insert_kyc_requirement_process", + params, + rs); +} diff --git a/src/exchangedb/insert_partner.c b/src/exchangedb/insert_partner.c @@ -0,0 +1,68 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_partner.c + * @brief Implementation of the insert_partner function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_partner.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_partner (struct EXCHANGEDB_PostgresContext *ctx, + 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) +{ + 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 (ctx->conn, + wad_fee), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_string (partner_base_url), + GNUNET_PQ_query_param_end + }; + + + PREPARE (ctx, + "insert_partner", + "INSERT INTO partners" + " (partner_master_pub" + " ,start_date" + " ,end_date" + " ,wad_frequency" + " ,wad_fee" + " ,master_sig" + " ,partner_base_url" + " ) VALUES " + " ($1, $2, $3, $4, $5, $6, $7)" + " ON CONFLICT DO NOTHING;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_partner", + params); +} diff --git a/src/exchangedb/insert_purse_request.c b/src/exchangedb/insert_purse_request.c @@ -0,0 +1,124 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_purse_request.c + * @brief Implementation of the insert_purse_request function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_purse_request.h" +#include "pg_get_purse_request.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_purse_request (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePublicKeyP *merge_pub, + struct GNUNET_TIME_Timestamp purse_expiration, + const struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t age_limit, + enum TALER_WalletAccountMergeFlags flags, + const struct TALER_Amount *purse_fee, + const struct TALER_Amount *amount, + const struct TALER_PurseContractSignatureP *purse_sig, + bool *in_conflict) +{ + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get (); + uint32_t flags32 = (uint32_t) flags; + bool in_reserve_quota = (TALER_WAMF_MODE_CREATE_FROM_PURSE_QUOTA + == (flags & TALER_WAMF_MERGE_MODE_MASK)); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_auto_from_type (merge_pub), + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_timestamp (&purse_expiration), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_uint32 (&age_limit), + GNUNET_PQ_query_param_uint32 (&flags32), + GNUNET_PQ_query_param_bool (in_reserve_quota), + TALER_PQ_query_param_amount (ctx->conn, + amount), + TALER_PQ_query_param_amount (ctx->conn, + purse_fee), + GNUNET_PQ_query_param_auto_from_type (purse_sig), + GNUNET_PQ_query_param_end + }; + + *in_conflict = false; + PREPARE (ctx, + "insert_purse_request", + "INSERT INTO purse_requests" + " (purse_pub" + " ,merge_pub" + " ,purse_creation" + " ,purse_expiration" + " ,h_contract_terms" + " ,age_limit" + " ,flags" + " ,in_reserve_quota" + " ,amount_with_fee" + " ,purse_fee" + " ,purse_sig" + " ) VALUES " + " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)" + " ON CONFLICT DO NOTHING;"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_purse_request", + params); + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs) + return qs; + { + struct TALER_PurseMergePublicKeyP merge_pub2; + struct GNUNET_TIME_Timestamp purse_expiration2; + struct TALER_PrivateContractHashP h_contract_terms2; + uint32_t age_limit2; + struct TALER_Amount amount2; + struct TALER_Amount balance; + struct TALER_PurseContractSignatureP purse_sig2; + + qs = EXCHANGEDB_get_purse_request (ctx, + purse_pub, + &merge_pub2, + &purse_expiration2, + &h_contract_terms2, + &age_limit2, + &amount2, + &balance, + &purse_sig2); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if ( (age_limit2 == age_limit) && + (0 == TALER_amount_cmp (amount, + &amount2)) && + (0 == GNUNET_memcmp (&h_contract_terms2, + h_contract_terms)) && + (0 == GNUNET_memcmp (&merge_pub2, + merge_pub)) ) + { + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + *in_conflict = true; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } +} diff --git a/src/exchangedb/insert_records_by_table.c b/src/exchangedb/insert_records_by_table.c @@ -0,0 +1,2451 @@ +/* + This file is part of GNUnet + Copyright (C) 2020-2025 Taler Systems SA + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @file src/exchangedb/insert_records_by_table.c + * @brief replicate_records_by_table implementation + * @author Christian Grothoff + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_records_by_table.h" +#include "pg_helper.h" +#include <gnunet/gnunet_pq_lib.h> + + +/** + * Signature of helper functions of #EXCHANGEDB_insert_records_by_table(). + * + * @param ctx plugin context + * @param td record to insert + * @return transaction status code + */ +typedef enum GNUNET_DB_QueryStatus +(*InsertRecordCallback)(struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td); + + +/** + * Function called with denominations records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_denominations (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct TALER_DenominationHashP denom_hash; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&denom_hash), + GNUNET_PQ_query_param_uint32 ( + &td->details.denominations.denom_type), + GNUNET_PQ_query_param_uint32 ( + &td->details.denominations.age_mask), + TALER_PQ_query_param_denom_pub ( + &td->details.denominations.denom_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.denominations.master_sig), + GNUNET_PQ_query_param_timestamp ( + &td->details.denominations.valid_from), + GNUNET_PQ_query_param_timestamp ( + &td->details.denominations.expire_withdraw), + GNUNET_PQ_query_param_timestamp ( + &td->details.denominations.expire_deposit), + GNUNET_PQ_query_param_timestamp ( + &td->details.denominations.expire_legal), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.denominations.coin), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.denominations.fees.withdraw), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.denominations.fees.deposit), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.denominations.fees.refresh), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.denominations.fees.refund), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_denominations", + "INSERT INTO denominations" + "(denominations_serial" + ",denom_pub_hash" + ",denom_type" + ",age_mask" + ",denom_pub" + ",master_sig" + ",valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," + " $11, $12, $13, $14, $15);"); + + TALER_denom_pub_hash ( + &td->details.denominations.denom_pub, + &denom_hash); + + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_denominations", + params); +} + + +/** + * Function called with denomination_revocations records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_denomination_revocations ( + struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.denomination_revocations.master_sig), + GNUNET_PQ_query_param_uint64 ( + &td->details.denomination_revocations.denominations_serial), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_denomination_revocations", + "INSERT INTO denomination_revocations" + "(denom_revocations_serial_id" + ",master_sig" + ",denominations_serial" + ") VALUES " + "($1, $2, $3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_denomination_revocations", + params); +} + + +/** + * Function called with wire target records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_wire_targets (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct TALER_NormalizedPaytoHashP normalized_payto_hash; + struct TALER_FullPaytoHashP full_payto_hash; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&full_payto_hash), + GNUNET_PQ_query_param_auto_from_type (&normalized_payto_hash), + GNUNET_PQ_query_param_string ( + td->details.wire_targets.full_payto_uri.full_payto), + GNUNET_PQ_query_param_end + }; + + TALER_full_payto_hash ( + td->details.wire_targets.full_payto_uri, + &full_payto_hash); + TALER_full_payto_normalize_and_hash ( + td->details.wire_targets.full_payto_uri, + &normalized_payto_hash); + PREPARE (ctx, + "insert_into_table_wire_targets", + "INSERT INTO wire_targets" + "(wire_target_serial_id" + ",wire_target_h_payto" + ",h_normalized_payto" + ",payto_uri" + ") VALUES " + "($1, $2, $3, $4);"); + return GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "insert_into_table_wire_targets", + params); +} + + +/** + * Function called with kyc target records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_kyc_targets (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.kyc_targets.h_normalized_payto), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.kyc_targets.access_token), + td->details.kyc_targets.no_account + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type ( + &td->details.kyc_targets.target_pub), + GNUNET_PQ_query_param_bool ( + td->details.kyc_targets.is_wallet), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_kyc_targets", + "INSERT INTO kyc_targets" + "(kyc_target_serial_id" + ",h_normalized_payto" + ",access_token" + ",target_pub" + ",is_wallet" + ") VALUES " + "($1, $2, $3, $4, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_kyc_targets", + params); +} + + +/** + * Function called with records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_legitimization_measures ( + struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.legitimization_measures.target_token), + GNUNET_PQ_query_param_timestamp ( + &td->details.legitimization_measures.start_time), + TALER_PQ_query_param_json ( + td->details.legitimization_measures.measures), + GNUNET_PQ_query_param_uint32 ( + &td->details.legitimization_measures.display_priority), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_legitimization_measures", + "INSERT INTO legitimization_measures" + "(legitimization_measure_serial_id" + ",access_token" + ",start_time" + ",jmeasures" + ",display_priority" + ") VALUES " + "($1, $2, $3, $4::TEXT::JSONB, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_legitimization_measures", + params); +} + + +/** + * Function called with records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_legitimization_outcomes ( + struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.legitimization_outcomes.h_payto), + GNUNET_PQ_query_param_timestamp ( + &td->details.legitimization_outcomes.decision_time), + GNUNET_PQ_query_param_timestamp ( + &td->details.legitimization_outcomes.expiration_time), + TALER_PQ_query_param_json ( + td->details.legitimization_outcomes.properties), + GNUNET_PQ_query_param_bool ( + td->details.legitimization_outcomes.to_investigate), + TALER_PQ_query_param_json ( + td->details.legitimization_outcomes.new_rules), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_legitimization_outcomes", + "INSERT INTO legitimization_outcomes" + "(outcome_serial_id" + ",h_payto" + ",decision_time" + ",expiration_time" + ",jproperties" + ",to_investigate" + ",jnew_rules" + ") VALUES " + "($1, $2, $3, $4, $5::TEXT::JSONB, $6, $7::TEXT::JSONB);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_legitimization_outcomes", + params); +} + + +/** + * Function called with records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_legitimization_processes ( + struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.legitimization_processes.h_payto), + GNUNET_PQ_query_param_timestamp ( + &td->details.legitimization_processes.start_time), + GNUNET_PQ_query_param_timestamp ( + &td->details.legitimization_processes.expiration_time), + GNUNET_PQ_query_param_uint64 ( + &td->details.legitimization_processes.legitimization_measure_serial_id), + GNUNET_PQ_query_param_uint32 ( + &td->details.legitimization_processes.measure_index), + GNUNET_PQ_query_param_string ( + td->details.legitimization_processes.provider_name), + GNUNET_PQ_query_param_string ( + td->details.legitimization_processes.provider_user_id), + GNUNET_PQ_query_param_string ( + td->details.legitimization_processes.provider_legitimization_id), + GNUNET_PQ_query_param_string ( + td->details.legitimization_processes.redirect_url), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_legitimization_processes", + "INSERT INTO legitimization_processes" + "(legitimization_process_serial_id" + ",h_payto" + ",start_time" + ",expiration_time" + ",legitimization_measure_serial_id" + ",measure_index" + ",provider_name" + ",provider_user_id" + ",provider_legitimization_id" + ",redirect_url" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_legitimization_processes", + params); +} + + +/** + * Function called with reserves records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_reserves (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&td->details.reserves.reserve_pub), + GNUNET_PQ_query_param_timestamp (&td->details.reserves.expiration_date), + GNUNET_PQ_query_param_timestamp (&td->details.reserves.gc_date), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_reserves", + "INSERT INTO reserves" + "(reserve_uuid" + ",reserve_pub" + ",expiration_date" + ",gc_date" + ") VALUES " + "($1, $2, $3, $4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_reserves", + params); +} + + +/** + * Function called with reserves_in records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_reserves_in (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 (&td->details.reserves_in.wire_reference), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.reserves_in.credit), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_in.sender_account_h_payto), + GNUNET_PQ_query_param_string ( + td->details.reserves_in.exchange_account_section), + GNUNET_PQ_query_param_timestamp ( + &td->details.reserves_in.execution_date), + GNUNET_PQ_query_param_auto_from_type (&td->details.reserves_in.reserve_pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_reserves_in", + "INSERT INTO reserves_in" + "(reserve_in_serial_id" + ",wire_reference" + ",credit" + ",wire_source_h_payto" + ",exchange_account_section" + ",execution_date" + ",reserve_pub" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_reserves_in", + params); +} + + +/** + * Function called with kycauth_in records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_kycauths_in (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 (&td->details.kycauth_in.wire_reference), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.reserves_in.credit), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_in.sender_account_h_payto), + GNUNET_PQ_query_param_string ( + td->details.reserves_in.exchange_account_section), + GNUNET_PQ_query_param_timestamp ( + &td->details.reserves_in.execution_date), + GNUNET_PQ_query_param_auto_from_type (&td->details.kycauth_in.account_pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_kycauth_in", + "INSERT INTO kycauths_in" + "(kycauth_in_serial_id" + ",wire_reference" + ",credit" + ",wire_source_h_payto" + ",exchange_account_section" + ",execution_date" + ",account_pub" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_kycauth_in", + params); +} + + +/** + * Function called with reserves_open_requests records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_reserves_open_requests (struct EXCHANGEDB_PostgresContext *ctx, + const struct + TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_timestamp ( + &td->details.reserves_open_requests.expiration_date), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_open_requests.reserve_sig), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.reserves_open_requests.reserve_payment), + GNUNET_PQ_query_param_uint32 ( + &td->details.reserves_open_requests.requested_purse_limit), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_reserves_open_requests", + "INSERT INTO reserves_open_requests" + "(open_request_uuid" + ",reserve_pub" + ",request_timestamp" + ",expiration_date" + ",reserve_sig" + ",reserve_payment" + ",requested_purse_limit" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_reserves_open_requests", + params); +} + + +/** + * Function called with reserves_open_requests records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_reserves_open_deposits ( + struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_open_deposits.coin_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_open_deposits.coin_sig), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_open_deposits.reserve_sig), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.reserves_open_deposits.contribution), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_reserves_open_deposits", + "INSERT INTO reserves_open_deposits" + "(reserve_open_deposit_uuid" + ",reserve_sig" + ",reserve_pub" + ",coin_pub" + ",coin_sig" + ",contribution" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_reserves_open_deposits", + params); +} + + +/** + * Function called with reserves_close records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_reserves_close (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_timestamp ( + &td->details.reserves_close.execution_date), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_close.wtid), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_close.sender_account_h_payto), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.reserves_close.amount), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.reserves_close.closing_fee), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.reserves_close.reserve_pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_reserves_close", + "INSERT INTO reserves_close" + "(close_uuid" + ",execution_date" + ",wtid" + ",wire_target_h_payto" + ",amount" + ",closing_fee" + ",reserve_pub" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_reserves_close", + params); +} + + +/** + * Function called with auditors records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_auditors (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&td->details.auditors.auditor_pub), + GNUNET_PQ_query_param_string (td->details.auditors.auditor_name), + GNUNET_PQ_query_param_string (td->details.auditors.auditor_url), + GNUNET_PQ_query_param_bool (td->details.auditors.is_active), + GNUNET_PQ_query_param_timestamp (&td->details.auditors.last_change), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_auditors", + "INSERT INTO auditors" + "(auditor_uuid" + ",auditor_pub" + ",auditor_name" + ",auditor_url" + ",is_active" + ",last_change" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_auditors", + params); +} + + +/** + * Function called with auditor_denom_sigs records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_auditor_denom_sigs (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 (&td->details.auditor_denom_sigs.auditor_uuid), + GNUNET_PQ_query_param_uint64 ( + &td->details.auditor_denom_sigs.denominations_serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.auditor_denom_sigs.auditor_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_auditor_denom_sigs", + "INSERT INTO auditor_denom_sigs" + "(auditor_denom_serial" + ",auditor_uuid" + ",denominations_serial" + ",auditor_sig" + ") VALUES " + "($1, $2, $3, $4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_auditor_denom_sigs", + params); +} + + +/** + * Function called with exchange_sign_keys records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_exchange_sign_keys (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.exchange_sign_keys.exchange_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.exchange_sign_keys.master_sig), + GNUNET_PQ_query_param_timestamp ( + &td->details.exchange_sign_keys.meta.start), + GNUNET_PQ_query_param_timestamp ( + &td->details.exchange_sign_keys.meta.expire_sign), + GNUNET_PQ_query_param_timestamp ( + &td->details.exchange_sign_keys.meta.expire_legal), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_exchange_sign_keys", + "INSERT INTO exchange_sign_keys" + "(esk_serial" + ",exchange_pub" + ",master_sig" + ",valid_from" + ",expire_sign" + ",expire_legal" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_exchange_sign_keys", + params); +} + + +/** + * Function called with signkey_revocations records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_signkey_revocations (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 (&td->details.signkey_revocations.esk_serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.signkey_revocations.master_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_signkey_revocations", + "INSERT INTO signkey_revocations" + "(signkey_revocations_serial_id" + ",esk_serial" + ",master_sig" + ") VALUES " + "($1, $2, $3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_signkey_revocations", + params); +} + + +/** + * Function called with known_coins records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_known_coins (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.known_coins.coin_pub), + TALER_PQ_query_param_denom_sig ( + &td->details.known_coins.denom_sig), + GNUNET_PQ_query_param_uint64 ( + &td->details.known_coins.denominations_serial), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_known_coins", + "INSERT INTO known_coins" + "(known_coin_id" + ",coin_pub" + ",denom_sig" + ",denominations_serial" + ") VALUES " + "($1, $2, $3, $4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_known_coins", + params); +} + + +/** + * Function called with refresh records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_refresh (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&td->details.refresh.rc), + GNUNET_PQ_query_param_auto_from_type (&td->details.refresh.execution_date), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.refresh.amount_with_fee), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.refresh.old_coin_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.refresh.old_coin_sig), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.refresh.refresh_seed), + GNUNET_PQ_query_param_uint32 ( + &td->details.refresh.noreveal_index), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.refresh.planchets_h), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.refresh.selected_h), + td->details.refresh.no_blinding_seed + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type ( + &td->details.refresh.blinding_seed), + td->details.refresh.no_blinding_seed + ? GNUNET_PQ_query_param_null () + : TALER_PQ_query_param_array_cs_r_pub ( + td->details.refresh.num_cs_r_values, + td->details.refresh.cs_r_values, + ctx->conn), + td->details.refresh.no_blinding_seed + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_uint64 ( + &td->details.refresh.cs_r_choices), + GNUNET_PQ_query_param_array_uint64 ( + td->details.refresh.num_coins, + td->details.refresh.denom_serials, + ctx->conn), + TALER_PQ_query_param_array_blinded_denom_sig ( + td->details.refresh.num_coins, + td->details.refresh.denom_sigs, + ctx->conn), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_refresh", + "INSERT INTO refresh" + "(refresh_id" + ",rc" + ",execution_date" + ",amount_with_fee" + ",old_coin_pub" + ",old_coin_sig" + ",refresh_seed" + ",noreveal_index" + ",planchets_h" + ",selected_h" + ",blinding_seed" + ",cs_r_values" + ",cs_r_choices" + ",denom_serials" + ",denom_sigs" + ") VALUES " + "($1, $2, $3, $4, $5, $6,$7,$8,$9,$10,$11,$12,$13,$14,$15);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_refresh", + params); +} + + +/** + * Function called with batch deposits records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_batch_deposits (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 (&td->details.batch_deposits.shard), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.batch_deposits.merchant_pub), + GNUNET_PQ_query_param_timestamp ( + &td->details.batch_deposits.wallet_timestamp), + GNUNET_PQ_query_param_timestamp ( + &td->details.batch_deposits.exchange_timestamp), + GNUNET_PQ_query_param_timestamp ( + &td->details.batch_deposits.refund_deadline), + GNUNET_PQ_query_param_timestamp (&td->details.batch_deposits.wire_deadline), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.batch_deposits.h_contract_terms), + td->details.batch_deposits.no_wallet_data_hash + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type ( + &td->details.batch_deposits.wallet_data_hash), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.batch_deposits.wire_salt), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.batch_deposits.wire_target_h_payto), + td->details.batch_deposits.no_policy_details + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_uint64 ( + &td->details.batch_deposits.policy_details_serial_id), + GNUNET_PQ_query_param_bool (td->details.batch_deposits.policy_blocked), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.batch_deposits.total_amount), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.batch_deposits.total_without_fee), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.batch_deposits.merchant_sig), + GNUNET_PQ_query_param_bool (td->details.batch_deposits.done), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_batch_deposits", + "INSERT INTO batch_deposits" + "(batch_deposit_serial_id" + ",shard" + ",merchant_pub" + ",wallet_timestamp" + ",exchange_timestamp" + ",refund_deadline" + ",wire_deadline" + ",h_contract_terms" + ",wallet_data_hash" + ",wire_salt" + ",wire_target_h_payto" + ",policy_details_serial_id" + ",policy_blocked" + ",total_amount" + ",total_without_fee" + ",merchant_sig" + ",done" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," + " $11, $12, $13, $14, $15, $16, $17);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_batch_deposits", + params); +} + + +/** + * Function called with deposits records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_coin_deposits (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 ( + &td->details.coin_deposits.batch_deposit_serial_id), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.coin_deposits.coin_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.coin_deposits.coin_sig), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.coin_deposits.amount_with_fee), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_coin_deposits", + "INSERT INTO coin_deposits" + "(coin_deposit_serial_id" + ",batch_deposit_serial_id" + ",coin_pub" + ",coin_sig" + ",amount_with_fee" + ") VALUES " + "($1, $2, $3, $4, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_coin_deposits", + params); +} + + +/** + * Function called with refunds records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_refunds (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&td->details.refunds.coin_pub), + GNUNET_PQ_query_param_auto_from_type (&td->details.refunds.merchant_sig), + GNUNET_PQ_query_param_uint64 (&td->details.refunds.rtransaction_id), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.refunds.amount_with_fee), + GNUNET_PQ_query_param_uint64 ( + &td->details.refunds.batch_deposit_serial_id), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_refunds", + "INSERT INTO refunds" + "(refund_serial_id" + ",coin_pub" + ",merchant_sig" + ",rtransaction_id" + ",amount_with_fee" + ",batch_deposit_serial_id" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_refunds", + params); +} + + +/** + * Function called with wire_out records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_wire_out (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_timestamp (&td->details.wire_out.execution_date), + GNUNET_PQ_query_param_auto_from_type (&td->details.wire_out.wtid_raw), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wire_out.wire_target_h_payto), + GNUNET_PQ_query_param_string ( + td->details.wire_out.exchange_account_section), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wire_out.amount), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_wire_out", + "INSERT INTO wire_out" + "(wireout_uuid" + ",execution_date" + ",wtid_raw" + ",wire_target_h_payto" + ",exchange_account_section" + ",amount" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_wire_out", + params); +} + + +/** + * Function called with aggregation_tracking records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_aggregation_tracking (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 ( + &td->details.aggregation_tracking.batch_deposit_serial_id), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.aggregation_tracking.wtid_raw), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_aggregation_tracking", + "INSERT INTO aggregation_tracking" + "(aggregation_serial_id" + ",batch_deposit_serial_id" + ",wtid_raw" + ") VALUES " + "($1, $2, $3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_aggregation_tracking", + params); +} + + +/** + * Function called with wire_fee records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_wire_fee (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_string (td->details.wire_fee.wire_method), + GNUNET_PQ_query_param_timestamp (&td->details.wire_fee.start_date), + GNUNET_PQ_query_param_timestamp (&td->details.wire_fee.end_date), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wire_fee.fees.wire), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wire_fee.fees.closing), + GNUNET_PQ_query_param_auto_from_type (&td->details.wire_fee.master_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_wire_fee", + "INSERT INTO wire_fee" + "(wire_fee_serial" + ",wire_method" + ",start_date" + ",end_date" + ",wire_fee" + ",closing_fee" + ",master_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_wire_fee", + params); +} + + +/** + * Function called with wire_fee records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_global_fee (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 ( + &td->serial), + GNUNET_PQ_query_param_timestamp ( + &td->details.global_fee.start_date), + GNUNET_PQ_query_param_timestamp ( + &td->details.global_fee.end_date), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.global_fee.fees.history), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.global_fee.fees.account), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.global_fee.fees.purse), + GNUNET_PQ_query_param_relative_time ( + &td->details.global_fee.purse_timeout), + GNUNET_PQ_query_param_relative_time ( + &td->details.global_fee.history_expiration), + GNUNET_PQ_query_param_uint32 ( + &td->details.global_fee.purse_account_limit), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.global_fee.master_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_global_fee", + "INSERT INTO global_fee" + "(global_fee_serial" + ",start_date" + ",end_date" + ",history_fee" + ",account_fee" + ",purse_fee" + ",purse_timeout" + ",history_expiration" + ",purse_account_limit" + ",master_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_global_fee", + params); +} + + +/** + * Function called with recoup records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_recoup (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&td->details.recoup.coin_sig), + GNUNET_PQ_query_param_auto_from_type (&td->details.recoup.coin_blind), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.recoup.amount), + GNUNET_PQ_query_param_timestamp (&td->details.recoup.timestamp), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.recoup.coin_pub), + GNUNET_PQ_query_param_uint64 (&td->details.recoup.withdraw_serial_id), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_recoup", + "INSERT INTO recoup" + "(recoup_uuid" + ",coin_sig" + ",coin_blind" + ",amount" + ",recoup_timestamp" + ",coin_pub" + ",withdraw_serial_id" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_recoup", + params); +} + + +/** + * Function called with recoup_refresh records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_recoup_refresh (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&td->details.recoup_refresh.coin_sig), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.recoup_refresh.coin_blind), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.recoup_refresh.amount), + GNUNET_PQ_query_param_timestamp (&td->details.recoup_refresh.timestamp), + GNUNET_PQ_query_param_uint64 (&td->details.recoup_refresh.known_coin_id), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.recoup.coin_pub), + GNUNET_PQ_query_param_uint64 (&td->details.recoup_refresh.rrc_serial), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_recoup_refresh", + "INSERT INTO recoup_refresh" + "(recoup_refresh_uuid" + ",coin_sig" + ",coin_blind" + ",amount" + ",recoup_timestamp" + ",known_coin_id" + ",coin_pub" + ",rrc_serial" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_recoup_refresh", + params); +} + + +/** + * Function called with extensions records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_extensions (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_string (td->details.extensions.name), + NULL == td->details.extensions.manifest ? + GNUNET_PQ_query_param_null () : + GNUNET_PQ_query_param_string (td->details.extensions.manifest), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_extensions", + "INSERT INTO extensions" + "(extension_id" + ",name" + ",manifest" + ") VALUES " + "($1, $2, $3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_extensions", + params); +} + + +/** + * Function called with policy_details records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_policy_details (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.policy_details.hash_code), + (td->details.policy_details.no_policy_json) + ? GNUNET_PQ_query_param_null () + : TALER_PQ_query_param_json (td->details.policy_details.policy_json), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.policy_details.commitment), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.policy_details.accumulated_total), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.policy_details.fee), + TALER_PQ_query_param_amount (ctx->conn, + &td->details.policy_details.transferable), + GNUNET_PQ_query_param_timestamp (&td->details.policy_details.deadline), + GNUNET_PQ_query_param_uint16 ( + &td->details.policy_details.fulfillment_state), + (td->details.policy_details.no_fulfillment_id) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_uint64 ( + &td->details.policy_details.fulfillment_id), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_policy_details", + "INSERT INTO policy_details" + "(policy_details_serial_id" + ",policy_hash_code" + ",policy_json" + ",deadline" + ",commitment" + ",accumulated_total" + ",fee" + ",transferable" + ",fulfillment_state" + ",fulfillment_id" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_policy_details", + params); +} + + +/** + * Function called with policy_fulfillment records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_policy_fulfillments (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_timestamp ( + &td->details.policy_fulfillments.fulfillment_timestamp), + (NULL == td->details.policy_fulfillments.fulfillment_proof) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string ( + td->details.policy_fulfillments.fulfillment_proof), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.policy_fulfillments.h_fulfillment_proof), + GNUNET_PQ_query_param_fixed_size ( + td->details.policy_fulfillments.policy_hash_codes, + td->details.policy_fulfillments.policy_hash_codes_count), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_policy_fulfillments", + "INSERT INTO policy_fulfillments " + "(fulfillment_id" + ",fulfillment_timestamp" + ",fulfillment_proof" + ",h_fulfillment_proof" + ",policy_hash_codes" + ") VALUES " + "($1, $2, $3::TEXT::JSONB, $4, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_policy_fulfillments", + params); +} + + +/** + * Function called with purse_requests records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_purse_requests (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_requests.purse_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_requests.merge_pub), + GNUNET_PQ_query_param_timestamp ( + &td->details.purse_requests.purse_creation), + GNUNET_PQ_query_param_timestamp ( + &td->details.purse_requests.purse_expiration), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_requests.h_contract_terms), + GNUNET_PQ_query_param_uint32 (&td->details.purse_requests.age_limit), + GNUNET_PQ_query_param_uint32 (&td->details.purse_requests.flags), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.purse_requests.amount_with_fee), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.purse_requests.purse_fee), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_requests.purse_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_purse_requests", + "INSERT INTO purse_requests" + "(purse_requests_serial_id" + ",purse_pub" + ",merge_pub" + ",purse_creation" + ",purse_expiration" + ",h_contract_terms" + ",age_limit" + ",flags" + ",amount_with_fee" + ",purse_fee" + ",purse_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_purse_requests", + params); +} + + +/** + * Function called with purse_decision records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_purse_decision (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_decision.purse_pub), + GNUNET_PQ_query_param_timestamp ( + &td->details.purse_decision.action_timestamp), + GNUNET_PQ_query_param_bool ( + td->details.purse_decision.refunded), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_purse_refunds", + "INSERT INTO purse_refunds" + "(purse_refunds_serial_id" + ",purse_pub" + ",action_timestamp" + ",refunded" + ") VALUES " + "($1, $2, $3, $4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_purse_decision", + params); +} + + +/** + * Function called with purse_merges records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_purse_merges (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 (&td->details.purse_merges.partner_serial_id), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_merges.reserve_pub), + GNUNET_PQ_query_param_auto_from_type (&td->details.purse_merges.purse_pub), + GNUNET_PQ_query_param_auto_from_type (&td->details.purse_merges.merge_sig), + GNUNET_PQ_query_param_timestamp (&td->details.purse_merges.merge_timestamp), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_purse_merges", + "INSERT INTO purse_merges" + "(purse_merge_request_serial_id" + ",partner_serial_id" + ",reserve_pub" + ",purse_pub" + ",merge_sig" + ",merge_timestamp" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_purse_merges", + params); +} + + +/** + * Function called with purse_deposits records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_purse_deposits (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 ( + &td->details.purse_deposits.partner_serial_id), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_deposits.purse_pub), + GNUNET_PQ_query_param_auto_from_type (&td->details.purse_deposits.coin_pub), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.purse_deposits.amount_with_fee), + GNUNET_PQ_query_param_auto_from_type (&td->details.purse_deposits.coin_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_purse_deposits", + "INSERT INTO purse_deposits" + "(purse_deposit_serial_id" + ",partner_serial_id" + ",purse_pub" + ",coin_pub" + ",amount_with_fee" + ",coin_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_purse_deposits", + params); +} + + +/** +x * Function called with account_mergers records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_account_mergers (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.account_merges.reserve_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.account_merges.reserve_sig), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.account_merges.purse_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.account_merges.wallet_h_payto), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_account_merges", + "INSERT INTO account_merges" + "(account_merge_request_serial_id" + ",reserve_pub" + ",reserve_sig" + ",purse_pub" + ",wallet_h_payto" + ") VALUES " + "($1, $2, $3, $4, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_account_merges", + params); +} + + +/** + * Function called with history_requests records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_history_requests (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.history_requests.reserve_pub), + GNUNET_PQ_query_param_timestamp ( + &td->details.history_requests.request_timestamp), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.history_requests.reserve_sig), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.history_requests.history_fee), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_history_requests", + "INSERT INTO history_requests" + "(history_request_serial_id" + ",reserve_pub" + ",request_timestamp" + ",reserve_sig" + ",history_fee" + ") VALUES " + "($1, $2, $3, $4, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_history_requests", + params); +} + + +/** + * Function called with close_requests records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_close_requests (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.close_requests.reserve_pub), + GNUNET_PQ_query_param_timestamp ( + &td->details.close_requests.close_timestamp), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.close_requests.reserve_sig), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.close_requests.close), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.close_requests.close_fee), + GNUNET_PQ_query_param_string ( + td->details.close_requests.payto_uri.full_payto), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_close_requests", + "INSERT INTO close_requests" + "(close_request_serial_id" + ",reserve_pub" + ",close_timestamp" + ",reserve_sig" + ",close" + ",close_fee" + ",payto_uri" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_close_requests", + params); +} + + +/** + * Function called with wads_out records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_wads_out (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&td->details.wads_out.wad_id), + GNUNET_PQ_query_param_uint64 (&td->details.wads_out.partner_serial_id), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wads_out.amount), + GNUNET_PQ_query_param_timestamp (&td->details.wads_out.execution_time), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_wads_out", + "INSERT INTO wads_out" + "(wad_out_serial_id" + ",wad_id" + ",partner_serial_id" + ",amount" + ",execution_time" + ") VALUES " + "($1, $2, $3, $4, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_wads_out", + params); +} + + +/** + * Function called with wads_out_entries records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_wads_out_entries (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_uint64 ( + &td->details.wads_out_entries.wad_out_serial_id), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_out_entries.reserve_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_out_entries.purse_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_out_entries.h_contract), + GNUNET_PQ_query_param_timestamp ( + &td->details.wads_out_entries.purse_expiration), + GNUNET_PQ_query_param_timestamp ( + &td->details.wads_out_entries.merge_timestamp), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wads_out_entries.amount_with_fee), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wads_out_entries.wad_fee), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wads_out_entries.deposit_fees), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_out_entries.reserve_sig), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_out_entries.purse_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_wad_out_entries", + "INSERT INTO wad_out_entries" + "(wad_out_entry_serial_id" + ",wad_out_serial_id" + ",reserve_pub" + ",purse_pub" + ",h_contract" + ",purse_expiration" + ",merge_timestamp" + ",amount_with_fee" + ",wad_fee" + ",deposit_fees" + ",reserve_sig" + ",purse_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_wads_out_entries", + params); +} + + +/** + * Function called with wads_in records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_wads_in (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type (&td->details.wads_in.wad_id), + GNUNET_PQ_query_param_string (td->details.wads_in.origin_exchange_url), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wads_in.amount), + GNUNET_PQ_query_param_timestamp (&td->details.wads_in.arrival_time), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_wads_in", + "INSERT INTO wads_in" + "(wad_in_serial_id" + ",wad_id" + ",origin_exchange_url" + ",amount" + ",arrival_time" + ") VALUES " + "($1, $2, $3, $4, $5);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_wads_in", + params); +} + + +/** + * Function called with wads_in_entries records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_wads_in_entries (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_in_entries.reserve_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_in_entries.purse_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_in_entries.h_contract), + GNUNET_PQ_query_param_timestamp ( + &td->details.wads_in_entries.purse_expiration), + GNUNET_PQ_query_param_timestamp ( + &td->details.wads_in_entries.merge_timestamp), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wads_in_entries.amount_with_fee), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wads_in_entries.wad_fee), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.wads_in_entries.deposit_fees), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_in_entries.reserve_sig), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.wads_in_entries.purse_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_wad_in_entries", + "INSERT INTO wad_in_entries" + "(wad_in_entry_serial_id" + ",wad_in_serial_id" + ",reserve_pub" + ",purse_pub" + ",h_contract" + ",purse_expiration" + ",merge_timestamp" + ",amount_with_fee" + ",wad_fee" + ",deposit_fees" + ",reserve_sig" + ",purse_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_wads_in_entries", + params); +} + + +/** + * Function called with profit_drains records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_profit_drains (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.profit_drains.wtid), + GNUNET_PQ_query_param_string ( + td->details.profit_drains.account_section), + GNUNET_PQ_query_param_string ( + td->details.profit_drains.payto_uri.full_payto), + GNUNET_PQ_query_param_timestamp ( + &td->details.profit_drains.trigger_date), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.profit_drains.amount), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.profit_drains.master_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_profit_drains", + "INSERT INTO profit_drains" + "(profit_drain_serial_id" + ",wtid" + ",account_section" + ",payto_uri" + ",trigger_date" + ",amount" + ",master_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_profit_drains", + params); +} + + +/** + * Function called with aml_staff records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_aml_staff (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.aml_staff.decider_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.aml_staff.master_sig), + GNUNET_PQ_query_param_string ( + td->details.aml_staff.decider_name), + GNUNET_PQ_query_param_bool ( + td->details.aml_staff.is_active), + GNUNET_PQ_query_param_bool ( + td->details.aml_staff.read_only), + GNUNET_PQ_query_param_timestamp ( + &td->details.aml_staff.last_change), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_aml_staff", + "INSERT INTO aml_staff" + "(aml_staff_uuid" + ",decider_pub" + ",master_sig" + ",decider_name" + ",is_active" + ",read_only" + ",last_change" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_aml_staff", + params); +} + + +/** + * Function called with kyc_attributes records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_kyc_attributes (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.kyc_attributes.h_payto), + GNUNET_PQ_query_param_uint64 ( + &td->details.kyc_attributes.legitimization_serial), + GNUNET_PQ_query_param_timestamp ( + &td->details.kyc_attributes.collection_time), + GNUNET_PQ_query_param_timestamp ( + &td->details.kyc_attributes.expiration_time), + GNUNET_PQ_query_param_uint64 ( + &td->details.kyc_attributes.trigger_outcome_serial), + GNUNET_PQ_query_param_fixed_size ( + &td->details.kyc_attributes.encrypted_attributes, + td->details.kyc_attributes.encrypted_attributes_size), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_kyc_attributes", + "INSERT INTO kyc_attributes" + "(kyc_attributes_serial_id" + ",h_payto" + ",legitimization_serial" + ",collection_time" + ",expiration_time" + ",trigger_outcome_serial" + ",encrypted_attributes" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_kyc_attributes", + params); +} + + +/** + * Function called with aml_history records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_aml_history (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.aml_history.h_payto), + GNUNET_PQ_query_param_uint64 ( + &td->details.aml_history.outcome_serial_id), + GNUNET_PQ_query_param_string ( + td->details.aml_history.justification), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.aml_history.decider_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.aml_history.decider_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_aml_history", + "INSERT INTO aml_history" + "(aml_history_serial_id" + ",h_payto" + ",outcome_serial_id" + ",justification" + ",decider_pub" + ",decider_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_aml_history", + params); +} + + +/** + * Function called with kyc_event records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_kyc_events (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_timestamp ( + &td->details.kyc_events.event_timestamp), + GNUNET_PQ_query_param_string ( + td->details.kyc_events.event_type), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_kyc_events", + "INSERT INTO kyc_events" + "(kyc_event_serial_id" + ",event_timestamp" + ",event_type" + ") VALUES " + "($1, $2, $3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_kyc_events", + params); +} + + +/** + * Function called with purse_deletion records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_purse_deletion (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_deletion.purse_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.purse_deletion.purse_sig), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_into_table_purse_deletion", + "INSERT INTO purse_deletion" + "(purse_deletion_serial_id" + ",purse_pub" + ",purse_sig" + ") VALUES " + "($1, $2, $3);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_purse_deletion", + params); +} + + +/** + * Function called with withdraw records to insert into table. + * + * @param ctx plugin context + * @param td record to insert + */ +static enum GNUNET_DB_QueryStatus +irbt_cb_table_withdraw ( + struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&td->serial), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.withdraw.planchets_h), + GNUNET_PQ_query_param_timestamp ( + &td->details.withdraw.execution_date), + TALER_PQ_query_param_amount ( + ctx->conn, + &td->details.withdraw.amount_with_fee), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.withdraw.reserve_pub), + GNUNET_PQ_query_param_auto_from_type ( + &td->details.withdraw.reserve_sig), + td->details.withdraw.age_proof_required + ? GNUNET_PQ_query_param_uint16 ( + &td->details.withdraw.max_age) + : GNUNET_PQ_query_param_null (), + td->details.withdraw.age_proof_required + ? GNUNET_PQ_query_param_uint16 ( + &td->details.withdraw.noreveal_index) + : GNUNET_PQ_query_param_null (), + td->details.withdraw.age_proof_required + ? GNUNET_PQ_query_param_auto_from_type ( + &td->details.withdraw.selected_h) + : GNUNET_PQ_query_param_null (), + td->details.withdraw.no_blinding_seed + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type ( + &td->details.withdraw.blinding_seed), + (0 < td->details.withdraw.num_cs_r_values) + ? TALER_PQ_query_param_array_cs_r_pub ( + td->details.withdraw.num_cs_r_values, + td->details.withdraw.cs_r_values, + ctx->conn) + : GNUNET_PQ_query_param_null (), + (0 < td->details.withdraw.num_cs_r_values) + ? GNUNET_PQ_query_param_uint64 ( + &td->details.withdraw.cs_r_choices) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_array_uint64 ( + td->details.withdraw.num_coins, + td->details.withdraw.denom_serials, + ctx->conn), + TALER_PQ_query_param_array_blinded_denom_sig ( + td->details.withdraw.num_coins, + td->details.withdraw.denom_sigs, + ctx->conn), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "insert_into_table_withdraw", + "INSERT INTO withdraw" + "(withdraw_id" + ",planchets_h" + ",execution_date" + ",amount_with_fee" + ",reserve_pub" + ",reserve_sig" + ",max_age" + ",noreveal_index" + ",selected_h" + ",blinding_seed" + ",cs_r_values" + ",cs_r_choices" + ",denom_serials" + ",denom_sigs" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);"); + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_into_table_withdraw", + params); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_records_by_table (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td) +{ + InsertRecordCallback rh = NULL; + + switch (td->table) + { + case TALER_EXCHANGEDB_RT_DENOMINATIONS: + rh = &irbt_cb_table_denominations; + break; + case TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS: + rh = &irbt_cb_table_denomination_revocations; + break; + case TALER_EXCHANGEDB_RT_WIRE_TARGETS: + rh = &irbt_cb_table_wire_targets; + break; + case TALER_EXCHANGEDB_RT_KYC_TARGETS: + rh = &irbt_cb_table_kyc_targets; + break; + case TALER_EXCHANGEDB_RT_RESERVES: + rh = &irbt_cb_table_reserves; + break; + case TALER_EXCHANGEDB_RT_RESERVES_IN: + rh = &irbt_cb_table_reserves_in; + break; + case TALER_EXCHANGEDB_RT_KYCAUTHS_IN: + rh = &irbt_cb_table_kycauths_in; + break; + case TALER_EXCHANGEDB_RT_RESERVES_CLOSE: + rh = &irbt_cb_table_reserves_close; + break; + case TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS: + rh = &irbt_cb_table_reserves_open_requests; + break; + case TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS: + rh = &irbt_cb_table_reserves_open_deposits; + break; + case TALER_EXCHANGEDB_RT_AUDITORS: + rh = &irbt_cb_table_auditors; + break; + case TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS: + rh = &irbt_cb_table_auditor_denom_sigs; + break; + case TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS: + rh = &irbt_cb_table_exchange_sign_keys; + break; + case TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS: + rh = &irbt_cb_table_signkey_revocations; + break; + case TALER_EXCHANGEDB_RT_KNOWN_COINS: + rh = &irbt_cb_table_known_coins; + break; + case TALER_EXCHANGEDB_RT_REFRESH: + rh = &irbt_cb_table_refresh; + break; + case TALER_EXCHANGEDB_RT_BATCH_DEPOSITS: + rh = &irbt_cb_table_batch_deposits; + break; + case TALER_EXCHANGEDB_RT_COIN_DEPOSITS: + rh = &irbt_cb_table_coin_deposits; + break; + case TALER_EXCHANGEDB_RT_REFUNDS: + rh = &irbt_cb_table_refunds; + break; + case TALER_EXCHANGEDB_RT_WIRE_OUT: + rh = &irbt_cb_table_wire_out; + break; + case TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING: + rh = &irbt_cb_table_aggregation_tracking; + break; + case TALER_EXCHANGEDB_RT_WIRE_FEE: + rh = &irbt_cb_table_wire_fee; + break; + case TALER_EXCHANGEDB_RT_GLOBAL_FEE: + rh = &irbt_cb_table_global_fee; + break; + case TALER_EXCHANGEDB_RT_RECOUP: + rh = &irbt_cb_table_recoup; + break; + case TALER_EXCHANGEDB_RT_RECOUP_REFRESH: + rh = &irbt_cb_table_recoup_refresh; + break; + case TALER_EXCHANGEDB_RT_EXTENSIONS: + rh = &irbt_cb_table_extensions; + break; + case TALER_EXCHANGEDB_RT_POLICY_DETAILS: + rh = &irbt_cb_table_policy_details; + break; + case TALER_EXCHANGEDB_RT_POLICY_FULFILLMENTS: + rh = &irbt_cb_table_policy_fulfillments; + break; + case TALER_EXCHANGEDB_RT_PURSE_REQUESTS: + rh = &irbt_cb_table_purse_requests; + break; + case TALER_EXCHANGEDB_RT_PURSE_DECISION: + rh = &irbt_cb_table_purse_decision; + break; + case TALER_EXCHANGEDB_RT_PURSE_MERGES: + rh = &irbt_cb_table_purse_merges; + break; + case TALER_EXCHANGEDB_RT_PURSE_DEPOSITS: + rh = &irbt_cb_table_purse_deposits; + break; + case TALER_EXCHANGEDB_RT_ACCOUNT_MERGES: + rh = &irbt_cb_table_account_mergers; + break; + case TALER_EXCHANGEDB_RT_HISTORY_REQUESTS: + rh = &irbt_cb_table_history_requests; + break; + case TALER_EXCHANGEDB_RT_CLOSE_REQUESTS: + rh = &irbt_cb_table_close_requests; + break; + case TALER_EXCHANGEDB_RT_WADS_OUT: + rh = &irbt_cb_table_wads_out; + break; + case TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES: + rh = &irbt_cb_table_wads_out_entries; + break; + case TALER_EXCHANGEDB_RT_WADS_IN: + rh = &irbt_cb_table_wads_in; + break; + case TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES: + rh = &irbt_cb_table_wads_in_entries; + break; + case TALER_EXCHANGEDB_RT_PROFIT_DRAINS: + rh = &irbt_cb_table_profit_drains; + break; + case TALER_EXCHANGEDB_RT_AML_STAFF: + rh = &irbt_cb_table_aml_staff; + break; + case TALER_EXCHANGEDB_RT_PURSE_DELETION: + rh = &irbt_cb_table_purse_deletion; + break; + case TALER_EXCHANGEDB_RT_WITHDRAW: + rh = &irbt_cb_table_withdraw; + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_MEASURES: + rh = &irbt_cb_table_legitimization_measures; + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_OUTCOMES: + rh = &irbt_cb_table_legitimization_outcomes; + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES: + rh = &irbt_cb_table_legitimization_processes; + break; + case TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES: + rh = &irbt_cb_table_kyc_attributes; + break; + case TALER_EXCHANGEDB_RT_AML_HISTORY: + rh = &irbt_cb_table_aml_history; + break; + case TALER_EXCHANGEDB_RT_KYC_EVENTS: + rh = &irbt_cb_table_kyc_events; + break; + } + if (NULL == rh) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return rh (ctx, + td); +} + + +/* end of pg_insert_records_by_table.c */ diff --git a/src/exchangedb/insert_refund.c b/src/exchangedb/insert_refund.c @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_refund.c + * @brief Implementation of the insert_refund function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_refund.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_refund (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_Refund *refund) +{ + struct GNUNET_PQ_QueryParam params[] = { + 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_auto_from_type (&refund->details.h_contract_terms), + GNUNET_PQ_query_param_uint64 (&refund->details.rtransaction_id), + TALER_PQ_query_param_amount (ctx->conn, + &refund->details.refund_amount), + GNUNET_PQ_query_param_end + }; + + GNUNET_assert (GNUNET_YES == + TALER_amount_cmp_currency (&refund->details.refund_amount, + &refund->details.refund_fee)); + PREPARE (ctx, + "insert_refund", + "INSERT INTO refunds " + "(coin_pub" + ",batch_deposit_serial_id" + ",merchant_sig" + ",rtransaction_id" + ",amount_with_fee" + ") SELECT $1, cdep.batch_deposit_serial_id, $3, $5, $6" + " FROM coin_deposits cdep" + " JOIN batch_deposits bdep USING (batch_deposit_serial_id)" + " WHERE coin_pub=$1" + " AND h_contract_terms=$4" + " AND merchant_pub=$2"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_refund", + params); +} diff --git a/src/exchangedb/insert_reserve_closed.c b/src/exchangedb/insert_reserve_closed.c @@ -0,0 +1,111 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_reserve_closed.c + * @brief Implementation of the insert_reserve_closed function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_reserve_closed.h" +#include "pg_helper.h" +#include "pg_reserves_get.h" +#include "pg_reserves_update.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_reserve_closed (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct GNUNET_TIME_Timestamp execution_date, + const struct TALER_FullPayto receiver_account, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *closing_fee, + uint64_t close_request_row) +{ + struct TALER_EXCHANGEDB_Reserve reserve; + enum GNUNET_DB_QueryStatus qs; + struct TALER_FullPaytoHashP h_payto; + + TALER_full_payto_hash (receiver_account, + &h_payto); + { + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_timestamp (&execution_date), + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_auto_from_type (&h_payto), + TALER_PQ_query_param_amount (ctx->conn, + amount_with_fee), + TALER_PQ_query_param_amount (ctx->conn, + closing_fee), + GNUNET_PQ_query_param_uint64 (&close_request_row), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "reserves_close_insert", + "INSERT INTO reserves_close " + "(reserve_pub" + ",execution_date" + ",wtid" + ",wire_target_h_payto" + ",amount" + ",closing_fee" + ",close_request_row" + ") VALUES ($1, $2, $3, $4, $5, $6, $7);"); + + qs = GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "reserves_close_insert", + params); + } + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + return qs; + + /* update reserve balance */ + reserve.pub = *reserve_pub; + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + (qs = EXCHANGEDB_reserves_get (cls, + &reserve))) + { + /* Existence should have been checked before we got here... */ + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + qs = GNUNET_DB_STATUS_HARD_ERROR; + return qs; + } + { + 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); + } + return EXCHANGEDB_reserves_update (cls, + &reserve); +} diff --git a/src/exchangedb/insert_reserve_open_deposit.c b/src/exchangedb/insert_reserve_open_deposit.c @@ -0,0 +1,65 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_reserve_open_deposit.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_reserve_open_deposit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_reserve_open_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo *cpi, + const struct TALER_CoinSpendSignatureP *coin_sig, + uint64_t known_coin_id, + const struct TALER_Amount *coin_total, + const struct TALER_ReserveSignatureP *reserve_sig, + const struct TALER_ReservePublicKeyP *reserve_pub, + bool *insufficient_funds) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&cpi->coin_pub), + GNUNET_PQ_query_param_uint64 (&known_coin_id), + GNUNET_PQ_query_param_auto_from_type (coin_sig), + GNUNET_PQ_query_param_auto_from_type (reserve_sig), + GNUNET_PQ_query_param_auto_from_type (reserve_pub), + TALER_PQ_query_param_amount (ctx->conn, + coin_total), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("out_insufficient_funds", + insufficient_funds), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "insert_reserve_open_deposit", + "SELECT " + " out_insufficient_funds" + " FROM exchange_do_reserve_open_deposit" + " ($1,$2,$3,$4,$5,$6);"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "insert_reserve_open_deposit", + params, + rs); +} diff --git a/src/exchangedb/insert_sanction_list_hit.c b/src/exchangedb/insert_sanction_list_hit.c @@ -0,0 +1,92 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_sanction_list_hit.c + * @brief Implementation of the insert_sanction_list_hit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_sanction_list_hit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_sanction_list_hit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + bool to_investigate, + const json_t *new_rules, + const json_t *account_properties, + unsigned int num_events, + const char **events) +{ + struct GNUNET_TIME_Timestamp never + = GNUNET_TIME_UNIT_FOREVER_TS; + struct GNUNET_TIME_Timestamp now + = GNUNET_TIME_timestamp_get (); + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = *h_payto + }; + char *notify_s + = GNUNET_PQ_get_event_notify_channel (&rep.header); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_timestamp (&now), + GNUNET_PQ_query_param_timestamp (&never), + NULL != account_properties + ? TALER_PQ_query_param_json (account_properties) + : GNUNET_PQ_query_param_null (), + NULL != new_rules + ? TALER_PQ_query_param_json (new_rules) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_bool (to_investigate), + GNUNET_PQ_query_param_string (notify_s), + GNUNET_PQ_query_param_array_ptrs_string (num_events, + events, + ctx->conn), + GNUNET_PQ_query_param_end + }; + uint64_t outcome_serial_id; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("outcome_serial_id", + &outcome_serial_id), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "do_insert_sanction_list_hit", + "SELECT" + " out_outcome_serial_id AS outcome_serial_id" + " FROM exchange_do_insert_sanction_list_hit" + "($1,$2,$3,$4::TEXT::JSONB,$5::TEXT::JSONB,$6,$7,$8);"); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Inserting LEGI OUTCOME from sanction list hit\n"); + qs = GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "do_insert_sanction_list_hit", + params, + rs); + (void) outcome_serial_id; + GNUNET_PQ_cleanup_query_params_closures (params); + GNUNET_free (notify_s); + GNUNET_PQ_event_do_poll (ctx->conn); + return qs; +} diff --git a/src/exchangedb/insert_signkey_revocation.c b/src/exchangedb/insert_signkey_revocation.c @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_signkey_revocation.c + * @brief Implementation of the insert_signkey_revocation function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_signkey_revocation.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_signkey_revocation (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + 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 + }; + + + PREPARE (ctx, + "insert_signkey_revocation", + "INSERT INTO signkey_revocations " + "(esk_serial" + ",master_sig" + ") SELECT esk_serial, $2 " + " FROM exchange_sign_keys" + " WHERE exchange_pub=$1;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_signkey_revocation", + params); +} diff --git a/src/exchangedb/insert_successor_measure.c b/src/exchangedb/insert_successor_measure.c @@ -0,0 +1,86 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_successor_measure.c + * @brief Implementation of the insert_succesor_measure function for Postgres + * @author Florian Dold + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_successor_measure.h" +#include "pg_helper.h" +#include <gnunet/gnunet_pq_lib.h> + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_successor_measure (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp decision_time, + const char *new_measure_name, + const json_t *jmeasures, + bool *unknown_account, + struct GNUNET_TIME_Timestamp *last_date) +{ + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = *h_payto + }; + /* We're reverting back to default rules => never expires.*/ + struct GNUNET_TIME_Timestamp expiration_time = { + .abs_time = GNUNET_TIME_UNIT_FOREVER_ABS, + }; + char *notify_s + = GNUNET_PQ_get_event_notify_channel (&rep.header); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_timestamp (&decision_time), + GNUNET_PQ_query_param_timestamp (&expiration_time), + NULL != new_measure_name + ? GNUNET_PQ_query_param_string (new_measure_name) + : GNUNET_PQ_query_param_null (), + NULL != jmeasures + ? TALER_PQ_query_param_json (jmeasures) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("out_account_unknown", + unknown_account), + GNUNET_PQ_result_spec_timestamp ("out_last_date", + last_date), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "do_insert_successor_measure", + "SELECT" + " out_account_unknown" + ",out_last_date" + ",out_legitimization_measure_serial_id" + " FROM exchange_do_insert_successor_measure" + "($1, $2, $3, $4, $5::TEXT::JSONB);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "do_insert_successor_measure", + params, + rs); + GNUNET_free (notify_s); + GNUNET_PQ_event_do_poll (ctx->conn); + return qs; +} diff --git a/src/exchangedb/insert_wire.c b/src/exchangedb/insert_wire.c @@ -0,0 +1,83 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_wire.c + * @brief Implementation of the insert_wire function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_wire.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_wire (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + const char *conversion_url, + const char *open_banking_gateway, + const char *wire_transfer_gateway, + const json_t *debit_restrictions, + const json_t *credit_restrictions, + struct GNUNET_TIME_Timestamp start_date, + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (payto_uri.full_payto), + NULL == conversion_url + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (conversion_url), + TALER_PQ_query_param_json (debit_restrictions), + TALER_PQ_query_param_json (credit_restrictions), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_timestamp (&start_date), + NULL == bank_label + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (bank_label), + GNUNET_PQ_query_param_int64 (&priority), + NULL == open_banking_gateway + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (open_banking_gateway), + NULL == wire_transfer_gateway + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (wire_transfer_gateway), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_wire", + "INSERT INTO wire_accounts " + "(payto_uri" + ",conversion_url" + ",debit_restrictions" + ",credit_restrictions" + ",master_sig" + ",is_active" + ",last_change" + ",bank_label" + ",priority" + ",open_banking_gateway" + ",wire_transfer_gateway" + ") VALUES " + "($1,$2,$3::TEXT::JSONB,$4::TEXT::JSONB,$5,true,$6,$7,$8,$9,$10);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_wire", + params); +} diff --git a/src/exchangedb/insert_wire_fee.c b/src/exchangedb/insert_wire_fee.c @@ -0,0 +1,109 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/insert_wire_fee.c + * @brief Implementation of the insert_wire_fee function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "insert_wire_fee.h" +#include "pg_helper.h" +#include "pg_get_wire_fee.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_wire_fee (struct EXCHANGEDB_PostgresContext *ctx, + const char *type, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + const struct TALER_WireFeeSet *fees, + const struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (type), + GNUNET_PQ_query_param_timestamp (&start_date), + GNUNET_PQ_query_param_timestamp (&end_date), + TALER_PQ_query_param_amount (ctx->conn, + &fees->wire), + TALER_PQ_query_param_amount (ctx->conn, + &fees->closing), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_end + }; + struct TALER_WireFeeSet wx; + struct TALER_MasterSignatureP sig; + struct GNUNET_TIME_Timestamp sd; + struct GNUNET_TIME_Timestamp ed; + enum GNUNET_DB_QueryStatus qs; + uint64_t rowid; + + qs = EXCHANGEDB_get_wire_fee (ctx, + type, + start_date, + &rowid, + &sd, + &ed, + &wx, + &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_wire_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; + } + /* equal record already exists */ + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + + PREPARE (ctx, + "insert_wire_fee", + "INSERT INTO wire_fee " + "(wire_method" + ",start_date" + ",end_date" + ",wire_fee" + ",closing_fee" + ",master_sig" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_wire_fee", + params); +} diff --git a/src/exchangedb/iterate_active_auditors.c b/src/exchangedb/iterate_active_auditors.c @@ -0,0 +1,122 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/iterate_active_auditors.c + * @brief Implementation of the iterate_active_auditors function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "iterate_active_auditors.h" +#include "pg_helper.h" + + +/** + * 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; + +}; + + +/** + * Helper function for #EXCHANGEDB_iterate_active_auditors(). + * 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 (struct EXCHANGEDB_PostgresContext *ctx, + 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); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_active_auditors (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_AuditorsCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + struct AuditorsIteratorContext dic = { + .cb = cb, + .cb_cls = cb_cls, + }; + + PREPARE (ctx, + "select_auditors", + "SELECT" + " auditor_pub" + ",auditor_url" + ",auditor_name" + " FROM auditors" + " WHERE" + " is_active;"); + + return GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "select_auditors", + params, + &auditors_cb_helper, + &dic); +} diff --git a/src/exchangedb/iterate_active_signkeys.c b/src/exchangedb/iterate_active_signkeys.c @@ -0,0 +1,143 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/iterate_active_signkeys.c + * @brief Implementation of the iterate_active_signkeys function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "iterate_active_signkeys.h" +#include "pg_helper.h" + + +/** + * Closure for #signkeys_cb_helper() + */ +struct SignkeysIteratorContext +{ + /** + * Function to call with the results. + */ + TALER_EXCHANGEDB_ActiveSignkeysCallback cb; + + /** + * Closure to pass to @e cb + */ + void *cb_cls; + +}; + + +/** + * Helper function for #EXCHANGEDB_iterate_active_signkeys(). + * Calls the callback with each signkey. + * + * @param cls a `struct SignkeysIteratorContext` + * @param result db results + * @param num_results number of results in @a result + */ +static void +signkeys_cb_helper (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct SignkeysIteratorContext *dic = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_SignkeyMetaData meta; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_MasterSignatureP master_sig; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &master_sig), + GNUNET_PQ_result_spec_auto_from_type ("exchange_pub", + &exchange_pub), + 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), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + return; + } + dic->cb (dic->cb_cls, + &exchange_pub, + &meta, + &master_sig); + } +} + + +/** + * Function called to invoke @a cb on every non-revoked exchange signing key + * that has been signed by the master key. Revoked and (for signing!) + * expired keys are skipped. Runs in its own read-only transaction. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param cb function to call on each signing key + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_active_signkeys (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_ActiveSignkeysCallback cb, + void *cb_cls) +{ + struct GNUNET_TIME_Absolute now = {0}; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_end + }; + struct SignkeysIteratorContext dic = { + .cb = cb, + .cb_cls = cb_cls, + }; + + PREPARE (ctx, + "select_signkeys", + "SELECT" + " master_sig" + ",exchange_pub" + ",valid_from" + ",expire_sign" + ",expire_legal" + " FROM exchange_sign_keys esk" + " WHERE" + " expire_sign > $1" + " AND NOT EXISTS " + " (SELECT esk_serial " + " FROM signkey_revocations skr" + " WHERE esk.esk_serial = skr.esk_serial);"); + now = GNUNET_TIME_absolute_get (); + return GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "select_signkeys", + params, + &signkeys_cb_helper, + &dic); +} diff --git a/src/exchangedb/iterate_auditor_denominations.c b/src/exchangedb/iterate_auditor_denominations.c @@ -0,0 +1,119 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/iterate_auditor_denominations.c + * @brief Implementation of the iterate_auditor_denominations function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "iterate_auditor_denominations.h" +#include "pg_helper.h" + +/** + * 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 #EXCHANGEDB_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 (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AuditorDenomsIteratorContext *dic = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_AuditorPublicKeyP auditor_pub; + struct TALER_DenominationHashP h_denom_pub; + 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); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_auditor_denominations (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_AuditorDenominationsCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + struct AuditorDenomsIteratorContext dic = { + .cb = cb, + .cb_cls = cb_cls, + }; + /* Used in #postgres_iterate_auditor_denominations() */ + PREPARE (ctx, + "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)" + " WHERE auditors.is_active;"); + return GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "select_auditor_denoms", + params, + &auditor_denoms_cb_helper, + &dic); +} diff --git a/src/exchangedb/iterate_denomination_info.c b/src/exchangedb/iterate_denomination_info.c @@ -0,0 +1,184 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/iterate_denomination_info.c + * @brief Implementation of the iterate_denomination_info function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "iterate_denomination_info.h" +#include "pg_helper.h" + + +/** + * Closure for #domination_cb_helper() + */ +struct DenomIteratorContext +{ + /** + * Function to call with the results. + */ + TALER_EXCHANGEDB_DenominationCallback cb; + + /** + * Closure to pass to @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; +}; + + +/** + * Helper function for #EXCHANGEDB_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 (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct DenomIteratorContext *dic = cls; + struct EXCHANGEDB_PostgresContext *ctx = dic->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_DenominationKeyInformation issue; + struct TALER_DenominationPublicKey denom_pub; + struct TALER_DenominationHashP denom_hash; + uint64_t denom_serial; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("denominations_serial", + &denom_serial), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &issue.signature), + GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", + &denom_hash), + 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), + TALER_PQ_result_spec_denom_pub ("denom_pub", + &denom_pub), + GNUNET_PQ_result_spec_uint32 ("age_mask", + &issue.age_mask.bits), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + return; + } + + /* Unfortunately we have to carry the age mask in both, the + * TALER_DenominationPublicKey and + * TALER_EXCHANGEDB_DenominationKeyInformation at different times. + * Here we use _both_ so let's make sure the values are the same. */ + denom_pub.age_mask = issue.age_mask; + TALER_denom_pub_hash (&denom_pub, + &issue.denom_hash); + if (0 != + GNUNET_memcmp (&issue.denom_hash, + &denom_hash)) + { + GNUNET_break (0); + } + else + { + dic->cb (dic->cb_cls, + denom_serial, + &denom_pub, + &issue); + } + TALER_denom_pub_free (&denom_pub); + } +} + + +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_denomination_info (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_DenominationCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + struct DenomIteratorContext dic = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + + PREPARE (ctx, + "denomination_iterate", + "SELECT" + " denominations_serial" + ",master_sig" + ",denom_pub_hash" + ",valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" /* value of this denom */ + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ",denom_pub" + ",age_mask" + " FROM denominations;"); + return GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "denomination_iterate", + params, + &domination_cb_helper, + &dic); +} diff --git a/src/exchangedb/iterate_denominations.c b/src/exchangedb/iterate_denominations.c @@ -0,0 +1,175 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/iterate_denominations.c + * @brief Implementation of the iterate_denominations function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "iterate_denominations.h" +#include "pg_helper.h" + + +/** + * 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 EXCHANGEDB_PostgresContext *ctx; +}; + + +/** + * Helper function for #EXCHANGEDB_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 (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct DenomsIteratorContext *dic = cls; + struct EXCHANGEDB_PostgresContext *ctx = dic->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_DenominationKeyMetaData meta = {0}; + struct TALER_DenominationPublicKey denom_pub = {0}; + struct TALER_MasterSignatureP master_sig = {0}; + struct TALER_DenominationHashP h_denom_pub = {0}; + bool revoked; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("denominations_serial", + &meta.serial), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &master_sig), + GNUNET_PQ_result_spec_bool ("revoked", + &revoked), + 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), + TALER_PQ_RESULT_SPEC_AMOUNT ("coin", + &meta.value), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw", + &meta.fees.withdraw), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + &meta.fees.deposit), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh", + &meta.fees.refresh), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund", + &meta.fees.refund), + TALER_PQ_result_spec_denom_pub ("denom_pub", + &denom_pub), + GNUNET_PQ_result_spec_uint32 ("age_mask", + &meta.age_mask.bits), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + return; + } + + /* make sure the mask information is the same */ + denom_pub.age_mask = meta.age_mask; + + TALER_denom_pub_hash (&denom_pub, + &h_denom_pub); + dic->cb (dic->cb_cls, + &denom_pub, + &h_denom_pub, + &meta, + &master_sig, + revoked); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_denominations (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_DenominationsCallback cb, + void *cb_cls) +{ + struct GNUNET_TIME_Absolute now + = GNUNET_TIME_absolute_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_end + }; + struct DenomsIteratorContext dic = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx + }; + + PREPARE (ctx, + "select_denominations", + "SELECT" + " denominations_serial" + ",denominations.master_sig" + ",denom_revocations_serial_id IS NOT NULL AS revoked" + ",valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" /* value of this denom */ + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ",denom_type" + ",age_mask" + ",denom_pub" + " FROM denominations" + " LEFT JOIN " + " denomination_revocations USING (denominations_serial)" + " WHERE expire_deposit > $1;"); + return GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "select_denominations", + params, + &dominations_cb_helper, + &dic); +} diff --git a/src/exchangedb/iterate_kyc_reference.c b/src/exchangedb/iterate_kyc_reference.c @@ -0,0 +1,128 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_iterate_kyc_reference.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "iterate_kyc_reference.h" +#include "pg_helper.h" + + +/** + * Closure for #iterate_kyc_reference_cb() + */ +struct IteratorContext +{ + /** + * Function to call with the results. + */ + TALER_EXCHANGEDB_LegitimizationProcessCallback cb; + + /** + * Closure to pass to @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; +}; + + +/** + * Helper function for #EXCHANGEDB_iterate_kyc_reference(). + * Calls the callback with each denomination key. + * + * @param cls a `struct IteratorContext` + * @param result db results + * @param num_results number of results in @a result + */ +static void +iterate_kyc_reference_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct IteratorContext *ic = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + char *kyc_provider_name_name; + char *provider_user_id; + char *legitimization_id; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("provider_name", + &kyc_provider_name_name), + GNUNET_PQ_result_spec_string ("provider_user_id", + &provider_user_id), + GNUNET_PQ_result_spec_string ("provider_legitimization_id", + &legitimization_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + return; + } + ic->cb (ic->cb_cls, + kyc_provider_name_name, + provider_user_id, + legitimization_id); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_kyc_reference (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_LegitimizationProcessCallback lpc, + void *lpc_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + struct IteratorContext ic = { + .cb = lpc, + .cb_cls = lpc_cls, + .ctx = ctx + }; + + PREPARE (ctx, + "iterate_kyc_reference", + "SELECT " + " provider_name" + ",provider_user_id" + ",provider_legitimization_id" + " FROM legitimization_processes" + " WHERE h_payto=$1;"); + return GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "iterate_kyc_reference", + params, + &iterate_kyc_reference_cb, + &ic); +} diff --git a/src/exchangedb/iterate_reserve_close_info.c b/src/exchangedb/iterate_reserve_close_info.c @@ -0,0 +1,129 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_iterate_reserve_close_info.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "iterate_reserve_close_info.h" +#include "pg_helper.h" + +/** + * Closure for #iterate_reserve_close_info_cb() + */ +struct IteratorContext +{ + /** + * Function to call with the results. + */ + TALER_EXCHANGEDB_KycAmountCallback cb; + + /** + * Closure to pass to @e cb + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; +}; + + +/** + * Helper function for #EXCHANGEDB_iterate_reserve_close_info(). + * Calls the callback with each denomination key. + * + * @param cls a `struct IteratorContext` + * @param result db results + * @param num_results number of results in @a result + */ +static void +iterate_reserve_close_info_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct IteratorContext *ic = cls; + struct EXCHANGEDB_PostgresContext *ctx = ic->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_Amount amount; + struct GNUNET_TIME_Absolute ts; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_absolute_time ("execution_date", + &ts), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + return; + } + ic->cb (ic->cb_cls, + &amount, + ts); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_reserve_close_info (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_absolute_time (&time_limit), + GNUNET_PQ_query_param_end + }; + struct IteratorContext ic = { + .cb = kac, + .cb_cls = kac_cls, + .ctx = ctx + }; + + PREPARE (ctx, + "iterate_reserve_close_info", + "SELECT amount" + " ,execution_date" + " FROM reserves_close" + " WHERE wire_target_h_payto IN (" + " SELECT wire_target_h_payto" + " FROM wire_targets" + " WHERE h_normalized_payto=$1" + " )" + " AND execution_date >= $2" + " ORDER BY execution_date DESC"); + return GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "iterate_reserve_close_info", + params, + &iterate_reserve_close_info_cb, + &ic); +} diff --git a/src/exchangedb/kyc_provider_account_lookup.c b/src/exchangedb/kyc_provider_account_lookup.c @@ -0,0 +1,68 @@ +/* + This file is part of TALER + Copyright (C) 2022-2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/kyc_provider_account_lookup.c + * @brief Implementation of the kyc_provider_account_lookup function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "kyc_provider_account_lookup.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_kyc_provider_account_lookup (struct EXCHANGEDB_PostgresContext *ctx, + const char *provider_name, + const char *provider_legitimization_id, + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, + uint64_t *process_row) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (provider_legitimization_id), + GNUNET_PQ_query_param_string (provider_name), + 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_bool ("is_wallet", + is_wallet), + GNUNET_PQ_result_spec_uint64 ("legitimization_process_serial_id", + process_row), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "get_wire_target_by_legitimization_id", + "SELECT " + " lp.h_payto" + ",kt.is_wallet" + ",lp.legitimization_process_serial_id" + " FROM legitimization_processes lp" + " JOIN kyc_targets kt" + " ON (lp.h_payto = kt.h_normalized_payto)" + " WHERE provider_legitimization_id=$1" + " AND provider_name=$2;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "get_wire_target_by_legitimization_id", + params, + rs); +} diff --git a/src/exchangedb/kycauth_in_insert.c b/src/exchangedb/kycauth_in_insert.c @@ -0,0 +1,80 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/kycauth_in_insert.c + * @brief Implementation of the kycauth_in_insert function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "kycauth_in_insert.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_kycauth_in_insert (struct EXCHANGEDB_PostgresContext *ctx, + const union TALER_AccountPublicKeyP *account_pub, + const struct TALER_Amount *credit_amount, + struct GNUNET_TIME_Timestamp execution_date, + const struct TALER_FullPayto debit_account_uri, + const char *section_name, + uint64_t serial_id) +{ + struct TALER_NormalizedPaytoHashP h_normalized_payto; + struct TALER_FullPaytoHashP h_full_payto; + + TALER_full_payto_hash (debit_account_uri, + &h_full_payto); + TALER_full_payto_normalize_and_hash (debit_account_uri, + &h_normalized_payto); + { + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = h_normalized_payto + }; + char *notify_s + = GNUNET_PQ_get_event_notify_channel (&rep.header); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (account_pub), + GNUNET_PQ_query_param_uint64 (&serial_id), + TALER_PQ_query_param_amount (ctx->conn, + credit_amount), + GNUNET_PQ_query_param_auto_from_type (&h_full_payto), + GNUNET_PQ_query_param_auto_from_type (&h_normalized_payto), + GNUNET_PQ_query_param_string (debit_account_uri.full_payto), + GNUNET_PQ_query_param_string (section_name), + GNUNET_PQ_query_param_timestamp (&execution_date), + GNUNET_PQ_query_param_string (notify_s), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "kycauth_in_insert", + "CALL" + " exchange_do_kycauth_in_insert" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9);"); + qs = GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "kycauth_in_insert", + params); + GNUNET_free (notify_s); + return qs; + } +} diff --git a/src/exchangedb/lookup_active_legitimization.c b/src/exchangedb/lookup_active_legitimization.c @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_lookup_pending_legitimization.c + * @brief Implementation of the lookup_pending_legitimization function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_active_legitimization.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_active_legitimization (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t legitimization_process_serial_id, + uint32_t *measure_index, + json_t **jmeasures) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&legitimization_process_serial_id), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_json ( + "jmeasures", + jmeasures), + GNUNET_PQ_result_spec_uint32 ( + "measure_index", + measure_index), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_active_legitimization", + "SELECT " + " lm.jmeasures::TEXT" + ",lp.measure_index" + " FROM legitimization_processes lp" + " JOIN legitimization_measures lm" + " USING (legitimization_measure_serial_id)" + " WHERE lp.legitimization_process_serial_id=$1" + " AND NOT lm.is_finished;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_active_legitimization", + params, + rs); +} diff --git a/src/exchangedb/lookup_aml_file_number.c b/src/exchangedb/lookup_aml_file_number.c @@ -0,0 +1,61 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_aml_file_number.c + * @brief Implementation of the lookup_aml_file_number function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_aml_file_number.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_aml_file_number (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint64_t *kyc_target_row, + bool *is_wallet) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "kyc_target_serial_id", + kyc_target_row), + GNUNET_PQ_result_spec_bool ( + "is_wallet", + is_wallet), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_aml_file_number", + "SELECT " + " kyc_target_serial_id" + ",is_wallet" + " FROM kyc_targets" + " WHERE h_normalized_payto=$1"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_aml_file_number", + params, + rs); +} diff --git a/src/exchangedb/lookup_aml_history.c b/src/exchangedb/lookup_aml_history.c @@ -0,0 +1,202 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_aml_history.c + * @brief Implementation of the lookup_aml_history function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_aml_history.h" +#include "pg_helper.h" + + +/** + * Closure for callbacks called from #EXCHANGEDB_lookup_aml_history() + */ +struct AmlHistoryContext +{ + + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlHistoryCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to 'true' if the transaction failed. + */ + bool failed; + +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct AmlHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_aml_entry (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AmlHistoryContext *ahc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t outcome_serial_id; + struct GNUNET_TIME_Timestamp decision_time; + char *justification; + struct TALER_AmlOfficerPublicKeyP decider_pub; + json_t *jproperties; + json_t *jnew_rules = NULL; + bool to_investigate; + bool is_active; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("outcome_serial_id", + &outcome_serial_id), + GNUNET_PQ_result_spec_timestamp ("decision_time", + &decision_time), + GNUNET_PQ_result_spec_string ("justification", + &justification), + GNUNET_PQ_result_spec_auto_from_type ("decider_pub", + &decider_pub), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("jproperties", + &jproperties), + NULL), + TALER_PQ_result_spec_json ("jnew_rules", + &jnew_rules), + GNUNET_PQ_result_spec_bool ("to_investigate", + &to_investigate), + GNUNET_PQ_result_spec_bool ("is_active", + &is_active), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ahc->failed = true; + return; + } + ahc->cb (ahc->cb_cls, + outcome_serial_id, + decision_time, + justification, + &decider_pub, + jproperties, + jnew_rules, + to_investigate, + is_active); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_aml_history (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlHistoryCallback cb, + void *cb_cls) +{ + struct AmlHistoryContext ahc = { + .ctx = ctx, + .cb = cb, + .cb_cls = cb_cls + }; + uint64_t ulimit = (limit < 0) ? (-limit) : limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "lookup_aml_history_desc", + "SELECT" + " lo.decision_time" + ",lo.outcome_serial_id" + ",ah.justification" + ",ah.decider_pub" + ",lo.jproperties::TEXT" + ",lo.jnew_rules::TEXT" + ",lo.to_investigate" + ",lo.is_active" + " FROM aml_history ah" + " JOIN legitimization_outcomes lo" + " USING (outcome_serial_id)" + " WHERE ah.h_payto=$1" + " AND lo.outcome_serial_id < $2" + " ORDER BY outcome_serial_id DESC" + " LIMIT $3;"); + PREPARE (ctx, + "lookup_aml_history_asc", + "SELECT" + " lo.decision_time" + ",lo.outcome_serial_id" + ",ah.justification" + ",ah.decider_pub" + ",lo.jproperties::TEXT" + ",lo.jnew_rules::TEXT" + ",lo.to_investigate" + ",lo.is_active" + " FROM aml_history ah" + " JOIN legitimization_outcomes lo" + " USING (outcome_serial_id)" + " WHERE ah.h_payto=$1" + " AND lo.outcome_serial_id > $2" + " ORDER BY outcome_serial_id ASC" + " LIMIT $3;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit < 0) + ? "lookup_aml_history_desc" + : "lookup_aml_history_asc", + params, + &handle_aml_entry, + &ahc); + if (qs <= 0) + return qs; + if (ahc.failed) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} diff --git a/src/exchangedb/lookup_aml_officer.c b/src/exchangedb/lookup_aml_officer.c @@ -0,0 +1,70 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_aml_officer.c + * @brief Implementation of the lookup_aml_officer function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_aml_officer.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_aml_officer (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + struct TALER_MasterSignatureP *master_sig, + char **decider_name, + bool *is_active, + bool *read_only, + struct GNUNET_TIME_Absolute *last_change) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (decider_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + master_sig), + GNUNET_PQ_result_spec_string ("decider_name", + decider_name), + GNUNET_PQ_result_spec_bool ("is_active", + is_active), + GNUNET_PQ_result_spec_bool ("read_only", + read_only), + GNUNET_PQ_result_spec_absolute_time ("last_change", + last_change), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_aml_officer", + "SELECT " + " master_sig" + ",decider_name" + ",is_active" + ",read_only" + ",last_change" + " FROM aml_staff" + " WHERE decider_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_aml_officer", + params, + rs); +} diff --git a/src/exchangedb/lookup_auditor_status.c b/src/exchangedb/lookup_auditor_status.c @@ -0,0 +1,59 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_auditor_status.c + * @brief Implementation of the lookup_auditor_status function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_auditor_status.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_auditor_status (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AuditorPublicKeyP *auditor_pub, + char **auditor_url, + bool *enabled) +{ + 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), + GNUNET_PQ_result_spec_bool ("is_active", + enabled), + GNUNET_PQ_result_spec_end + }; + + /* Used in #postgres_lookup_auditor_status() */ + PREPARE (ctx, + "lookup_auditor_status", + "SELECT" + " auditor_url" + ",is_active" + " FROM auditors" + " WHERE auditor_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "lookup_auditor_status", + params, + rs); +} diff --git a/src/exchangedb/lookup_auditor_timestamp.c b/src/exchangedb/lookup_auditor_timestamp.c @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_auditor_timestamp.c + * @brief Implementation of the lookup_auditor_timestamp function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_auditor_timestamp.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_auditor_timestamp (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AuditorPublicKeyP *auditor_pub, + struct GNUNET_TIME_Timestamp *last_date) +{ + 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_timestamp ("last_change", + last_date), + GNUNET_PQ_result_spec_end + }; + + /* Used in #postgres_lookup_auditor_timestamp() */ + PREPARE (ctx, + "lookup_auditor_timestamp", + "SELECT" + " last_change" + " FROM auditors" + " WHERE auditor_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "lookup_auditor_timestamp", + params, + rs); +} diff --git a/src/exchangedb/lookup_completed_legitimization.c b/src/exchangedb/lookup_completed_legitimization.c @@ -0,0 +1,97 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_completed_legitimization.c + * @brief Implementation of the lookup_pending_legitimization function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_completed_legitimization.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_completed_legitimization (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t legitimization_measure_serial_id, + uint32_t measure_index, + struct TALER_AccountAccessTokenP *access_token, + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, + json_t **jmeasures, + bool *is_finished, + size_t *encrypted_attributes_len, + void **encrypted_attributes + ) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&legitimization_measure_serial_id), + GNUNET_PQ_query_param_uint32 (&measure_index), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_json ( + "jmeasures", + jmeasures), + GNUNET_PQ_result_spec_auto_from_type ( + "h_normalized_payto", + h_payto), + GNUNET_PQ_result_spec_auto_from_type ( + "access_token", + access_token), + GNUNET_PQ_result_spec_bool ( + "is_finished", + is_finished), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_variable_size ( + "encrypted_attributes", + encrypted_attributes, + encrypted_attributes_len), + NULL), + GNUNET_PQ_result_spec_bool ( + "is_wallet", + is_wallet), + GNUNET_PQ_result_spec_end + }; + + *encrypted_attributes_len = 0; + *encrypted_attributes = NULL; + PREPARE (ctx, + "lookup_completed_legitimization", + "SELECT " + " lm.jmeasures::TEXT" + ",kt.h_normalized_payto" + ",kt.is_wallet" + ",lm.access_token" + ",lm.is_finished" + ",ka.encrypted_attributes" + " FROM legitimization_measures lm" + " JOIN kyc_targets kt" + " ON (lm.access_token = kt.access_token)" + " LEFT JOIN legitimization_processes lp" + " ON (lm.legitimization_measure_serial_id = lp.legitimization_measure_serial_id)" + " LEFT JOIN kyc_attributes ka" + " ON (ka.legitimization_serial = lp.legitimization_process_serial_id)" + " WHERE lm.legitimization_measure_serial_id=$1" + " AND lp.measure_index=$2;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_completed_legitimization", + params, + rs); +} diff --git a/src/exchangedb/lookup_denomination_key.c b/src/exchangedb/lookup_denomination_key.c @@ -0,0 +1,80 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_denomination_key.c + * @brief Implementation of the lookup_denomination_key function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_denomination_key.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_denomination_key (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *h_denom_pub, + struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta) +{ + 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[] = { + 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), + TALER_PQ_RESULT_SPEC_AMOUNT ("coin", + &meta->value), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw", + &meta->fees.withdraw), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + &meta->fees.deposit), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh", + &meta->fees.refresh), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund", + &meta->fees.refund), + GNUNET_PQ_result_spec_uint32 ("age_mask", + &meta->age_mask.bits), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_denomination_key", + "SELECT" + " valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ",age_mask" + " FROM denominations" + " WHERE denom_pub_hash=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "lookup_denomination_key", + params, + rs); +} diff --git a/src/exchangedb/lookup_global_fee_by_time.c b/src/exchangedb/lookup_global_fee_by_time.c @@ -0,0 +1,180 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_global_fee_by_time.c + * @brief Implementation of the lookup_global_fee_by_time function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_global_fee_by_time.h" +#include "pg_helper.h" + +/** + * Closure for #global_fee_by_time_helper() + */ +struct GlobalFeeLookupContext +{ + + /** + * Set to the wire fees. Set to invalid if fees conflict over + * the given time period. + */ + struct TALER_GlobalFeeSet *fees; + + /** + * Set to timeout of unmerged purses + */ + struct GNUNET_TIME_Relative *purse_timeout; + + /** + * Set to history expiration for reserves. + */ + struct GNUNET_TIME_Relative *history_expiration; + + /** + * Set to number of free purses per account. + */ + uint32_t *purse_account_limit; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; +}; + + +/** + * Helper function for #EXCHANGEDB_lookup_global_fee_by_time(). + * Calls the callback with each denomination key. + * + * @param cls a `struct GlobalFeeLookupContext` + * @param result db results + * @param num_results number of results in @a result + */ +static void +global_fee_by_time_helper (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct GlobalFeeLookupContext *wlc = cls; + struct EXCHANGEDB_PostgresContext *ctx = wlc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_GlobalFeeSet fs; + struct GNUNET_TIME_Relative purse_timeout; + struct GNUNET_TIME_Relative history_expiration; + uint32_t purse_account_limit; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee", + &fs.history), + TALER_PQ_RESULT_SPEC_AMOUNT ("account_fee", + &fs.account), + TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee", + &fs.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_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + /* invalidate */ + memset (wlc->fees, + 0, + sizeof (struct TALER_GlobalFeeSet)); + return; + } + if (0 == i) + { + *wlc->fees = fs; + *wlc->purse_timeout = purse_timeout; + *wlc->history_expiration = history_expiration; + *wlc->purse_account_limit = purse_account_limit; + continue; + } + if ( (0 != + TALER_global_fee_set_cmp (&fs, + wlc->fees)) || + (purse_account_limit != *wlc->purse_account_limit) || + (GNUNET_TIME_relative_cmp (purse_timeout, + !=, + *wlc->purse_timeout)) || + (GNUNET_TIME_relative_cmp (history_expiration, + !=, + *wlc->history_expiration)) ) + { + /* invalidate */ + memset (wlc->fees, + 0, + sizeof (struct TALER_GlobalFeeSet)); + return; + } + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_global_fee_by_time (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp start_time, + struct GNUNET_TIME_Timestamp end_time, + struct TALER_GlobalFeeSet *fees, + struct GNUNET_TIME_Relative *purse_timeout, + struct GNUNET_TIME_Relative *history_expiration, + uint32_t *purse_account_limit) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&start_time), + GNUNET_PQ_query_param_timestamp (&end_time), + GNUNET_PQ_query_param_end + }; + struct GlobalFeeLookupContext wlc = { + .fees = fees, + .purse_timeout = purse_timeout, + .history_expiration = history_expiration, + .purse_account_limit = purse_account_limit, + .ctx = ctx + }; + + PREPARE (ctx, + "lookup_global_fee_by_time", + "SELECT" + " history_fee" + ",account_fee" + ",purse_fee" + ",purse_timeout" + ",history_expiration" + ",purse_account_limit" + " FROM global_fee" + " WHERE end_date > $1" + " AND start_date < $2;"); + return GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "lookup_global_fee_by_time", + params, + &global_fee_by_time_helper, + &wlc); +} diff --git a/src/exchangedb/lookup_h_payto_by_access_token.c b/src/exchangedb/lookup_h_payto_by_access_token.c @@ -0,0 +1,61 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_h_payto_by_access_token.c + * @brief Implementation of the lookup_h_payto_by_access_token function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_h_payto_by_access_token.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_h_payto_by_access_token (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AccountAccessTokenP *access_token, + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (access_token), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ( + "h_normalized_payto", + h_payto), + GNUNET_PQ_result_spec_bool ( + "is_wallet", + is_wallet), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_h_payto_by_access_token", + "SELECT " + " h_normalized_payto" + " ,is_wallet" + " FROM kyc_targets" + " WHERE (access_token = $1);"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_h_payto_by_access_token", + params, + rs); +} diff --git a/src/exchangedb/lookup_kyc_history.c b/src/exchangedb/lookup_kyc_history.c @@ -0,0 +1,193 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_kyc_history.c + * @brief Implementation of the lookup_kyc_history function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_kyc_history.h" +#include "pg_helper.h" + +/** + * Closure for callbacks called from #EXCHANGEDB_lookup_kyc_history() + */ +struct KycHistoryContext +{ + + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_KycHistoryCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to 'true' if the transaction failed. + */ + bool failed; + +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct KycHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_kyc_entry (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct KycHistoryContext *khc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + char *provider_name = NULL; + bool finished; + uint32_t error_code; + char *error_message = NULL; + char *provider_user_id = NULL; + char *provider_legitimization_id = NULL; + struct GNUNET_TIME_Timestamp collection_time; + struct GNUNET_TIME_Absolute expiration_time + = GNUNET_TIME_UNIT_ZERO_ABS; + void *encrypted_attributes; + size_t encrypted_attributes_len; + + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("provider_name", + &provider_name), + NULL), + GNUNET_PQ_result_spec_bool ("finished", + &finished), + GNUNET_PQ_result_spec_uint32 ("error_code", + &error_code), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("error_message", + &error_message), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("provider_user_id", + &provider_user_id), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("provider_legitimization_id", + &provider_legitimization_id), + NULL), + GNUNET_PQ_result_spec_timestamp ("collection_time", + &collection_time), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_absolute_time ("expiration_time", + &expiration_time), + NULL), + GNUNET_PQ_result_spec_variable_size ("encrypted_attributes", + &encrypted_attributes, + &encrypted_attributes_len), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + khc->failed = true; + return; + } + khc->cb (khc->cb_cls, + provider_name, + finished, + (enum TALER_ErrorCode) error_code, + error_message, + provider_user_id, + provider_legitimization_id, + collection_time, + expiration_time, + encrypted_attributes_len, + encrypted_attributes); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_kyc_history (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_KycHistoryCallback cb, + void *cb_cls) +{ + struct KycHistoryContext khc = { + .ctx = ctx, + .cb = cb, + .cb_cls = cb_cls + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "lookup_kyc_history", + "SELECT" + " lp.provider_name" + ",lp.finished" + ",lp.error_code" + ",lp.error_message" + ",lp.provider_user_id" + ",lp.provider_legitimization_id" + ",ka.collection_time" + ",ka.expiration_time" + ",ka.encrypted_attributes" + " FROM kyc_attributes ka" + " JOIN legitimization_processes lp" + " ON (ka.legitimization_serial = lp.legitimization_process_serial_id)" + " WHERE ka.h_payto=$1" + " ORDER BY ka.collection_time DESC;"); + + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "lookup_kyc_history", + params, + &handle_kyc_entry, + &khc); + if (qs <= 0) + return qs; + if (khc.failed) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} diff --git a/src/exchangedb/lookup_kyc_process_by_account.c b/src/exchangedb/lookup_kyc_process_by_account.c @@ -0,0 +1,92 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_kyc_process_by_account.c + * @brief Implementation of the lookup_kyc_process_by_account function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_kyc_process_by_account.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_kyc_process_by_account (struct EXCHANGEDB_PostgresContext *ctx, + const char *provider_name, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint64_t *process_row, + struct GNUNET_TIME_Absolute *expiration, + char **provider_account_id, + char **provider_legitimization_id, + bool *is_wallet) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_string (provider_name), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "legitimization_process_serial_id", + process_row), + GNUNET_PQ_result_spec_absolute_time ( + "expiration_time", + expiration), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ( + "provider_user_id", + provider_account_id), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ( + "provider_legitimization_id", + provider_legitimization_id), + NULL), + GNUNET_PQ_result_spec_bool ( + "is_wallet", + is_wallet), + GNUNET_PQ_result_spec_end + }; + + *provider_account_id = NULL; + *provider_legitimization_id = NULL; + PREPARE (ctx, + "lookup_kyc_process_by_account", + "SELECT " + " lp.legitimization_process_serial_id" + ",lp.expiration_time" + ",lp.provider_user_id" + ",lp.provider_legitimization_id" + ",kt.is_wallet" + " FROM legitimization_processes lp" + " JOIN kyc_targets kt" + " ON (lp.h_payto = kt.h_normalized_payto)" + " WHERE h_payto=$1" + " AND provider_name=$2" + " AND NOT finished" + /* Note: there *should* only be one unfinished + match, so this is just to be safe(r): */ + " ORDER BY lp.expiration_time DESC" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_kyc_process_by_account", + params, + rs); +} diff --git a/src/exchangedb/lookup_kyc_requirement_by_row.c b/src/exchangedb/lookup_kyc_requirement_by_row.c @@ -0,0 +1,111 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_kyc_requirement_by_row.c + * @brief Implementation of the lookup_kyc_requirement_by_row function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_kyc_requirement_by_row.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_kyc_requirement_by_row (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + const union TALER_AccountPublicKeyP *account_pub, + enum GNUNET_GenericReturnValue *is_wallet, + struct TALER_AccountAccessTokenP *access_token, + uint64_t *rule_gen, + json_t **jrules, + bool *aml_review, + bool *kyc_required) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_auto_from_type (account_pub), + GNUNET_PQ_query_param_end + }; + bool bis_wallet; + bool bis_wallet_unknown; + bool not_found; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("access_token", + access_token), + NULL), + GNUNET_PQ_result_spec_allow_null ( + /* can be NULL due to LEFT JOIN */ + TALER_PQ_result_spec_json ("jrules", + jrules), + NULL), + GNUNET_PQ_result_spec_allow_null ( + /* can be NULL due to LEFT JOIN */ + GNUNET_PQ_result_spec_bool ("is_wallet", + &bis_wallet), + &bis_wallet_unknown), + GNUNET_PQ_result_spec_allow_null ( + /* can be NULL due to LEFT JOIN */ + GNUNET_PQ_result_spec_bool ("aml_review", + aml_review), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ("rule_gen", + rule_gen), + NULL), + GNUNET_PQ_result_spec_bool ("kyc_required", + kyc_required), + GNUNET_PQ_result_spec_bool ("not_found", + &not_found), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + *jrules = NULL; + *aml_review = false; + *is_wallet = GNUNET_SYSERR; + *rule_gen = 0; + memset (access_token, + 0, + sizeof (*access_token)); + PREPARE (ctx, + "lookup_kyc_requirement_by_row", + "SELECT " + " out_access_token AS access_token" + ",out_jrules::TEXT AS jrules" + ",out_is_wallet AS is_wallet" + ",out_not_found AS not_found" + ",out_aml_review AS aml_review" + ",out_kyc_required AS kyc_required" + ",out_rule_gen AS rule_gen" + " FROM exchange_do_lookup_kyc_requirement_by_row" + " ($1, $2);"); + qs = GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_kyc_requirement_by_row", + params, + rs); + if (qs <= 0) + return qs; + if (! bis_wallet_unknown) + *is_wallet = (bis_wallet) ? GNUNET_YES : GNUNET_NO; + if (not_found) + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + return qs; +} diff --git a/src/exchangedb/lookup_kyc_status_by_token.c b/src/exchangedb/lookup_kyc_status_by_token.c @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_kyc_status_by_token.c + * @brief Implementation of the lookup_kyc_status_by_token function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_kyc_status_by_token.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_kyc_status_by_token (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AccountAccessTokenP *access_token, + uint64_t *row, + json_t **jmeasures) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (access_token), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "legitimization_measure_serial_id", + row), + TALER_PQ_result_spec_json ( + "jmeasures", + jmeasures), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_kyc_status_by_token", + "SELECT" + " legitimization_measure_serial_id" + ",jmeasures::TEXT" + " FROM legitimization_measures" + " WHERE access_token=$1" + " AND NOT is_finished" + " ORDER BY display_priority DESC" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "lookup_kyc_status_by_token", + params, + rs); +} diff --git a/src/exchangedb/lookup_pending_legitimization.c b/src/exchangedb/lookup_pending_legitimization.c @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2024, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_pending_legitimization.c + * @brief Implementation of the lookup_pending_legitimization function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_pending_legitimization.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_pending_legitimization (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t legitimization_measure_serial_id, + struct TALER_AccountAccessTokenP *access_token, + struct TALER_NormalizedPaytoHashP *h_payto, + json_t **jmeasures, + bool *is_finished, + bool *is_wallet) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&legitimization_measure_serial_id), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_json ( + "jmeasures", + jmeasures), + GNUNET_PQ_result_spec_auto_from_type ( + "h_normalized_payto", + h_payto), + GNUNET_PQ_result_spec_auto_from_type ( + "access_token", + access_token), + GNUNET_PQ_result_spec_bool ( + "is_finished", + is_finished), + GNUNET_PQ_result_spec_bool ( + "is_wallet", + is_wallet), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_pending_legitimization", + "SELECT " + " lm.jmeasures::TEXT" + ",kt.h_normalized_payto" + ",kt.is_wallet" + ",lm.access_token" + ",lm.is_finished" + " FROM legitimization_measures lm" + " JOIN kyc_targets kt" + " USING (access_token)" + " WHERE lm.legitimization_measure_serial_id=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_pending_legitimization", + params, + rs); +} diff --git a/src/exchangedb/lookup_records_by_table.c b/src/exchangedb/lookup_records_by_table.c @@ -0,0 +1,3802 @@ +/* + This file is part of GNUnet + Copyright (C) 2020-2025 Taler Systems SA + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @file src/exchangedb/lookup_records_by_table.c + * @brief implementation of lookup_records_by_table + * @author Christian Grothoff + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_records_by_table.h" +#include "pg_helper.h" +#include <gnunet/gnunet_pq_lib.h> + + +/** + * Closure for callbacks used by #postgres_lookup_records_by_table. + */ +struct LookupRecordsByTableContext +{ + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Function to call with the results. + */ + TALER_EXCHANGEDB_ReplicationCallback cb; + + /** + * Closure for @a cb. + */ + void *cb_cls; + + /** + * Set to true on errors. + */ + bool error; +}; + + +/** + * Function called with denominations table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_denominations (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_DENOMINATIONS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_uint32 ( + "denom_type", + &td.details.denominations.denom_type), + GNUNET_PQ_result_spec_uint32 ( + "age_mask", + &td.details.denominations.age_mask), + TALER_PQ_result_spec_denom_pub ( + "denom_pub", + &td.details.denominations.denom_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "master_sig", + &td.details.denominations.master_sig), + GNUNET_PQ_result_spec_timestamp ( + "valid_from", + &td.details.denominations.valid_from), + GNUNET_PQ_result_spec_timestamp ( + "expire_withdraw", + &td.details.denominations. + expire_withdraw), + GNUNET_PQ_result_spec_timestamp ( + "expire_deposit", + &td.details.denominations. + expire_deposit), + GNUNET_PQ_result_spec_timestamp ( + "expire_legal", + &td.details.denominations.expire_legal), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "coin", + &td.details.denominations.coin), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "fee_withdraw", + &td.details.denominations.fees.withdraw), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "fee_deposit", + &td.details.denominations.fees.deposit), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "fee_refresh", + &td.details.denominations.fees.refresh), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "fee_refund", + &td.details.denominations.fees.refund), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with denomination_revocations table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_denomination_revocations (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_uint64 ( + "denominations_serial", + &td.details.denomination_revocations.denominations_serial), + GNUNET_PQ_result_spec_auto_from_type ( + "master_sig", + &td.details.denomination_revocations.master_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wire_targets table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_wire_targets (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_WIRE_TARGETS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_string ( + "payto_uri", + &td.details.wire_targets.full_payto_uri.full_payto), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wire_targets table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_kyc_targets (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_KYC_TARGETS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "h_normalized_payto", + &td.details.kyc_targets.h_normalized_payto), + GNUNET_PQ_result_spec_auto_from_type ( + "access_token", + &td.details.kyc_targets.access_token), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ( + "target_pub", + &td.details.kyc_targets.target_pub), + &td.details.kyc_targets.no_account), + GNUNET_PQ_result_spec_bool ( + "is_wallet", + &td.details.kyc_targets.is_wallet), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with reserves table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_reserves (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_RESERVES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &td.details.reserves.reserve_pub), + GNUNET_PQ_result_spec_timestamp ("expiration_date", + &td.details.reserves.expiration_date), + GNUNET_PQ_result_spec_timestamp ("gc_date", + &td.details.reserves.gc_date), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with reserves_in table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_reserves_in (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_RESERVES_IN + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.reserves_in.reserve_pub), + GNUNET_PQ_result_spec_uint64 ( + "wire_reference", + &td.details.reserves_in.wire_reference), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "credit", + &td.details.reserves_in.credit), + GNUNET_PQ_result_spec_auto_from_type ( + "wire_source_h_payto", + &td.details.reserves_in.sender_account_h_payto), + GNUNET_PQ_result_spec_string ( + "exchange_account_section", + &td.details.reserves_in.exchange_account_section), + GNUNET_PQ_result_spec_timestamp ( + "execution_date", + &td.details.reserves_in.execution_date), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with kycauth_in table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_kycauth_in (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_KYCAUTHS_IN + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "account_pub", + &td.details.kycauth_in.account_pub), + GNUNET_PQ_result_spec_uint64 ( + "wire_reference", + &td.details.kycauth_in.wire_reference), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "credit", + &td.details.kycauth_in.credit), + GNUNET_PQ_result_spec_auto_from_type ( + "wire_source_h_payto", + &td.details.kycauth_in.sender_account_h_payto), + GNUNET_PQ_result_spec_string ( + "exchange_account_section", + &td.details.kycauth_in.exchange_account_section), + GNUNET_PQ_result_spec_timestamp ( + "execution_date", + &td.details.kycauth_in.execution_date), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with reserves_close table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_reserves_close (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_RESERVES_CLOSE + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.reserves_close.reserve_pub), + GNUNET_PQ_result_spec_timestamp ( + "execution_date", + &td.details.reserves_close.execution_date), + GNUNET_PQ_result_spec_auto_from_type ( + "wtid", + &td.details.reserves_close.wtid), + GNUNET_PQ_result_spec_auto_from_type ( + "wire_target_h_payto", + &td.details.reserves_close.sender_account_h_payto), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount", + &td.details.reserves_close.amount), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "closing_fee", + &td.details.reserves_close.closing_fee), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with reserves_open_requests table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_reserves_open_requests (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.reserves_open_requests.reserve_pub), + GNUNET_PQ_result_spec_timestamp ( + "request_timestamp", + &td.details.reserves_open_requests.request_timestamp), + GNUNET_PQ_result_spec_timestamp ( + "expiration_date", + &td.details.reserves_open_requests.expiration_date), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_sig", + &td.details.reserves_open_requests.reserve_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "reserve_payment", + &td.details.reserves_open_requests.reserve_payment), + GNUNET_PQ_result_spec_uint32 ( + "requested_purse_limit", + &td.details.reserves_open_requests.requested_purse_limit), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with reserves_open_deposits table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_reserves_open_deposits (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_sig", + &td.details.reserves_open_deposits.reserve_sig), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.reserves_open_deposits.reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_pub", + &td.details.reserves_open_deposits.coin_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_sig", + &td.details.reserves_open_deposits.coin_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "contribution", + &td.details.reserves_open_deposits.contribution), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with auditors table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_auditors (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_AUDITORS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ("auditor_pub", + &td.details.auditors.auditor_pub), + GNUNET_PQ_result_spec_string ("auditor_url", + &td.details.auditors.auditor_url), + GNUNET_PQ_result_spec_string ("auditor_name", + &td.details.auditors.auditor_name), + GNUNET_PQ_result_spec_bool ("is_active", + &td.details.auditors.is_active), + GNUNET_PQ_result_spec_timestamp ("last_change", + &td.details.auditors.last_change), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with auditor_denom_sigs table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_auditor_denom_sigs (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_uint64 ( + "auditor_uuid", + &td.details.auditor_denom_sigs.auditor_uuid), + GNUNET_PQ_result_spec_uint64 ( + "denominations_serial", + &td.details.auditor_denom_sigs.denominations_serial), + GNUNET_PQ_result_spec_auto_from_type ( + "auditor_sig", + &td.details.auditor_denom_sigs.auditor_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with exchange_sign_keys table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_exchange_sign_keys (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ("exchange_pub", + &td.details.exchange_sign_keys. + exchange_pub), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &td.details.exchange_sign_keys. + master_sig), + GNUNET_PQ_result_spec_timestamp ("valid_from", + &td.details.exchange_sign_keys.meta. + start), + GNUNET_PQ_result_spec_timestamp ("expire_sign", + &td.details.exchange_sign_keys.meta. + expire_sign), + GNUNET_PQ_result_spec_timestamp ("expire_legal", + &td.details.exchange_sign_keys.meta. + expire_legal), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with signkey_revocations table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_signkey_revocations (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_uint64 ("esk_serial", + &td.details.signkey_revocations.esk_serial), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &td.details.signkey_revocations. + master_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with known_coins table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_known_coins (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_KNOWN_COINS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_pub", + &td.details.known_coins.coin_pub), + TALER_PQ_result_spec_denom_sig ( + "denom_sig", + &td.details.known_coins.denom_sig), + GNUNET_PQ_result_spec_uint64 ( + "denominations_serial", + &td.details.known_coins.denominations_serial), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with refresh table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_refresh (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_REFRESH + }; + + for (unsigned int i = 0; i<num_results; i++) + { + bool no_cs_r_values; + bool no_cs_r_choices; + size_t num_denom_sigs; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "rc", + &td.details.refresh.rc), + GNUNET_PQ_result_spec_auto_from_type ( + "execution_date", + &td.details.refresh.execution_date), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount_with_fee", + &td.details.refresh.amount_with_fee), + GNUNET_PQ_result_spec_auto_from_type ( + "old_coin_pub", + &td.details.refresh.old_coin_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "old_coin_sig", + &td.details.refresh.old_coin_sig), + GNUNET_PQ_result_spec_auto_from_type ( + "refresh_seed", + &td.details.refresh.refresh_seed), + GNUNET_PQ_result_spec_uint32 ( + "noreveal_index", + &td.details.refresh.noreveal_index), + GNUNET_PQ_result_spec_auto_from_type ( + "planchets_h", + &td.details.refresh.planchets_h), + GNUNET_PQ_result_spec_auto_from_type ( + "selected_h", + &td.details.refresh.selected_h), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ( + "blinding_seed", + &td.details.refresh.blinding_seed), + &td.details.refresh.no_blinding_seed), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_array_cs_r_pub ( + ctx->conn, + "cs_r_values", + &td.details.refresh.num_cs_r_values, + &td.details.refresh.cs_r_values), + &no_cs_r_values), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ( + "cs_r_choices", + &td.details.refresh.cs_r_choices), + &no_cs_r_choices), + GNUNET_PQ_result_spec_array_uint64 ( + ctx->conn, + "denom_serials", + &td.details.refresh.num_coins, + &td.details.refresh.denom_serials), + TALER_PQ_result_spec_array_blinded_denom_sig ( + ctx->conn, + "denom_sigs", + &num_denom_sigs, + &td.details.refresh.denom_sigs), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with batch deposits table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_batch_deposits (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_BATCH_DEPOSITS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_uint64 ( + "shard", + &td.details.batch_deposits.shard), + GNUNET_PQ_result_spec_auto_from_type ( + "merchant_pub", + &td.details.batch_deposits.merchant_pub), + GNUNET_PQ_result_spec_timestamp ( + "wallet_timestamp", + &td.details.batch_deposits.wallet_timestamp), + GNUNET_PQ_result_spec_timestamp ( + "exchange_timestamp", + &td.details.batch_deposits.exchange_timestamp), + GNUNET_PQ_result_spec_timestamp ( + "refund_deadline", + &td.details.batch_deposits.refund_deadline), + GNUNET_PQ_result_spec_timestamp ( + "wire_deadline", + &td.details.batch_deposits.wire_deadline), + GNUNET_PQ_result_spec_auto_from_type ( + "h_contract_terms", + &td.details.batch_deposits.h_contract_terms), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ( + "wallet_data_hash", + &td.details.batch_deposits.wallet_data_hash), + &td.details.batch_deposits.no_wallet_data_hash), + GNUNET_PQ_result_spec_auto_from_type ( + "wire_salt", + &td.details.batch_deposits.wire_salt), + GNUNET_PQ_result_spec_auto_from_type ( + "wire_target_h_payto", + &td.details.batch_deposits.wire_target_h_payto), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ( + "policy_details_serial_id", + &td.details.batch_deposits.policy_details_serial_id), + &td.details.batch_deposits.no_policy_details), + GNUNET_PQ_result_spec_bool ( + "policy_blocked", + &td.details.batch_deposits.policy_blocked), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "total_amount", + &td.details.batch_deposits.total_amount), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "total_without_fee", + &td.details.batch_deposits.total_without_fee), + GNUNET_PQ_result_spec_auto_from_type ( + "merchant_sig", + &td.details.batch_deposits.merchant_sig), + GNUNET_PQ_result_spec_bool ( + "done", + &td.details.batch_deposits.done), + GNUNET_PQ_result_spec_end + }; + + td.details.batch_deposits.policy_details_serial_id = 0; + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with coin deposits table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_coin_deposits (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_COIN_DEPOSITS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_uint64 ( + "batch_deposit_serial_id", + &td.details.coin_deposits.batch_deposit_serial_id), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_pub", + &td.details.coin_deposits.coin_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_sig", + &td.details.coin_deposits.coin_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount_with_fee", + &td.details.coin_deposits.amount_with_fee), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with refunds table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_refunds (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_REFUNDS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_pub", + &td.details.refunds.coin_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "merchant_sig", + &td.details.refunds.merchant_sig), + GNUNET_PQ_result_spec_uint64 ( + "rtransaction_id", + &td.details.refunds.rtransaction_id), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount_with_fee", + &td.details.refunds.amount_with_fee), + GNUNET_PQ_result_spec_uint64 ( + "batch_deposit_serial_id", + &td.details.refunds.batch_deposit_serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wire_out table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_wire_out (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_WIRE_OUT + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_timestamp ( + "execution_date", + &td.details.wire_out.execution_date), + GNUNET_PQ_result_spec_auto_from_type ( + "wtid_raw", + &td.details.wire_out.wtid_raw), + GNUNET_PQ_result_spec_auto_from_type ( + "wire_target_h_payto", + &td.details.wire_out.wire_target_h_payto), + GNUNET_PQ_result_spec_string ( + "exchange_account_section", + &td.details.wire_out.exchange_account_section), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount", + &td.details.wire_out.amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with aggregation_tracking table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_aggregation_tracking (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_uint64 ( + "batch_deposit_serial_id", + &td.details.aggregation_tracking.batch_deposit_serial_id), + GNUNET_PQ_result_spec_auto_from_type ( + "wtid_raw", + &td.details.aggregation_tracking.wtid_raw), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wire_fee table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_wire_fee (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_WIRE_FEE + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_string ("wire_method", + &td.details.wire_fee.wire_method), + GNUNET_PQ_result_spec_timestamp ("start_date", + &td.details.wire_fee.start_date), + GNUNET_PQ_result_spec_timestamp ("end_date", + &td.details.wire_fee.end_date), + TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee", + &td.details.wire_fee.fees.wire), + TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", + &td.details.wire_fee.fees.closing), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + &td.details.wire_fee.master_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wire_fee table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_global_fee (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_GLOBAL_FEE + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "serial", + &td.serial), + GNUNET_PQ_result_spec_timestamp ( + "start_date", + &td.details.global_fee.start_date), + GNUNET_PQ_result_spec_timestamp ( + "end_date", + &td.details.global_fee.end_date), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "history_fee", + &td.details.global_fee.fees.history), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "account_fee", + &td.details.global_fee.fees.account), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "purse_fee", + &td.details.global_fee.fees.purse), + GNUNET_PQ_result_spec_relative_time ( + "purse_timeout", + &td.details.global_fee.purse_timeout), + GNUNET_PQ_result_spec_relative_time ( + "history_expiration", + &td.details.global_fee.history_expiration), + GNUNET_PQ_result_spec_uint32 ( + "purse_account_limit", + &td.details.global_fee.purse_account_limit), + GNUNET_PQ_result_spec_auto_from_type ( + "master_sig", + &td.details.global_fee.master_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with recoup table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_recoup (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_RECOUP + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &td.details.recoup.coin_sig), + GNUNET_PQ_result_spec_auto_from_type ("coin_blind", + &td.details.recoup.coin_blind), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &td.details.recoup.amount), + GNUNET_PQ_result_spec_timestamp ("recoup_timestamp", + &td.details.recoup.timestamp), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_pub", + &td.details.recoup.coin_pub), + GNUNET_PQ_result_spec_uint64 ("withdraw_serial_id", + &td.details.recoup.withdraw_serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with recoup_refresh table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_recoup_refresh (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_RECOUP_REFRESH + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &td.details.recoup_refresh.coin_sig) + , + GNUNET_PQ_result_spec_auto_from_type ( + "coin_blind", + &td.details.recoup_refresh.coin_blind), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &td.details.recoup_refresh.amount), + GNUNET_PQ_result_spec_timestamp ("recoup_timestamp", + &td.details.recoup_refresh.timestamp), + GNUNET_PQ_result_spec_uint64 ("known_coin_id", + &td.details.recoup_refresh.known_coin_id), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_pub", + &td.details.recoup_refresh.coin_pub), + GNUNET_PQ_result_spec_uint64 ("rrc_serial", + &td.details.recoup_refresh.rrc_serial), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with extensions table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_extensions (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_EXTENSIONS + }; + bool no_manifest = false; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("extension_id", + &td.serial), + GNUNET_PQ_result_spec_string ("name", + &td.details.extensions.name), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("manifest", + &td.details.extensions.manifest), + &no_manifest), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with policy_details table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_policy_details (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_POLICY_DETAILS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("policy_details_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ("hash_code", + &td.details.policy_details. + hash_code), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("policy_json", + &td.details.policy_details. + policy_json), + &td.details.policy_details.no_policy_json), + GNUNET_PQ_result_spec_timestamp ("deadline", + &td.details.policy_details. + deadline), + TALER_PQ_RESULT_SPEC_AMOUNT ("commitment", + &td.details.policy_details. + commitment), + TALER_PQ_RESULT_SPEC_AMOUNT ("accumulated_total", + &td.details.policy_details. + accumulated_total), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee", + &td.details.policy_details. + fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("transferable", + &td.details.policy_details. + transferable), + GNUNET_PQ_result_spec_uint16 ("fulfillment_state", + &td.details.policy_details. + fulfillment_state), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ("fulfillment_id", + &td.details.policy_details. + fulfillment_id), + &td.details.policy_details.no_fulfillment_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with policy_fulfillments table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_policy_fulfillments (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_POLICY_FULFILLMENTS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + bool no_proof = false; + bool no_timestamp = false; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("fulfillment_id", + &td.serial), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_timestamp ("fulfillment_timestamp", + &td.details.policy_fulfillments. + fulfillment_timestamp), + &no_timestamp), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("fulfillment_proof", + &td.details.policy_fulfillments. + fulfillment_proof), + &no_proof), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with purse_requests table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_purse_requests (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_PURSE_REQUESTS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "purse_requests_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_pub", + &td.details.purse_requests.purse_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "merge_pub", + &td.details.purse_requests.merge_pub), + GNUNET_PQ_result_spec_timestamp ( + "purse_creation", + &td.details.purse_requests.purse_creation), + GNUNET_PQ_result_spec_timestamp ( + "purse_expiration", + &td.details.purse_requests.purse_expiration), + GNUNET_PQ_result_spec_auto_from_type ( + "h_contract_terms", + &td.details.purse_requests.h_contract_terms), + GNUNET_PQ_result_spec_uint32 ( + "age_limit", + &td.details.purse_requests.age_limit), + GNUNET_PQ_result_spec_uint32 ( + "flags", + &td.details.purse_requests.flags), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount_with_fee", + &td.details.purse_requests.amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "purse_fee", + &td.details.purse_requests.purse_fee), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_sig", + &td.details.purse_requests.purse_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with purse_decision table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_purse_decision (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_PURSE_DECISION + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "purse_refunds_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_pub", + &td.details.purse_decision.purse_pub), + GNUNET_PQ_result_spec_timestamp ( + "action_timestamp", + &td.details.purse_decision.action_timestamp), + GNUNET_PQ_result_spec_bool ( + "refunded", + &td.details.purse_decision.refunded), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with purse_merges table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_purse_merges (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_PURSE_MERGES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "purse_merge_request_serial_id", + &td.serial), + GNUNET_PQ_result_spec_uint64 ( + "partner_serial_id", + &td.details.purse_merges.partner_serial_id), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.purse_merges.reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_pub", + &td.details.purse_merges.purse_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "merge_sig", + &td.details.purse_merges.merge_sig), + GNUNET_PQ_result_spec_timestamp ( + "merge_timestamp", + &td.details.purse_merges.merge_timestamp), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with purse_deposits table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_purse_deposits (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_PURSE_DEPOSITS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "purse_deposit_serial_id", + &td.serial), + GNUNET_PQ_result_spec_uint64 ( + "partner_serial_id", + &td.details.purse_deposits.partner_serial_id), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_pub", + &td.details.purse_deposits.purse_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_pub", + &td.details.purse_deposits.coin_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount_with_fee", + &td.details.purse_deposits.amount_with_fee), + GNUNET_PQ_result_spec_auto_from_type ( + "coin_sig", + &td.details.purse_deposits.coin_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with account_merges table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_account_merges (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_ACCOUNT_MERGES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "account_merge_request_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.account_merges.reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_sig", + &td.details.account_merges.reserve_sig), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_pub", + &td.details.account_merges.purse_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "wallet_h_payto", + &td.details.account_merges.wallet_h_payto), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with history_requests table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_history_requests (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_HISTORY_REQUESTS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "history_request_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.history_requests.reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_sig", + &td.details.history_requests.reserve_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "history_fee", + &td.details.history_requests.history_fee), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with close_requests table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_close_requests (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_CLOSE_REQUESTS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "close_request_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.close_requests.reserve_pub), + GNUNET_PQ_result_spec_timestamp ( + "close_timestamp", + &td.details.close_requests.close_timestamp), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_sig", + &td.details.close_requests.reserve_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "close", + &td.details.close_requests.close), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "close_fee", + &td.details.close_requests.close_fee), + GNUNET_PQ_result_spec_string ( + "payto_uri", + &td.details.close_requests.payto_uri.full_payto), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wads_out table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_wads_out (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_WADS_OUT + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "wad_out_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "wad_id", + &td.details.wads_out.wad_id), + GNUNET_PQ_result_spec_uint64 ( + "partner_serial_id", + &td.details.wads_out.partner_serial_id), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount", + &td.details.wads_out.amount), + GNUNET_PQ_result_spec_timestamp ( + "execution_time", + &td.details.wads_out.execution_time), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wads_out_entries table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_wads_out_entries (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "wad_out_entry_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.wads_out_entries.reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_pub", + &td.details.wads_out_entries.purse_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "h_contract", + &td.details.wads_out_entries.h_contract), + GNUNET_PQ_result_spec_timestamp ( + "purse_expiration", + &td.details.wads_out_entries.purse_expiration), + GNUNET_PQ_result_spec_timestamp ( + "merge_timestamp", + &td.details.wads_out_entries.merge_timestamp), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount_with_fee", + &td.details.wads_out_entries.amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "wad_fee", + &td.details.wads_out_entries.wad_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "deposit_fees", + &td.details.wads_out_entries.deposit_fees), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_sig", + &td.details.wads_out_entries.reserve_sig), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_sig", + &td.details.wads_out_entries.purse_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wads_in table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_wads_in (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_WADS_IN + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "wad_in_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "wad_id", + &td.details.wads_in.wad_id), + GNUNET_PQ_result_spec_string ( + "origin_exchange_url", + &td.details.wads_in.origin_exchange_url), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount", + &td.details.wads_in.amount), + GNUNET_PQ_result_spec_timestamp ( + "arrival_time", + &td.details.wads_in.arrival_time), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with wads_in_entries table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_wads_in_entries (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "wad_in_entry_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.wads_in_entries.reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_pub", + &td.details.wads_in_entries.purse_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "h_contract", + &td.details.wads_in_entries.h_contract), + GNUNET_PQ_result_spec_timestamp ( + "purse_expiration", + &td.details.wads_in_entries.purse_expiration), + GNUNET_PQ_result_spec_timestamp ( + "merge_timestamp", + &td.details.wads_in_entries.merge_timestamp), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount_with_fee", + &td.details.wads_in_entries.amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "wad_fee", + &td.details.wads_in_entries.wad_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "deposit_fees", + &td.details.wads_in_entries.deposit_fees), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_sig", + &td.details.wads_in_entries.reserve_sig), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_sig", + &td.details.wads_in_entries.purse_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with profit_drains table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_profit_drains (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_PROFIT_DRAINS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "profit_drain_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "wtid", + &td.details.profit_drains.wtid), + GNUNET_PQ_result_spec_string ( + "account_section", + &td.details.profit_drains.account_section), + GNUNET_PQ_result_spec_string ( + "payto_uri", + &td.details.profit_drains.payto_uri.full_payto), + GNUNET_PQ_result_spec_timestamp ( + "trigger_date", + &td.details.profit_drains.trigger_date), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount", + &td.details.profit_drains.amount), + GNUNET_PQ_result_spec_auto_from_type ( + "master_sig", + &td.details.profit_drains.master_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with aml_staff table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_aml_staff (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_AML_STAFF + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "aml_staff_uuid", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "decider_pub", + &td.details.aml_staff.decider_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "master_sig", + &td.details.aml_staff.master_sig), + GNUNET_PQ_result_spec_string ( + "decider_name", + &td.details.aml_staff.decider_name), + GNUNET_PQ_result_spec_bool ( + "is_active", + &td.details.aml_staff.is_active), + GNUNET_PQ_result_spec_bool ( + "read_only", + &td.details.aml_staff.read_only), + GNUNET_PQ_result_spec_timestamp ( + "last_change", + &td.details.aml_staff.last_change), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with purse_deletion table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_purse_deletion (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_PURSE_DELETION + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "purse_deletion_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_sig", + &td.details.purse_deletion.purse_sig), + GNUNET_PQ_result_spec_auto_from_type ( + "purse_pub", + &td.details.purse_deletion.purse_pub), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with withdraw table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_withdraw (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_WITHDRAW + }; + + for (unsigned int i = 0; i<num_results; i++) + { + bool no_max_age; + bool no_noreveal_index; + bool no_selected_h; + bool no_cs_r_values; + bool no_cs_r_choices; + size_t num_sigs; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "withdraw_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "planchets_h", + &td.details.withdraw.planchets_h), + GNUNET_PQ_result_spec_timestamp ( + "execution_date", + &td.details.withdraw.execution_date), + TALER_PQ_RESULT_SPEC_AMOUNT ( + "amount_with_fee", + &td.details.withdraw.amount_with_fee), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_pub", + &td.details.withdraw.reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "reserve_sig", + &td.details.withdraw.reserve_sig), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint16 ( + "max_age", + &td.details.withdraw.max_age), + &no_max_age), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint16 ( + "noreveal_index", + &td.details.withdraw.noreveal_index), + &no_noreveal_index), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ( + "selected_h", + &td.details.withdraw.selected_h), + &no_selected_h), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ( + "blinding_seed", + &td.details.withdraw.blinding_seed), + &td.details.withdraw.no_blinding_seed), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_array_cs_r_pub ( + ctx->conn, + "cs_r_values", + &td.details.withdraw.num_cs_r_values, + &td.details.withdraw.cs_r_values), + &no_cs_r_values), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ( + "cs_r_choices", + &td.details.withdraw.cs_r_choices), + &no_cs_r_choices), + GNUNET_PQ_result_spec_array_uint64 ( + ctx->conn, + "denom_serials", + &td.details.withdraw.num_coins, + &td.details.withdraw.denom_serials), + TALER_PQ_result_spec_array_blinded_denom_sig ( + ctx->conn, + "denom_sigs", + &num_sigs, + &td.details.withdraw.denom_sigs), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + if (num_sigs != td.details.withdraw.num_coins) + { + GNUNET_break (0); + ctx->error = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + if (no_max_age != no_noreveal_index) + { + GNUNET_break (0); + ctx->error = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + if (no_max_age != no_selected_h) + { + GNUNET_break (0); + ctx->error = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + if (no_cs_r_values != no_cs_r_choices) + { + GNUNET_break (0); + ctx->error = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + if (no_cs_r_values != td.details.withdraw.no_blinding_seed) + { + GNUNET_break (0); + ctx->error = true; + GNUNET_PQ_cleanup_result (rs); + return; + } + td.details.withdraw.age_proof_required = ! no_max_age; + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with legitimization_measures table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_legitimization_measures (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_LEGITIMIZATION_MEASURES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "access_token", + &td.details.legitimization_measures.target_token), + GNUNET_PQ_result_spec_timestamp ( + "start_time", + &td.details.legitimization_measures.start_time), + TALER_PQ_result_spec_json ( + "jmeasures", + &td.details.legitimization_measures.measures), + GNUNET_PQ_result_spec_uint32 ( + "display_priority", + &td.details.legitimization_measures.display_priority), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with legitimization_outcomes table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_legitimization_outcomes (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_LEGITIMIZATION_OUTCOMES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "h_payto", + &td.details.legitimization_outcomes.h_payto), + GNUNET_PQ_result_spec_timestamp ( + "decision_time", + &td.details.legitimization_outcomes.decision_time), + GNUNET_PQ_result_spec_timestamp ( + "expiration_time", + &td.details.legitimization_outcomes.expiration_time), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ( + "jproperties", + &td.details.legitimization_outcomes.properties), + NULL), + GNUNET_PQ_result_spec_bool ( + "to_investigate_id", + &td.details.legitimization_outcomes.to_investigate), + TALER_PQ_result_spec_json ( + "jnew_rules", + &td.details.legitimization_outcomes.new_rules), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with legitimization_processes table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_legitimization_processes (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "h_payto", + &td.details.legitimization_processes.h_payto), + GNUNET_PQ_result_spec_timestamp ( + "start_time", + &td.details.legitimization_processes.start_time), + GNUNET_PQ_result_spec_timestamp ( + "expiration_time", + &td.details.legitimization_processes.expiration_time), + GNUNET_PQ_result_spec_uint64 ( + "legitimization_measure_serial_id", + &td.details.legitimization_processes.legitimization_measure_serial_id), + GNUNET_PQ_result_spec_uint32 ( + "measure_index", + &td.details.legitimization_processes.measure_index), + GNUNET_PQ_result_spec_string ( + "provider_name", + &td.details.legitimization_processes.provider_name), + GNUNET_PQ_result_spec_string ( + "provider_user_id", + &td.details.legitimization_processes.provider_user_id), + GNUNET_PQ_result_spec_string ( + "provider_legitimization_id", + &td.details.legitimization_processes.provider_legitimization_id), + GNUNET_PQ_result_spec_string ( + "redirect_url", + &td.details.legitimization_processes.redirect_url), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with kyc_attributes table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_kyc_attributes (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "kyc_attributes_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "h_payto", + &td.details.kyc_attributes.h_payto), + GNUNET_PQ_result_spec_uint64 ( + "legitimization_serial", + &td.details.kyc_attributes.legitimization_serial), + GNUNET_PQ_result_spec_timestamp ( + "collection_time", + &td.details.kyc_attributes.collection_time), + GNUNET_PQ_result_spec_timestamp ( + "expiration_time", + &td.details.kyc_attributes.expiration_time), + GNUNET_PQ_result_spec_uint64 ( + "trigger_outcome_serial", + &td.details.kyc_attributes.trigger_outcome_serial), + GNUNET_PQ_result_spec_variable_size ( + "encrypted_attributes", + &td.details.kyc_attributes.encrypted_attributes, + &td.details.kyc_attributes.encrypted_attributes_size), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with aml_history table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_aml_history (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_AML_HISTORY + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "aml_history_serial_id", + &td.serial), + GNUNET_PQ_result_spec_auto_from_type ( + "h_payto", + &td.details.aml_history.h_payto), + GNUNET_PQ_result_spec_uint64 ( + "outcome_serial_id", + &td.details.aml_history.outcome_serial_id), + GNUNET_PQ_result_spec_string ( + "justification", + &td.details.aml_history.justification), + GNUNET_PQ_result_spec_auto_from_type ( + "decider_pub", + &td.details.aml_history.decider_pub), + GNUNET_PQ_result_spec_auto_from_type ( + "decider_sig", + &td.details.aml_history.decider_sig), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Function called with kyc_events table entries. + * + * @param cls closure + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lrbt_cb_table_kyc_events (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LookupRecordsByTableContext *ctx = cls; + struct TALER_EXCHANGEDB_TableData td = { + .table = TALER_EXCHANGEDB_RT_KYC_EVENTS + }; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "kyc_event_serial_id", + &td.serial), + GNUNET_PQ_result_spec_timestamp ( + "event_timestamp", + &td.details.kyc_events.event_timestamp), + GNUNET_PQ_result_spec_string ( + "event_type", + &td.details.kyc_events.event_type), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->error = true; + return; + } + ctx->cb (ctx->cb_cls, + &td); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Assign statement to @a n and PREPARE + * @a sql under name @a n. + */ +#define XPREPARE(n,sql) \ + statement = n; \ + PREPARE (ctx, n, sql); + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_records_by_table (struct EXCHANGEDB_PostgresContext *ctx, + enum TALER_EXCHANGEDB_ReplicatedTable table, + uint64_t serial, + TALER_EXCHANGEDB_ReplicationCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial), + GNUNET_PQ_query_param_end + }; + struct LookupRecordsByTableContext ctx = { + .ctx = ctx, + .cb = cb, + .cb_cls = cb_cls + }; + GNUNET_PQ_PostgresResultHandler rh = NULL; + const char *statement = NULL; + enum GNUNET_DB_QueryStatus qs; + + switch (table) + { + case TALER_EXCHANGEDB_RT_DENOMINATIONS: + XPREPARE ("select_above_serial_by_table_denominations", + "SELECT" + " denominations_serial AS serial" + ",denom_type" + ",denom_pub" + ",master_sig" + ",valid_from" + ",expire_withdraw" + ",expire_deposit" + ",expire_legal" + ",coin" + ",fee_withdraw" + ",fee_deposit" + ",fee_refresh" + ",fee_refund" + ",age_mask" + " FROM denominations" + " WHERE denominations_serial > $1" + " ORDER BY denominations_serial ASC;"); + rh = &lrbt_cb_table_denominations; + break; + case TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS: + XPREPARE ("select_above_serial_by_table_denomination_revocations", + "SELECT" + " denom_revocations_serial_id AS serial" + ",master_sig" + ",denominations_serial" + " FROM denomination_revocations" + " WHERE denom_revocations_serial_id > $1" + " ORDER BY denom_revocations_serial_id ASC;"); + rh = &lrbt_cb_table_denomination_revocations; + break; + case TALER_EXCHANGEDB_RT_WIRE_TARGETS: + XPREPARE ("select_above_serial_by_table_wire_targets", + "SELECT" + " wire_target_serial_id AS serial" + ",payto_uri" + " FROM wire_targets" + " WHERE wire_target_serial_id > $1" + " ORDER BY wire_target_serial_id ASC;"); + rh = &lrbt_cb_table_wire_targets; + break; + case TALER_EXCHANGEDB_RT_KYC_TARGETS: + XPREPARE ("select_above_serial_by_table_kyc_targets", + "SELECT" + " kyc_target_serial_id AS serial" + ",h_normalized_payto" + ",access_token" + ",target_pub" + ",is_wallet" + " FROM kyc_targets" + " WHERE kyc_target_serial_id > $1" + " ORDER BY kyc_target_serial_id ASC;"); + rh = &lrbt_cb_table_kyc_targets; + break; + case TALER_EXCHANGEDB_RT_RESERVES: + XPREPARE ("select_above_serial_by_table_reserves", + "SELECT" + " reserve_uuid AS serial" + ",reserve_pub" + ",expiration_date" + ",gc_date" + " FROM reserves" + " WHERE reserve_uuid > $1" + " ORDER BY reserve_uuid ASC;"); + rh = &lrbt_cb_table_reserves; + break; + case TALER_EXCHANGEDB_RT_RESERVES_IN: + XPREPARE ("select_above_serial_by_table_reserves_in", + "SELECT" + " reserve_in_serial_id AS serial" + ",reserve_pub" + ",wire_reference" + ",credit" + ",wire_source_h_payto" + ",exchange_account_section" + ",execution_date" + " FROM reserves_in" + " WHERE reserve_in_serial_id > $1" + " ORDER BY reserve_in_serial_id ASC;"); + rh = &lrbt_cb_table_reserves_in; + break; + case TALER_EXCHANGEDB_RT_KYCAUTHS_IN: + XPREPARE ("select_above_serial_by_table_kycauth_in", + "SELECT" + " kycauth_in_serial_id AS serial" + ",account_pub" + ",wire_reference" + ",credit" + ",wire_source_h_payto" + ",exchange_account_section" + ",execution_date" + " FROM kycauths_in" + " WHERE kycauth_in_serial_id > $1" + " ORDER BY kycauth_in_serial_id ASC;"); + rh = &lrbt_cb_table_kycauth_in; + break; + case TALER_EXCHANGEDB_RT_RESERVES_CLOSE: + XPREPARE ("select_above_serial_by_table_reserves_close", + "SELECT" + " close_uuid AS serial" + ",reserve_pub" + ",execution_date" + ",wtid" + ",wire_target_h_payto" + ",amount" + ",closing_fee" + " FROM reserves_close" + " WHERE close_uuid > $1" + " ORDER BY close_uuid ASC;"); + rh = &lrbt_cb_table_reserves_close; + break; + case TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS: + XPREPARE ("select_above_serial_by_table_reserves_open_requests", + "SELECT" + " open_request_uuid AS serial" + ",reserve_pub" + ",request_timestamp" + ",expiration_date" + ",reserve_sig" + ",reserve_payment" + ",requested_purse_limit" + " FROM reserves_open_requests" + " WHERE open_request_uuid > $1" + " ORDER BY open_request_uuid ASC;"); + rh = &lrbt_cb_table_reserves_open_requests; + break; + case TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS: + XPREPARE ("select_above_serial_by_table_reserves_open_deposits", + "SELECT" + " reserves_open_deposit_uuid AS serial" + ",reserve_sig" + ",reserve_pub" + ",coin_pub" + ",coin_sig" + ",contribution" + " FROM reserves_open_deposits" + " WHERE reserves_open_deposit_uuid > $1" + " ORDER BY reserves_open_deposit_uuid ASC;"); + rh = &lrbt_cb_table_reserves_open_deposits; + break; + case TALER_EXCHANGEDB_RT_AUDITORS: + XPREPARE ("select_above_serial_by_table_auditors", + "SELECT" + " auditor_uuid AS serial" + ",auditor_pub" + ",auditor_name" + ",auditor_url" + ",is_active" + ",last_change" + " FROM auditors" + " WHERE auditor_uuid > $1" + " ORDER BY auditor_uuid ASC;"); + rh = &lrbt_cb_table_auditors; + break; + case TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS: + XPREPARE ("select_above_serial_by_table_auditor_denom_sigs", + "SELECT" + " auditor_denom_serial AS serial" + ",auditor_uuid" + ",denominations_serial" + ",auditor_sig" + " FROM auditor_denom_sigs" + " WHERE auditor_denom_serial > $1" + " ORDER BY auditor_denom_serial ASC;"); + rh = &lrbt_cb_table_auditor_denom_sigs; + break; + case TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS: + XPREPARE ("select_above_serial_by_table_exchange_sign_keys", + "SELECT" + " esk_serial AS serial" + ",exchange_pub" + ",master_sig" + ",valid_from" + ",expire_sign" + ",expire_legal" + " FROM exchange_sign_keys" + " WHERE esk_serial > $1" + " ORDER BY esk_serial ASC;"); + rh = &lrbt_cb_table_exchange_sign_keys; + break; + case TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS: + XPREPARE ("select_above_serial_by_table_signkey_revocations", + "SELECT" + " signkey_revocations_serial_id AS serial" + ",esk_serial" + ",master_sig" + " FROM signkey_revocations" + " WHERE signkey_revocations_serial_id > $1" + " ORDER BY signkey_revocations_serial_id ASC;"); + rh = &lrbt_cb_table_signkey_revocations; + break; + case TALER_EXCHANGEDB_RT_KNOWN_COINS: + XPREPARE ("select_above_serial_by_table_known_coins", + "SELECT" + " known_coin_id AS serial" + ",coin_pub" + ",denom_sig" + ",denominations_serial" + " FROM known_coins" + " WHERE known_coin_id > $1" + " ORDER BY known_coin_id ASC;"); + rh = &lrbt_cb_table_known_coins; + break; + case TALER_EXCHANGEDB_RT_REFRESH: + XPREPARE ("select_above_serial_by_table_refresh", + "SELECT" + " refresh_id AS serial" + ",rc" + ",execution_date" + ",amount_with_fee" + ",old_coin_pub" + ",old_coin_sig" + ",refresh_seed" + ",noreveal_index" + ",planchets_h" + ",selected_h" + ",blinding_seed" + ",cs_r_values" + ",cs_r_choices" + ",denom_serials" + ",denom_sigs" + " FROM refresh" + " WHERE refresh_id > $1" + " ORDER BY refresh_id ASC;"); + rh = &lrbt_cb_table_refresh; + break; + case TALER_EXCHANGEDB_RT_BATCH_DEPOSITS: + XPREPARE ("select_above_serial_by_table_batch_deposits", + "SELECT" + " batch_deposit_serial_id AS serial" + ",shard" + ",merchant_pub" + ",wallet_timestamp" + ",exchange_timestamp" + ",refund_deadline" + ",wire_deadline" + ",h_contract_terms" + ",wallet_data_hash" + ",wire_salt" + ",wire_target_h_payto" + ",policy_details_serial_id" + ",policy_blocked" + ",total_amount" + ",total_without_fee" + ",merchant_sig" + ",done" + " FROM batch_deposits" + " WHERE batch_deposit_serial_id > $1" + " ORDER BY batch_deposit_serial_id ASC;"); + rh = &lrbt_cb_table_batch_deposits; + break; + case TALER_EXCHANGEDB_RT_COIN_DEPOSITS: + XPREPARE ("select_above_serial_by_table_coin_deposits", + "SELECT" + " coin_deposit_serial_id AS serial" + ",batch_deposit_serial_id" + ",coin_pub" + ",coin_sig" + ",amount_with_fee" + " FROM coin_deposits" + " WHERE coin_deposit_serial_id > $1" + " ORDER BY coin_deposit_serial_id ASC;"); + rh = &lrbt_cb_table_coin_deposits; + break; + case TALER_EXCHANGEDB_RT_REFUNDS: + XPREPARE ("select_above_serial_by_table_refunds", + "SELECT" + " refund_serial_id AS serial" + ",coin_pub" + ",merchant_sig" + ",rtransaction_id" + ",amount_with_fee" + ",batch_deposit_serial_id" + " FROM refunds" + " WHERE refund_serial_id > $1" + " ORDER BY refund_serial_id ASC;"); + rh = &lrbt_cb_table_refunds; + break; + case TALER_EXCHANGEDB_RT_WIRE_OUT: + XPREPARE ("select_above_serial_by_table_wire_out", + "SELECT" + " wireout_uuid AS serial" + ",execution_date" + ",wtid_raw" + ",wire_target_h_payto" + ",exchange_account_section" + ",amount" + " FROM wire_out" + " WHERE wireout_uuid > $1" + " ORDER BY wireout_uuid ASC;"); + rh = &lrbt_cb_table_wire_out; + break; + case TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING: + XPREPARE ("select_above_serial_by_table_aggregation_tracking", + "SELECT" + " aggregation_serial_id AS serial" + ",batch_deposit_serial_id" + ",wtid_raw" + " FROM aggregation_tracking" + " WHERE aggregation_serial_id > $1" + " ORDER BY aggregation_serial_id ASC;"); + rh = &lrbt_cb_table_aggregation_tracking; + break; + case TALER_EXCHANGEDB_RT_WIRE_FEE: + XPREPARE ("select_above_serial_by_table_wire_fee", + "SELECT" + " wire_fee_serial AS serial" + ",wire_method" + ",start_date" + ",end_date" + ",wire_fee" + ",closing_fee" + ",master_sig" + " FROM wire_fee" + " WHERE wire_fee_serial > $1" + " ORDER BY wire_fee_serial ASC;"); + rh = &lrbt_cb_table_wire_fee; + break; + case TALER_EXCHANGEDB_RT_GLOBAL_FEE: + XPREPARE ("select_above_serial_by_table_global_fee", + "SELECT" + " global_fee_serial AS serial" + ",start_date" + ",end_date" + ",history_fee" + ",account_fee" + ",purse_fee" + ",purse_timeout" + ",history_expiration" + ",purse_account_limit" + ",master_sig" + " FROM global_fee" + " WHERE global_fee_serial > $1" + " ORDER BY global_fee_serial ASC;"); + rh = &lrbt_cb_table_global_fee; + break; + case TALER_EXCHANGEDB_RT_RECOUP: + XPREPARE ("select_above_serial_by_table_recoup", + "SELECT" + " recoup_uuid AS serial" + ",coin_sig" + ",coin_blind" + ",amount" + ",recoup_timestamp" + ",coin_pub" + ",reserve_out_serial_id" + " FROM recoup" + " WHERE recoup_uuid > $1" + " ORDER BY recoup_uuid ASC;"); + rh = &lrbt_cb_table_recoup; + break; + case TALER_EXCHANGEDB_RT_RECOUP_REFRESH: + XPREPARE ("select_above_serial_by_table_recoup_refresh", + "SELECT" + " recoup_refresh_uuid AS serial" + ",coin_sig" + ",coin_blind" + ",amount" + ",recoup_timestamp" + ",coin_pub" + ",known_coin_id" + ",rrc_serial" + " FROM recoup_refresh" + " WHERE recoup_refresh_uuid > $1" + " ORDER BY recoup_refresh_uuid ASC;"); + rh = &lrbt_cb_table_recoup_refresh; + break; + case TALER_EXCHANGEDB_RT_EXTENSIONS: + // FIXME: this seems broken! -- where is the SQL!? + statement = "select_above_serial_by_table_extensions"; + rh = &lrbt_cb_table_extensions; + break; + case TALER_EXCHANGEDB_RT_POLICY_DETAILS: + // FIXME: this seems broken! -- where is the SQL!? + statement = "select_above_serial_by_table_policy_details"; + rh = &lrbt_cb_table_policy_details; + break; + case TALER_EXCHANGEDB_RT_POLICY_FULFILLMENTS: + // FIXME: this seems broken! -- where is the SQL!? + statement = "select_above_serial_by_table_policy_fulfillments"; + rh = &lrbt_cb_table_policy_fulfillments; + break; + case TALER_EXCHANGEDB_RT_PURSE_REQUESTS: + XPREPARE ("select_above_serial_by_table_purse_requests", + "SELECT" + " purse_requests_serial_id" + ",purse_pub" + ",merge_pub" + ",purse_creation" + ",purse_expiration" + ",h_contract_terms" + ",age_limit" + ",flags" + ",amount_with_fee" + ",purse_fee" + ",purse_sig" + " FROM purse_requests" + " WHERE purse_requests_serial_id > $1" + " ORDER BY purse_requests_serial_id ASC;"); + rh = &lrbt_cb_table_purse_requests; + break; + case TALER_EXCHANGEDB_RT_PURSE_DECISION: + XPREPARE ("select_above_serial_by_table_purse_decision", + "SELECT" + " purse_decision_serial_id" + ",action_timestamp" + ",refunded" + ",purse_pub" + " FROM purse_decision" + " WHERE purse_decision_serial_id > $1" + " ORDER BY purse_decision_serial_id ASC;"); + rh = &lrbt_cb_table_purse_decision; + break; + case TALER_EXCHANGEDB_RT_PURSE_MERGES: + XPREPARE ("select_above_serial_by_table_purse_merges", + "SELECT" + " purse_merge_request_serial_id" + ",partner_serial_id" + ",reserve_pub" + ",purse_pub" + ",merge_sig" + ",merge_timestamp" + " FROM purse_merges" + " WHERE purse_merge_request_serial_id > $1" + " ORDER BY purse_merge_request_serial_id ASC;"); + rh = &lrbt_cb_table_purse_merges; + break; + case TALER_EXCHANGEDB_RT_PURSE_DEPOSITS: + XPREPARE ("select_above_serial_by_table_purse_deposits", + "SELECT" + " purse_deposit_serial_id" + ",partner_serial_id" + ",purse_pub" + ",coin_pub" + ",amount_with_fee" + ",coin_sig" + " FROM purse_deposits" + " WHERE purse_deposit_serial_id > $1" + " ORDER BY purse_deposit_serial_id ASC;"); + rh = &lrbt_cb_table_purse_deposits; + break; + case TALER_EXCHANGEDB_RT_ACCOUNT_MERGES: + XPREPARE ("select_above_serial_by_table_account_merges", + "SELECT" + " account_merge_request_serial_id" + ",reserve_pub" + ",reserve_sig" + ",purse_pub" + ",wallet_h_payto" + " FROM account_merges" + " WHERE account_merge_request_serial_id > $1" + " ORDER BY account_merge_request_serial_id ASC;"); + rh = &lrbt_cb_table_account_merges; + break; + case TALER_EXCHANGEDB_RT_HISTORY_REQUESTS: + XPREPARE ("select_above_serial_by_table_history_requests", + "SELECT" + " history_request_serial_id" + ",reserve_pub" + ",request_timestamp" + ",reserve_sig" + ",history_fee" + " FROM history_requests" + " WHERE history_request_serial_id > $1" + " ORDER BY history_request_serial_id ASC;"); + rh = &lrbt_cb_table_history_requests; + break; + case TALER_EXCHANGEDB_RT_CLOSE_REQUESTS: + XPREPARE ("select_above_serial_by_table_close_requests", + "SELECT" + " close_request_serial_id" + ",reserve_pub" + ",close_timestamp" + ",reserve_sig" + ",close" + " FROM close_requests" + " WHERE close_request_serial_id > $1" + " ORDER BY close_request_serial_id ASC;"); + rh = &lrbt_cb_table_close_requests; + break; + case TALER_EXCHANGEDB_RT_WADS_OUT: + XPREPARE ("select_above_serial_by_table_wads_out", + "SELECT" + " wad_out_serial_id" + ",wad_id" + ",partner_serial_id" + ",amount" + ",execution_time" + " FROM wads_out" + " WHERE wad_out_serial_id > $1" + " ORDER BY wad_out_serial_id ASC;"); + rh = &lrbt_cb_table_wads_out; + break; + case TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES: + XPREPARE ("select_above_serial_by_table_wads_out_entries", + "SELECT" + " wad_out_entry_serial_id" + ",reserve_pub" + ",purse_pub" + ",h_contract" + ",purse_expiration" + ",merge_timestamp" + ",amount_with_fee" + ",wad_fee" + ",deposit_fees" + ",reserve_sig" + ",purse_sig" + " FROM wad_out_entries" + " WHERE wad_out_entry_serial_id > $1" + " ORDER BY wad_out_entry_serial_id ASC;"); + rh = &lrbt_cb_table_wads_out_entries; + break; + case TALER_EXCHANGEDB_RT_WADS_IN: + XPREPARE ("select_above_serial_by_table_wads_in", + "SELECT" + " wad_in_serial_id" + ",wad_id" + ",origin_exchange_url" + ",amount" + ",arrival_time" + " FROM wads_in" + " WHERE wad_in_serial_id > $1" + " ORDER BY wad_in_serial_id ASC;"); + rh = &lrbt_cb_table_wads_in; + break; + case TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES: + XPREPARE ("select_above_serial_by_table_wads_in_entries", + "SELECT" + " wad_in_entry_serial_id" + ",reserve_pub" + ",purse_pub" + ",h_contract" + ",purse_expiration" + ",merge_timestamp" + ",amount_with_fee" + ",wad_fee" + ",deposit_fees" + ",reserve_sig" + ",purse_sig" + " FROM wad_in_entries" + " WHERE wad_in_entry_serial_id > $1" + " ORDER BY wad_in_entry_serial_id ASC;"); + rh = &lrbt_cb_table_wads_in_entries; + break; + case TALER_EXCHANGEDB_RT_PROFIT_DRAINS: + XPREPARE ("select_above_serial_by_table_profit_drains", + "SELECT" + " profit_drain_serial_id" + ",wtid" + ",account_section" + ",payto_uri" + ",trigger_date" + ",amount" + ",master_sig" + " FROM profit_drains" + " WHERE profit_drain_serial_id > $1" + " ORDER BY profit_drain_serial_id ASC;"); + rh = &lrbt_cb_table_profit_drains; + break; + + case TALER_EXCHANGEDB_RT_AML_STAFF: + XPREPARE ("select_above_serial_by_table_aml_staff", + "SELECT" + " aml_staff_uuid" + ",decider_pub" + ",master_sig" + ",decider_name" + ",is_active" + ",read_only" + ",last_change" + " FROM aml_staff" + " WHERE aml_staff_uuid > $1" + " ORDER BY aml_staff_uuid ASC;"); + rh = &lrbt_cb_table_aml_staff; + break; + case TALER_EXCHANGEDB_RT_PURSE_DELETION: + XPREPARE ("select_above_serial_by_table_purse_deletion", + "SELECT" + " purse_deletion_serial_id" + ",purse_pub" + ",purse_sig" + " FROM purse_deletion" + " WHERE purse_deletion_serial_id > $1" + " ORDER BY purse_deletion_serial_id ASC;"); + rh = &lrbt_cb_table_purse_deletion; + break; + case TALER_EXCHANGEDB_RT_WITHDRAW: + XPREPARE ("select_above_serial_by_table_withdraw", + "SELECT" + " withdraw_id" + ",planchets_h" + ",execution_date" + ",amount_with_fee" + ",reserve_pub" + ",reserve_sig" + ",max_age" + ",noreveal_index" + ",selected_h" + ",blinding_seed" + ",cs_r_values" + ",cs_r_choices" + ",denom_serials" + ",denom_sigs" + " FROM withdraw" + " WHERE withdraw_id > $1" + " ORDER BY withdraw_id ASC;"); + rh = &lrbt_cb_table_withdraw; + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_MEASURES: + XPREPARE ("select_above_serial_by_table_legitimization_measures", + "SELECT" + " legitimization_measure_serial_id AS serial" + ",access_token" + ",start_time" + ",jmeasures::TEXT" + ",display_priority" + " FROM legitimization_measures" + " WHERE legitimization_measure_serial_id > $1" + " ORDER BY legitimization_measure_serial_id ASC;"); + rh = &lrbt_cb_table_legitimization_measures; + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_OUTCOMES: + XPREPARE ("select_above_serial_by_table_legitimization_outcomes", + "SELECT" + " outcome_serial_id AS serial" + ",h_payto" + ",decision_time" + ",expiration_time" + ",jproperties::TEXT" + ",to_investigate" + ",jnew_rules::TEXT" + " FROM legitimization_outcomes" + " WHERE outcome_serial_id > $1" + " ORDER BY outcome_serial_id ASC;"); + rh = &lrbt_cb_table_legitimization_outcomes; + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES: + XPREPARE ("select_above_serial_by_table_legitimization_processes", + "SELECT" + " legitimization_process_serial_id AS serial" + ",h_payto" + ",start_time" + ",expiration_time" + ",legitimization_measure_serial_id" + ",measure_index" + ",provider_name" + ",provider_user_id" + ",provider_legitimization_id" + ",redirect_url" + " FROM legitimization_processes" + " WHERE legitimization_process_serial_id > $1" + " ORDER BY legitimization_process_serial_id ASC;"); + rh = &lrbt_cb_table_legitimization_processes; + break; + case TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES: + XPREPARE ("select_above_serial_by_table_kyc_attributes", + "SELECT" + " kyc_attributes_serial_id" + ",h_payto" + ",legitimization_serial" + ",collection_time" + ",expiration_time" + ",trigger_outcome_serial" + ",encrypted_attributes" + " FROM kyc_attributes" + " WHERE kyc_attributes_serial_id > $1" + " ORDER BY kyc_attributes_serial_id ASC;"); + rh = &lrbt_cb_table_kyc_attributes; + break; + case TALER_EXCHANGEDB_RT_AML_HISTORY: + XPREPARE ("select_above_serial_by_table_aml_history", + "SELECT" + " aml_history_serial_id" + ",h_payto" + ",outcome_serial_id" + ",justification" + ",decider_pub" + ",decider_sig" + " FROM aml_history" + " WHERE aml_history_serial_id > $1" + " ORDER BY aml_history_serial_id ASC;"); + rh = &lrbt_cb_table_aml_history; + break; + case TALER_EXCHANGEDB_RT_KYC_EVENTS: + XPREPARE ("select_above_serial_by_table_kyc_events", + "SELECT" + " kyc_event_serial_id AS serial" + ",event_timestamp" + ",event_type" + " FROM kyc_events" + " WHERE kyc_event_serial_id > $1" + " ORDER BY kyc_event_serial_id ASC;"); + rh = &lrbt_cb_table_kyc_events; + break; + } + if (NULL == rh) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + statement, + params, + rh, + &ctx); + if (qs < 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to run `%s'\n", + statement); + return qs; + } + if (ctx.error) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} + + +#undef XPREPARE + +/* end of pg_lookup_records_by_table.c */ diff --git a/src/exchangedb/lookup_rules_by_access_token.c b/src/exchangedb/lookup_rules_by_access_token.c @@ -0,0 +1,68 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_rules_by_access_token.c + * @brief Implementation of the lookup_rules_by_access_token function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_rules_by_access_token.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_rules_by_access_token (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + json_t **jnew_rules, + uint64_t *rowid) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ( + "jnew_rules", + jnew_rules), + NULL), + GNUNET_PQ_result_spec_uint64 ( + "row_id", + rowid), + GNUNET_PQ_result_spec_end + }; + + *jnew_rules = NULL; + PREPARE (ctx, + "lookup_rules_by_access_token", + "SELECT" + " jnew_rules::TEXT" + ",outcome_serial_id AS row_id" + " FROM legitimization_outcomes" + " WHERE h_payto=$1" + " AND is_active" + " ORDER BY expiration_time DESC," + " outcome_serial_id DESC" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "lookup_rules_by_access_token", + params, + rs); +} diff --git a/src/exchangedb/lookup_serial_by_table.c b/src/exchangedb/lookup_serial_by_table.c @@ -0,0 +1,466 @@ +/* + This file is part of TALER + Copyright (C) 2022-2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_lookup_serial_by_table.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_serial_by_table.h" +#include "pg_helper.h" + + +/** + * Assign statement to @a n and PREPARE + * @a sql under name @a n. + */ +#define XPREPARE(n,sql) \ + statement = n; \ + PREPARE (ctx, n, sql); + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_serial_by_table (struct EXCHANGEDB_PostgresContext *ctx, + enum TALER_EXCHANGEDB_ReplicatedTable table, + uint64_t *serial) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial", + serial), + GNUNET_PQ_result_spec_end + }; + const char *statement = NULL; + + switch (table) + { + case TALER_EXCHANGEDB_RT_DENOMINATIONS: + XPREPARE ("select_serial_by_table_denominations", + "SELECT" + " denominations_serial AS serial" + " FROM denominations" + " ORDER BY denominations_serial DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS: + XPREPARE ("select_serial_by_table_denomination_revocations", + "SELECT" + " denom_revocations_serial_id AS serial" + " FROM denomination_revocations" + " ORDER BY denom_revocations_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_WIRE_TARGETS: + XPREPARE ("select_serial_by_table_wire_targets", + "SELECT" + " wire_target_serial_id AS serial" + " FROM wire_targets" + " ORDER BY wire_target_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_KYC_TARGETS: + XPREPARE ("select_serial_by_table_kyc_targets", + "SELECT" + " kyc_target_serial_id AS serial" + " FROM kyc_targets" + " ORDER BY kyc_target_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_RESERVES: + XPREPARE ("select_serial_by_table_reserves", + "SELECT" + " reserve_uuid AS serial" + " FROM reserves" + " ORDER BY reserve_uuid DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_RESERVES_IN: + XPREPARE ("select_serial_by_table_reserves_in", + "SELECT" + " reserve_in_serial_id AS serial" + " FROM reserves_in" + " ORDER BY reserve_in_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_KYCAUTHS_IN: + XPREPARE ("select_serial_by_table_kycauths_in", + "SELECT" + " kycauth_in_serial_id AS serial" + " FROM kycauths_in" + " ORDER BY kycauths_in_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_RESERVES_CLOSE: + XPREPARE ("select_serial_by_table_reserves_close", + "SELECT" + " close_uuid AS serial" + " FROM reserves_close" + " ORDER BY close_uuid DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS: + XPREPARE ("select_serial_by_table_reserves_open_requests", + "SELECT" + " open_request_uuid AS serial" + " FROM reserves_open_requests" + " ORDER BY open_request_uuid DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS: + XPREPARE ("select_serial_by_table_reserves_open_deposits", + "SELECT" + " reserve_open_deposit_uuid AS serial" + " FROM reserves_open_deposits" + " ORDER BY reserve_open_deposit_uuid DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_AUDITORS: + XPREPARE ("select_serial_by_table_auditors", + "SELECT" + " auditor_uuid AS serial" + " FROM auditors" + " ORDER BY auditor_uuid DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS: + XPREPARE ("select_serial_by_table_auditor_denom_sigs", + "SELECT" + " auditor_denom_serial AS serial" + " FROM auditor_denom_sigs" + " ORDER BY auditor_denom_serial DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS: + XPREPARE ("select_serial_by_table_exchange_sign_keys", + "SELECT" + " esk_serial AS serial" + " FROM exchange_sign_keys" + " ORDER BY esk_serial DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS: + XPREPARE ("select_serial_by_table_signkey_revocations", + "SELECT" + " signkey_revocations_serial_id AS serial" + " FROM signkey_revocations" + " ORDER BY signkey_revocations_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_KNOWN_COINS: + XPREPARE ("select_serial_by_table_known_coins", + "SELECT" + " known_coin_id AS serial" + " FROM known_coins" + " ORDER BY known_coin_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_REFRESH: + XPREPARE ("select_serial_by_table_refresh", + "SELECT" + " refresh_id AS serial" + " FROM refresh" + " ORDER BY refresh_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_BATCH_DEPOSITS: + XPREPARE ("select_serial_by_table_batch_deposits", + "SELECT" + " batch_deposit_serial_id AS serial" + " FROM batch_deposits" + " ORDER BY batch_deposit_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_COIN_DEPOSITS: + XPREPARE ("select_serial_by_table_coin_deposits", + "SELECT" + " coin_deposit_serial_id AS serial" + " FROM coin_deposits" + " ORDER BY coin_deposit_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_REFUNDS: + XPREPARE ("select_serial_by_table_refunds", + "SELECT" + " refund_serial_id AS serial" + " FROM refunds" + " ORDER BY refund_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_WIRE_OUT: + XPREPARE ("select_serial_by_table_wire_out", + "SELECT" + " wireout_uuid AS serial" + " FROM wire_out" + " ORDER BY wireout_uuid DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING: + XPREPARE ("select_serial_by_table_aggregation_tracking", + "SELECT" + " aggregation_serial_id AS serial" + " FROM aggregation_tracking" + " ORDER BY aggregation_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_WIRE_FEE: + XPREPARE ("select_serial_by_table_wire_fee", + "SELECT" + " wire_fee_serial AS serial" + " FROM wire_fee" + " ORDER BY wire_fee_serial DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_GLOBAL_FEE: + XPREPARE ("select_serial_by_table_global_fee", + "SELECT" + " global_fee_serial AS serial" + " FROM global_fee" + " ORDER BY global_fee_serial DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_RECOUP: + XPREPARE ("select_serial_by_table_recoup", + "SELECT" + " recoup_uuid AS serial" + " FROM recoup" + " ORDER BY recoup_uuid DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_RECOUP_REFRESH: + XPREPARE ("select_serial_by_table_recoup_refresh", + "SELECT" + " recoup_refresh_uuid AS serial" + " FROM recoup_refresh" + " ORDER BY recoup_refresh_uuid DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_EXTENSIONS: + XPREPARE ("select_serial_by_table_extensions", + "SELECT" + " extension_id AS serial" + " FROM extensions" + " ORDER BY extension_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_POLICY_DETAILS: + XPREPARE ("select_serial_by_table_policy_details", + "SELECT" + " policy_details_serial_id AS serial" + " FROM policy_details" + " ORDER BY policy_details_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_POLICY_FULFILLMENTS: + XPREPARE ("select_serial_by_table_policy_fulfillments", + "SELECT" + " fulfillment_id AS serial" + " FROM policy_fulfillments" + " ORDER BY fulfillment_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_PURSE_REQUESTS: + XPREPARE ("select_serial_by_table_purse_requests", + "SELECT" + " purse_requests_serial_id AS serial" + " FROM purse_requests" + " ORDER BY purse_requests_serial_id DESC" + " LIMIT 1;") + break; + case TALER_EXCHANGEDB_RT_PURSE_DECISION: + XPREPARE ("select_serial_by_table_purse_decision", + "SELECT" + " purse_decision_serial_id AS serial" + " FROM purse_decision" + " ORDER BY purse_decision_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_PURSE_MERGES: + XPREPARE ("select_serial_by_table_purse_merges", + "SELECT" + " purse_merge_request_serial_id AS serial" + " FROM purse_merges" + " ORDER BY purse_merge_request_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_PURSE_DEPOSITS: + XPREPARE ("select_serial_by_table_purse_deposits", + "SELECT" + " purse_deposit_serial_id AS serial" + " FROM purse_deposits" + " ORDER BY purse_deposit_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_ACCOUNT_MERGES: + XPREPARE ("select_serial_by_table_account_merges", + "SELECT" + " account_merge_request_serial_id AS serial" + " FROM account_merges" + " ORDER BY account_merge_request_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_HISTORY_REQUESTS: + XPREPARE ("select_serial_by_table_history_requests", + "SELECT" + " history_request_serial_id AS serial" + " FROM history_requests" + " ORDER BY history_request_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_CLOSE_REQUESTS: + XPREPARE ("select_serial_by_table_close_requests", + "SELECT" + " close_request_serial_id AS serial" + " FROM close_requests" + " ORDER BY close_request_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_WADS_OUT: + XPREPARE ("select_serial_by_table_wads_out", + "SELECT" + " wad_out_serial_id AS serial" + " FROM wads_out" + " ORDER BY wad_out_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES: + XPREPARE ("select_serial_by_table_wads_out_entries", + "SELECT" + " wad_out_entry_serial_id AS serial" + " FROM wad_out_entries" + " ORDER BY wad_out_entry_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_WADS_IN: + XPREPARE ("select_serial_by_table_wads_in", + "SELECT" + " wad_in_serial_id AS serial" + " FROM wads_in" + " ORDER BY wad_in_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES: + XPREPARE ("select_serial_by_table_wads_in_entries", + "SELECT" + " wad_in_entry_serial_id AS serial" + " FROM wad_in_entries" + " ORDER BY wad_in_entry_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_PROFIT_DRAINS: + XPREPARE ("select_serial_by_table_profit_drains", + "SELECT" + " profit_drain_serial_id AS serial" + " FROM profit_drains" + " ORDER BY profit_drain_serial_id DESC" + " LIMIT 1;"); + statement = "select_serial_by_table_profit_drains"; + break; + case TALER_EXCHANGEDB_RT_AML_STAFF: + XPREPARE ("select_serial_by_table_aml_staff", + "SELECT" + " aml_staff_uuid AS serial" + " FROM aml_staff" + " ORDER BY aml_staff_uuid DESC" + " LIMIT 1;"); + statement = "select_serial_by_table_aml_staff"; + break; + case TALER_EXCHANGEDB_RT_PURSE_DELETION: + XPREPARE ("select_serial_by_table_purse_deletion", + "SELECT" + " purse_deletion_serial_id AS serial" + " FROM purse_deletion" + " ORDER BY purse_deletion_serial_id DESC" + " LIMIT 1;"); + statement = "select_serial_by_table_purse_deletion"; + break; + case TALER_EXCHANGEDB_RT_WITHDRAW: + XPREPARE ("select_serial_by_table_withdraw", + "SELECT" + " withdraw_id AS serial" + " FROM withdraw" + " ORDER BY withdraw_id DESC" + " LIMIT 1;"); + statement = "select_serial_by_table_withdraw"; + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_MEASURES: + XPREPARE ("select_serial_by_table_legitimization_measures", + "SELECT" + " legitimization_measure_serial_id AS serial" + " FROM legitimization_measures" + " ORDER BY legitimization_measure_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_OUTCOMES: + XPREPARE ("select_serial_by_table_legitimization_outcomes", + "SELECT" + " outcome_serial_id AS serial" + " FROM legitimization_outcomes" + " ORDER BY outcome_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES: + XPREPARE ("select_serial_by_table_legitimization_processes", + "SELECT" + " legitimization_process_serial_id AS serial" + " FROM legitimization_processes" + " ORDER BY legitimization_process_serial_id DESC" + " LIMIT 1;"); + break; + case TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES: + XPREPARE ("select_serial_by_table_kyc_attributes", + "SELECT" + " kyc_attributes_serial_id AS serial" + " FROM kyc_attributes" + " ORDER BY kyc_attributes_serial_id DESC" + " LIMIT 1;"); + statement = "select_serial_by_table_kyc_attributes"; + break; + case TALER_EXCHANGEDB_RT_AML_HISTORY: + XPREPARE ("select_serial_by_table_aml_history", + "SELECT" + " aml_history_serial_id AS serial" + " FROM aml_history" + " ORDER BY aml_history_serial_id DESC" + " LIMIT 1;"); + statement = "select_serial_by_table_aml_history"; + break; + case TALER_EXCHANGEDB_RT_KYC_EVENTS: + XPREPARE ("select_serial_by_table_kyc_events", + "SELECT" + " kyc_event_serial_id AS serial" + " FROM kyc_events" + " ORDER BY kyc_event_serial_id DESC" + " LIMIT 1;"); + break; + } + if (NULL == statement) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + statement, + params, + rs); +} + + +#undef XPREPARE diff --git a/src/exchangedb/lookup_signing_key.c b/src/exchangedb/lookup_signing_key.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_signing_key.c + * @brief Implementation of the lookup_signing_key function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_signing_key.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_signing_key (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct TALER_EXCHANGEDB_SignkeyMetaData *meta) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (exchange_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + 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), + GNUNET_PQ_result_spec_end + }; + + + PREPARE (ctx, + "lookup_signing_key", + "SELECT" + " valid_from" + ",expire_sign" + ",expire_legal" + " FROM exchange_sign_keys" + " WHERE exchange_pub=$1"); + + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "lookup_signing_key", + params, + rs); +} diff --git a/src/exchangedb/lookup_signkey_revocation.c b/src/exchangedb/lookup_signkey_revocation.c @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_signkey_revocation.c + * @brief Implementation of the lookup_signkey_revocation function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_signkey_revocation.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_signkey_revocation (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (exchange_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + master_sig), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_signkey_revocation", + "SELECT " + " master_sig" + " FROM signkey_revocations" + " WHERE esk_serial=" + " (SELECT esk_serial" + " FROM exchange_sign_keys" + " WHERE exchange_pub=$1);"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "lookup_signkey_revocation", + params, + rs); +} diff --git a/src/exchangedb/lookup_transfer_by_deposit.c b/src/exchangedb/lookup_transfer_by_deposit.c @@ -0,0 +1,222 @@ +/* + This file is part of TALER + Copyright (C) 2022-2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_transfer_by_deposit.c + * @brief Implementation of the lookup_transfer_by_deposit function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_transfer_by_deposit.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_transfer_by_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant_pub, + bool *pending, + struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Timestamp *exec_time, + struct TALER_Amount *amount_with_fee, + struct TALER_Amount *deposit_fee, + struct TALER_EXCHANGEDB_KycStatus *kyc, + union TALER_AccountPublicKeyP *account_pub) +{ + enum GNUNET_DB_QueryStatus qs; + 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_pub), + GNUNET_PQ_query_param_end + }; + struct TALER_FullPayto payto_uri; + struct TALER_WireSaltP wire_salt; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("wtid_raw", + wtid), + GNUNET_PQ_result_spec_auto_from_type ("wire_salt", + &wire_salt), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri.full_payto), + GNUNET_PQ_result_spec_timestamp ("execution_date", + exec_time), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + deposit_fee), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("target_pub", + account_pub), + NULL), + GNUNET_PQ_result_spec_end + }; + + memset (kyc, + 0, + sizeof (*kyc)); + /* check if the aggregation record exists and get it */ + PREPARE (ctx, + "lookup_deposit_wtid", + "SELECT" + " atr.wtid_raw" + ",wire_out.execution_date" + ",cdep.amount_with_fee" + ",bdep.wire_salt" + ",wt.payto_uri" + ",kt.target_pub" + ",denom.fee_deposit" + " FROM coin_deposits cdep" + " JOIN batch_deposits bdep" + " USING (batch_deposit_serial_id)" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + /* kyc_targets might not match; then target_pub will be NULL */ + " LEFT JOIN kyc_targets kt" + " USING (h_normalized_payto)" + " JOIN aggregation_tracking atr" + " ON (cdep.batch_deposit_serial_id = atr.batch_deposit_serial_id)" + " JOIN known_coins kc" + " ON (kc.coin_pub = cdep.coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " JOIN wire_out" + " USING (wtid_raw)" + " WHERE cdep.coin_pub=$1" + " AND bdep.merchant_pub=$3" + " AND bdep.h_contract_terms=$2"); + /* NOTE: above query might be more efficient if we computed the shard + from the merchant_pub and included that in the query */ + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "lookup_deposit_wtid", + params, + rs); + if (0 > qs) + return qs; + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) + { + struct TALER_MerchantWireHashP wh; + + TALER_merchant_wire_signature_hash (payto_uri, + &wire_salt, + &wh); + if (0 == + GNUNET_memcmp (&wh, + h_wire)) + { + *pending = false; + kyc->ok = true; + GNUNET_PQ_cleanup_result (rs); + return qs; + } + qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + GNUNET_PQ_cleanup_result (rs); + } + *pending = true; + memset (wtid, + 0, + sizeof (*wtid)); + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "lookup_deposit_wtid returned 0 matching rows\n"); + { + /* Check if transaction exists in deposits, so that we just + do not have a WTID yet. In that case, return without wtid + (by setting 'pending' true). */ + struct GNUNET_PQ_ResultSpec rs2[] = { + GNUNET_PQ_result_spec_auto_from_type ("wire_salt", + &wire_salt), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri.full_payto), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + deposit_fee), + GNUNET_PQ_result_spec_timestamp ("wire_deadline", + exec_time), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ("legitimization_requirement_serial_id", + &kyc->requirement_row), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("target_pub", + account_pub), + NULL), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "get_deposit_without_wtid", + "SELECT" + " bdep.wire_salt" + ",wt.payto_uri" + ",cdep.amount_with_fee" + ",denom.fee_deposit" + ",bdep.wire_deadline" + ",agt.legitimization_requirement_serial_id" + ",kt.target_pub" + " FROM coin_deposits cdep" + " JOIN batch_deposits bdep" + " USING (batch_deposit_serial_id)" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + /* kyc_targets might not match; then target_pub will be NULL */ + " LEFT JOIN kyc_targets kt" + " USING (h_normalized_payto)" + " JOIN known_coins kc" + " ON (kc.coin_pub = cdep.coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " LEFT JOIN aggregation_transient agt " + " ON ( (bdep.wire_target_h_payto = agt.wire_target_h_payto) AND" + " (bdep.merchant_pub = agt.merchant_pub) )" + " WHERE cdep.coin_pub=$1" + " AND bdep.merchant_pub=$3" + " AND bdep.h_contract_terms=$2" + " LIMIT 1;"); + /* NOTE: above query might be more efficient if we computed the shard + from the merchant_pub and included that in the query */ + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_deposit_without_wtid", + params, + rs2); + if (0 > qs) + return qs; + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) + { + struct TALER_MerchantWireHashP wh; + + TALER_merchant_wire_signature_hash (payto_uri, + &wire_salt, + &wh); + if (0 != + GNUNET_memcmp (&wh, + h_wire)) + { + GNUNET_PQ_cleanup_result (rs2); + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + GNUNET_PQ_cleanup_result (rs2); + if (0 == kyc->requirement_row) + kyc->ok = true; /* technically: unknown */ + } + return qs; + } +} diff --git a/src/exchangedb/lookup_wire_fee_by_time.c b/src/exchangedb/lookup_wire_fee_by_time.c @@ -0,0 +1,154 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_wire_fee_by_time.c + * @brief Implementation of the lookup_wire_fee_by_time function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_wire_fee_by_time.h" +#include "pg_helper.h" + + +/** + * Closure for #wire_fee_by_time_helper() + */ +struct WireFeeLookupContext +{ + + /** + * Set to the wire fees. Set to invalid if fees conflict over + * the given time period. + */ + struct TALER_WireFeeSet *fees; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; +}; + + +/** + * Helper function for #EXCHANGEDB_lookup_wire_fee_by_time(). + * Calls the callback with the wire fee structure. + * + * @param cls a `struct WireFeeLookupContext` + * @param result db results + * @param num_results number of results in @a result + */ +static void +wire_fee_by_time_helper (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct WireFeeLookupContext *wlc = cls; + struct EXCHANGEDB_PostgresContext *ctx = wlc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_WireFeeSet fs; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee", + &fs.wire), + TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", + &fs.closing), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + /* invalidate */ + memset (wlc->fees, + 0, + sizeof (struct TALER_WireFeeSet)); + return; + } + if (0 == i) + { + *wlc->fees = fs; + continue; + } + if (0 != + TALER_wire_fee_set_cmp (&fs, + wlc->fees)) + { + /* invalidate */ + memset (wlc->fees, + 0, + sizeof (struct TALER_WireFeeSet)); + return; + } + } +} + + +/** + * Lookup information about known wire fees. Finds all applicable + * fees in the given range. If they are identical, returns the + * respective @a fees. If any of the fees + * differ between @a start_time and @a end_time, the transaction + * succeeds BUT returns an invalid amount for both fees. + * + * @param cls closure + * @param wire_method the wire method to lookup fees for + * @param start_time starting time of fee + * @param end_time end time of fee + * @param[out] fees wire fees for that time period; if + * different fees exists within this time + * period, an 'invalid' amount is returned. + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_wire_fee_by_time (struct EXCHANGEDB_PostgresContext *ctx, + const char *wire_method, + struct GNUNET_TIME_Timestamp start_time, + struct GNUNET_TIME_Timestamp end_time, + struct TALER_WireFeeSet *fees) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (wire_method), + GNUNET_PQ_query_param_timestamp (&start_time), + GNUNET_PQ_query_param_timestamp (&end_time), + GNUNET_PQ_query_param_end + }; + struct WireFeeLookupContext wlc = { + .fees = fees, + .ctx = ctx + }; + + PREPARE (ctx, + "lookup_wire_fee_by_time", + "SELECT" + " wire_fee" + ",closing_fee" + " FROM wire_fee" + " WHERE wire_method=$1" + " AND end_date > $2" + " AND start_date < $3;"); + return GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "lookup_wire_fee_by_time", + params, + &wire_fee_by_time_helper, + &wlc); +} diff --git a/src/exchangedb/lookup_wire_timestamp.c b/src/exchangedb/lookup_wire_timestamp.c @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_wire_timestamp.c + * @brief Implementation of the lookup_wire_timestamp function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_wire_timestamp.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_wire_timestamp (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + struct GNUNET_TIME_Timestamp *last_date) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (payto_uri.full_payto), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_timestamp ("last_change", + last_date), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "lookup_wire_timestamp", + "SELECT" + " last_change" + " FROM wire_accounts" + " WHERE payto_uri=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "lookup_wire_timestamp", + params, + rs); +} diff --git a/src/exchangedb/lookup_wire_transfer.c b/src/exchangedb/lookup_wire_transfer.c @@ -0,0 +1,186 @@ +/* + This file is part of TALER + Copyright (C) 2022-2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/lookup_wire_transfer.c + * @brief Implementation of the lookup_wire_transfer function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "lookup_wire_transfer.h" +#include "pg_helper.h" + +/** + * Closure for #handle_wt_result. + */ +struct WireTransferResultContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AggregationDataCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #EXCHANGEDB_lookup_wire_transfer(). + * + * @param cls closure of type `struct WireTransferResultContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_wt_result (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct WireTransferResultContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct TALER_PrivateContractHashP h_contract_terms; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_FullPaytoHashP h_payto; + struct TALER_MerchantPublicKeyP merchant_pub; + struct GNUNET_TIME_Timestamp exec_time; + struct TALER_Amount amount_with_fee; + struct TALER_Amount deposit_fee; + struct TALER_DenominationPublicKey denom_pub; + struct TALER_FullPayto payto_uri; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("aggregation_serial_id", + &rowid), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &h_contract_terms), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri.full_payto), + GNUNET_PQ_result_spec_auto_from_type ("wire_target_h_payto", + &h_payto), + 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), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &exec_time), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + &deposit_fee), + 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, + rowid, + &merchant_pub, + payto_uri, + &h_payto, + exec_time, + &h_contract_terms, + &denom_pub, + &coin_pub, + &amount_with_fee, + &deposit_fee); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_wire_transfer (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_WireTransferIdentifierRawP *wtid, + TALER_EXCHANGEDB_AggregationDataCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_end + }; + struct WireTransferResultContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "lookup_transactions", + "SELECT" + " aggregation_serial_id" + ",bdep.h_contract_terms" + ",payto_uri" + ",wt.wire_target_h_payto" + ",kc.coin_pub" + ",bdep.merchant_pub" + ",wire_out.execution_date" + ",cdep.amount_with_fee" + ",denom.fee_deposit" + ",denom.denom_pub" + " FROM aggregation_tracking" + " JOIN batch_deposits bdep" + " USING (batch_deposit_serial_id)" + " JOIN coin_deposits cdep" + " USING (batch_deposit_serial_id)" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " JOIN known_coins kc" + " USING (coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " JOIN wire_out" + " USING (wtid_raw)" + " WHERE wtid_raw=$1;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "lookup_transactions", + params, + &handle_wt_result, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/mark_refresh_reveal_success.c b/src/exchangedb/mark_refresh_reveal_success.c @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/mark_refresh_reveal_success.c + * @brief Implementation of the mark_refresh_reveal_success function for Postgres + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "mark_refresh_reveal_success.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_mark_refresh_reveal_success (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_RefreshCommitmentP *rc) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (rc), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "mark_refresh_reveal_success", + "UPDATE refresh" + " SET revealed=true" + " WHERE rc = $1"); + + return GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "mark_refresh_reveal_success", + params); +} +\ No newline at end of file diff --git a/src/exchangedb/persist_kyc_attributes.c b/src/exchangedb/persist_kyc_attributes.c @@ -0,0 +1,105 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/persist_kyc_attributes.c + * @brief Implementation of the persist_kyc_attributes function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "persist_kyc_attributes.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_persist_kyc_attributes (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t process_row, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_name, + const char *provider_account_id, + const char *provider_legitimization_id, + uint32_t birthday, + struct GNUNET_TIME_Absolute expiration_time, + const char *form_name, + size_t enc_attributes_size, + const void *enc_attributes) +{ + struct GNUNET_TIME_Timestamp collection_time + = GNUNET_TIME_timestamp_get (); + struct GNUNET_TIME_Timestamp expiration + = GNUNET_TIME_absolute_to_timestamp (expiration_time); + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = *h_payto + }; + char *kyc_completed_notify_s + = GNUNET_PQ_get_event_notify_channel (&rep.header); + struct GNUNET_PQ_QueryParam params[] = { + (0 == process_row) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_uint64 (&process_row), + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_uint32 (&birthday), + GNUNET_PQ_query_param_string (provider_name), + (NULL == provider_account_id) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (provider_account_id), + (NULL == provider_legitimization_id) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (provider_legitimization_id), + GNUNET_PQ_query_param_timestamp (&collection_time), + GNUNET_PQ_query_param_absolute_time (&expiration_time), + GNUNET_PQ_query_param_timestamp (&expiration), + (NULL == enc_attributes) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_fixed_size (enc_attributes, + enc_attributes_size), + GNUNET_PQ_query_param_string (kyc_completed_notify_s), + (NULL == form_name) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (form_name), + GNUNET_PQ_query_param_end + }; + bool ok; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("out_ok", + &ok), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Inserting KYC attributes, wake up on %s\n", + kyc_completed_notify_s); + GNUNET_break (NULL != h_payto); + PREPARE (ctx, + "persist_kyc_attributes", + "SELECT " + " out_ok" + " FROM exchange_do_persist_kyc_attributes " + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "persist_kyc_attributes", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + GNUNET_free (kyc_completed_notify_s); + GNUNET_PQ_event_do_poll (ctx->conn); + return qs; +} diff --git a/src/exchangedb/persist_policy_details.c b/src/exchangedb/persist_policy_details.c @@ -0,0 +1,76 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/persist_policy_details.c + * @brief Implementation of the persist_policy_details function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "persist_policy_details.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_persist_policy_details (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PolicyDetails *details, + uint64_t *policy_details_serial_id, + struct TALER_Amount *accumulated_total, + enum TALER_PolicyFulfillmentState *fulfillment_state) +{ + 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 (ctx->conn, + &details->commitment), + TALER_PQ_query_param_amount (ctx->conn, + &details->accumulated_total), + TALER_PQ_query_param_amount (ctx->conn, + &details->policy_fee), + TALER_PQ_query_param_amount (ctx->conn, + &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 + }; + + PREPARE (ctx, + "call_insert_or_update_policy_details", + "SELECT" + " out_policy_details_serial_id AS policy_details_serial_id" + ",out_accumulated_total AS accumulated_total" + ",out_fulfillment_state AS fulfillment_state" + " FROM exchange_do_insert_or_update_policy_details" + "($1, $2, $3, $4, $5, $6, $7, $8, $9);"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "call_insert_or_update_policy_details", + params, + rs); +} diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c @@ -27,212 +27,212 @@ #include <poll.h> #include <pthread.h> #include <libpq-fe.h> -#include "pg_abort_shard.h" -#include "pg_activate_signing_key.h" -#include "pg_add_denomination_key.h" -#include "pg_add_policy_fulfillment_proof.h" -#include "pg_aggregate.h" -#include "pg_batch_ensure_coin_known.h" -#include "pg_begin_revolving_shard.h" -#include "pg_begin_shard.h" -#include "pg_clear_aml_lock.h" -#include "pg_commit.h" -#include "pg_complete_shard.h" -#include "pg_compute_shard.h" -#include "pg_count_known_coins.h" -#include "pg_create_aggregation_transient.h" -#include "pg_create_tables.h" -#include "pg_delete_aggregation_transient.h" -#include "pg_delete_shard_locks.h" -#include "pg_disable_rules.h" -#include "pg_do_withdraw.h" -#include "pg_do_check_deposit_idempotent.h" -#include "pg_do_deposit.h" -#include "pg_do_purse_delete.h" -#include "pg_do_purse_deposit.h" -#include "pg_do_purse_merge.h" -#include "pg_do_recoup.h" -#include "pg_do_recoup_refresh.h" -#include "pg_do_refresh.h" -#include "pg_do_refund.h" -#include "pg_do_reserve_open.h" -#include "pg_do_reserve_purse.h" -#include "pg_drain_kyc_alert.h" -#include "pg_drop_tables.h" -#include "pg_enable_rules.h" -#include "pg_ensure_coin_known.h" -#include "pg_event_listen.h" -#include "pg_event_listen_cancel.h" -#include "pg_event_notify.h" -#include "pg_expire_purse.h" -#include "pg_find_aggregation_transient.h" -#include "pg_gc.h" -#include "pg_get_withdraw.h" -#include "pg_get_coin_denomination.h" -#include "pg_get_coin_transactions.h" -#include "pg_get_denomination_info.h" -#include "pg_get_denomination_by_serial.h" -#include "pg_get_denomination_revocation.h" -#include "pg_get_drain_profit.h" -#include "pg_get_expired_reserves.h" -#include "pg_get_extension_manifest.h" -#include "pg_get_global_fee.h" -#include "pg_get_global_fees.h" -#include "pg_get_known_coin.h" -#include "pg_get_kyc_rules.h" -#include "pg_get_old_coin_by_h_blind.h" -#include "pg_get_pending_kyc_requirement_process.h" -#include "pg_get_policy_details.h" -#include "pg_get_purse_deposit.h" -#include "pg_get_purse_request.h" -#include "pg_get_ready_deposit.h" -#include "pg_get_refresh.h" -#include "pg_get_reserve_balance.h" -#include "pg_get_reserve_by_h_planchets.h" -#include "pg_get_reserve_history.h" -#include "pg_get_signature_for_known_coin.h" -#include "pg_get_unfinished_close_requests.h" -#include "pg_get_wire_accounts.h" -#include "pg_get_wire_fee.h" -#include "pg_get_wire_fees.h" -#include "pg_get_wire_hash_for_contract.h" -#include "pg_have_deposit2.h" +#include "abort_shard.h" +#include "activate_signing_key.h" +#include "add_denomination_key.h" +#include "add_policy_fulfillment_proof.h" +#include "aggregate.h" +#include "batch_ensure_coin_known.h" +#include "begin_revolving_shard.h" +#include "begin_shard.h" +#include "clear_aml_lock.h" +#include "commit.h" +#include "complete_shard.h" +#include "compute_shard.h" +#include "count_known_coins.h" +#include "create_aggregation_transient.h" +#include "create_tables.h" +#include "delete_aggregation_transient.h" +#include "delete_shard_locks.h" +#include "disable_rules.h" +#include "do_withdraw.h" +#include "do_check_deposit_idempotent.h" +#include "do_deposit.h" +#include "do_purse_delete.h" +#include "do_purse_deposit.h" +#include "do_purse_merge.h" +#include "do_recoup.h" +#include "do_recoup_refresh.h" +#include "do_refresh.h" +#include "do_refund.h" +#include "do_reserve_open.h" +#include "do_reserve_purse.h" +#include "drain_kyc_alert.h" +#include "drop_tables.h" +#include "enable_rules.h" +#include "ensure_coin_known.h" +#include "event_listen.h" +#include "event_listen_cancel.h" +#include "event_notify.h" +#include "expire_purse.h" +#include "find_aggregation_transient.h" +#include "gc.h" +#include "get_withdraw.h" +#include "get_coin_denomination.h" +#include "get_coin_transactions.h" +#include "get_denomination_info.h" +#include "get_denomination_by_serial.h" +#include "get_denomination_revocation.h" +#include "get_drain_profit.h" +#include "get_expired_reserves.h" +#include "get_extension_manifest.h" +#include "get_global_fee.h" +#include "get_global_fees.h" +#include "get_known_coin.h" +#include "get_kyc_rules.h" +#include "get_old_coin_by_h_blind.h" +#include "get_pending_kyc_requirement_process.h" +#include "get_policy_details.h" +#include "get_purse_deposit.h" +#include "get_purse_request.h" +#include "get_ready_deposit.h" +#include "get_refresh.h" +#include "get_reserve_balance.h" +#include "get_reserve_by_h_planchets.h" +#include "get_reserve_history.h" +#include "get_signature_for_known_coin.h" +#include "get_unfinished_close_requests.h" +#include "get_wire_accounts.h" +#include "get_wire_fee.h" +#include "get_wire_fees.h" +#include "get_wire_hash_for_contract.h" +#include "have_deposit2.h" #include "pg_helper.h" -#include "pg_inject_auditor_triggers.h" -#include "pg_insert_active_legitimization_measure.h" -#include "pg_insert_aml_decision.h" -#include "pg_insert_aml_officer.h" -#include "pg_insert_aml_program_failure.h" -#include "pg_insert_auditor.h" -#include "pg_insert_auditor_denom_sig.h" -#include "pg_insert_close_request.h" -#include "pg_insert_contract.h" -#include "pg_insert_denomination_info.h" -#include "pg_insert_denomination_revocation.h" -#include "pg_insert_drain_profit.h" -#include "pg_insert_global_fee.h" -#include "pg_insert_kyc_failure.h" -#include "pg_insert_kyc_requirement_process.h" -#include "pg_insert_partner.h" -#include "pg_insert_purse_request.h" -#include "pg_insert_records_by_table.h" -#include "pg_insert_refund.h" -#include "pg_insert_reserve_closed.h" -#include "pg_insert_reserve_open_deposit.h" -#include "pg_insert_sanction_list_hit.h" -#include "pg_insert_signkey_revocation.h" -#include "pg_insert_successor_measure.h" -#include "pg_insert_wire.h" -#include "pg_insert_wire_fee.h" -#include "pg_iterate_active_auditors.h" -#include "pg_iterate_active_signkeys.h" -#include "pg_iterate_auditor_denominations.h" -#include "pg_iterate_denomination_info.h" -#include "pg_iterate_denominations.h" -#include "pg_iterate_kyc_reference.h" -#include "pg_iterate_reserve_close_info.h" -#include "pg_kyc_provider_account_lookup.h" -#include "pg_kycauth_in_insert.h" -#include "pg_lookup_active_legitimization.h" -#include "pg_lookup_aml_file_number.h" -#include "pg_lookup_aml_history.h" -#include "pg_lookup_aml_officer.h" -#include "pg_lookup_auditor_status.h" -#include "pg_lookup_auditor_timestamp.h" -#include "pg_lookup_completed_legitimization.h" -#include "pg_lookup_denomination_key.h" -#include "pg_lookup_global_fee_by_time.h" -#include "pg_lookup_h_payto_by_access_token.h" -#include "pg_lookup_kyc_history.h" -#include "pg_lookup_kyc_process_by_account.h" -#include "pg_lookup_kyc_requirement_by_row.h" -#include "pg_lookup_kyc_status_by_token.h" -#include "pg_lookup_pending_legitimization.h" -#include "pg_lookup_records_by_table.h" -#include "pg_lookup_rules_by_access_token.h" -#include "pg_lookup_serial_by_table.h" -#include "pg_lookup_signing_key.h" -#include "pg_lookup_signkey_revocation.h" -#include "pg_lookup_transfer_by_deposit.h" -#include "pg_lookup_wire_fee_by_time.h" -#include "pg_lookup_wire_timestamp.h" -#include "pg_lookup_wire_transfer.h" -#include "pg_mark_refresh_reveal_success.h" -#include "pg_persist_kyc_attributes.h" -#include "pg_persist_policy_details.h" -#include "pg_preflight.h" -#include "pg_profit_drains_get_pending.h" -#include "pg_profit_drains_set_finished.h" -#include "pg_release_revolving_shard.h" -#include "pg_reserves_get.h" -#include "pg_reserves_get_origin.h" -#include "pg_reserves_in_insert.h" -#include "pg_reserves_update.h" -#include "pg_rollback.h" -#include "pg_select_account_merges_above_serial_id.h" -#include "pg_select_aggregation_amounts_for_kyc_check.h" -#include "pg_select_aggregation_transient.h" -#include "pg_select_aggregations_above_serial.h" -#include "pg_select_all_kyc_attributes.h" -#include "pg_select_all_purse_decisions_above_serial_id.h" -#include "pg_select_all_purse_deletions_above_serial_id.h" -#include "pg_select_aml_attributes.h" -#include "pg_select_aml_decisions.h" -#include "pg_select_aml_measures.h" -#include "pg_select_aml_statistics.h" -#include "pg_select_auditor_denom_sig.h" -#include "pg_select_batch_deposits_missing_wire.h" -#include "pg_select_coin_deposits_above_serial_id.h" -#include "pg_select_contract.h" -#include "pg_select_contract_by_purse.h" -#include "pg_select_deposit_amounts_for_kyc_check.h" -#include "pg_select_exchange_credit_transfers.h" -#include "pg_select_exchange_debit_transfers.h" -#include "pg_select_exchange_kycauth_transfers.h" -#include "pg_select_kyc_accounts.h" -#include "pg_select_kyc_attributes.h" -#include "pg_select_merge_amounts_for_kyc_check.h" -#include "pg_select_purse.h" -#include "pg_select_purse_by_merge_pub.h" -#include "pg_select_purse_decisions_above_serial_id.h" -#include "pg_select_purse_deposits_above_serial_id.h" -#include "pg_select_purse_deposits_by_purse.h" -#include "pg_select_purse_merge.h" -#include "pg_select_purse_merges_above_serial_id.h" -#include "pg_select_purse_requests_above_serial_id.h" -#include "pg_select_recoup_above_serial_id.h" -#include "pg_select_recoup_refresh_above_serial_id.h" -#include "pg_select_refreshes_above_serial_id.h" -#include "pg_select_refunds_above_serial_id.h" -#include "pg_select_refunds_by_coin.h" -#include "pg_select_reserve_close_info.h" -#include "pg_select_reserve_closed_above_serial_id.h" -#include "pg_select_reserve_open_above_serial_id.h" -#include "pg_select_reserves_in_above_serial_id.h" -#include "pg_select_reserves_in_above_serial_id_by_account.h" -#include "pg_select_wire_out_above_serial_id.h" -#include "pg_select_wire_out_above_serial_id_by_account.h" -#include "pg_select_withdraw_amounts_for_kyc_check.h" -#include "pg_select_withdrawals_above_serial_id.h" -#include "pg_set_aml_lock.h" -#include "pg_set_extension_manifest.h" -#include "pg_set_purse_balance.h" -#include "pg_start.h" -#include "pg_start_deferred_wire_out.h" -#include "pg_start_read_committed.h" -#include "pg_start_read_only.h" -#include "pg_store_wire_transfer_out.h" -#include "pg_test_aml_officer.h" -#include "pg_trigger_kyc_rule_for_account.h" -#include "pg_update_aggregation_transient.h" -#include "pg_update_auditor.h" -#include "pg_update_kyc_process_by_row.h" -#include "pg_update_wire.h" -#include "pg_wad_in_insert.h" -#include "pg_wire_prepare_data_get.h" -#include "pg_wire_prepare_data_insert.h" -#include "pg_wire_prepare_data_mark_failed.h" -#include "pg_wire_prepare_data_mark_finished.h" +#include "inject_auditor_triggers.h" +#include "insert_active_legitimization_measure.h" +#include "insert_aml_decision.h" +#include "insert_aml_officer.h" +#include "insert_aml_program_failure.h" +#include "insert_auditor.h" +#include "insert_auditor_denom_sig.h" +#include "insert_close_request.h" +#include "insert_contract.h" +#include "insert_denomination_info.h" +#include "insert_denomination_revocation.h" +#include "insert_drain_profit.h" +#include "insert_global_fee.h" +#include "insert_kyc_failure.h" +#include "insert_kyc_requirement_process.h" +#include "insert_partner.h" +#include "insert_purse_request.h" +#include "insert_records_by_table.h" +#include "insert_refund.h" +#include "insert_reserve_closed.h" +#include "insert_reserve_open_deposit.h" +#include "insert_sanction_list_hit.h" +#include "insert_signkey_revocation.h" +#include "insert_successor_measure.h" +#include "insert_wire.h" +#include "insert_wire_fee.h" +#include "iterate_active_auditors.h" +#include "iterate_active_signkeys.h" +#include "iterate_auditor_denominations.h" +#include "iterate_denomination_info.h" +#include "iterate_denominations.h" +#include "iterate_kyc_reference.h" +#include "iterate_reserve_close_info.h" +#include "kyc_provider_account_lookup.h" +#include "kycauth_in_insert.h" +#include "lookup_active_legitimization.h" +#include "lookup_aml_file_number.h" +#include "lookup_aml_history.h" +#include "lookup_aml_officer.h" +#include "lookup_auditor_status.h" +#include "lookup_auditor_timestamp.h" +#include "lookup_completed_legitimization.h" +#include "lookup_denomination_key.h" +#include "lookup_global_fee_by_time.h" +#include "lookup_h_payto_by_access_token.h" +#include "lookup_kyc_history.h" +#include "lookup_kyc_process_by_account.h" +#include "lookup_kyc_requirement_by_row.h" +#include "lookup_kyc_status_by_token.h" +#include "lookup_pending_legitimization.h" +#include "lookup_records_by_table.h" +#include "lookup_rules_by_access_token.h" +#include "lookup_serial_by_table.h" +#include "lookup_signing_key.h" +#include "lookup_signkey_revocation.h" +#include "lookup_transfer_by_deposit.h" +#include "lookup_wire_fee_by_time.h" +#include "lookup_wire_timestamp.h" +#include "lookup_wire_transfer.h" +#include "mark_refresh_reveal_success.h" +#include "persist_kyc_attributes.h" +#include "persist_policy_details.h" +#include "preflight.h" +#include "profit_drains_get_pending.h" +#include "profit_drains_set_finished.h" +#include "release_revolving_shard.h" +#include "reserves_get.h" +#include "reserves_get_origin.h" +#include "reserves_in_insert.h" +#include "reserves_update.h" +#include "rollback.h" +#include "select_account_merges_above_serial_id.h" +#include "select_aggregation_amounts_for_kyc_check.h" +#include "select_aggregation_transient.h" +#include "select_aggregations_above_serial.h" +#include "select_all_kyc_attributes.h" +#include "select_all_purse_decisions_above_serial_id.h" +#include "select_all_purse_deletions_above_serial_id.h" +#include "select_aml_attributes.h" +#include "select_aml_decisions.h" +#include "select_aml_measures.h" +#include "select_aml_statistics.h" +#include "select_auditor_denom_sig.h" +#include "select_batch_deposits_missing_wire.h" +#include "select_coin_deposits_above_serial_id.h" +#include "select_contract.h" +#include "select_contract_by_purse.h" +#include "select_deposit_amounts_for_kyc_check.h" +#include "select_exchange_credit_transfers.h" +#include "select_exchange_debit_transfers.h" +#include "select_exchange_kycauth_transfers.h" +#include "select_kyc_accounts.h" +#include "select_kyc_attributes.h" +#include "select_merge_amounts_for_kyc_check.h" +#include "select_purse.h" +#include "select_purse_by_merge_pub.h" +#include "select_purse_decisions_above_serial_id.h" +#include "select_purse_deposits_above_serial_id.h" +#include "select_purse_deposits_by_purse.h" +#include "select_purse_merge.h" +#include "select_purse_merges_above_serial_id.h" +#include "select_purse_requests_above_serial_id.h" +#include "select_recoup_above_serial_id.h" +#include "select_recoup_refresh_above_serial_id.h" +#include "select_refreshes_above_serial_id.h" +#include "select_refunds_above_serial_id.h" +#include "select_refunds_by_coin.h" +#include "select_reserve_close_info.h" +#include "select_reserve_closed_above_serial_id.h" +#include "select_reserve_open_above_serial_id.h" +#include "select_reserves_in_above_serial_id.h" +#include "select_reserves_in_above_serial_id_by_account.h" +#include "select_wire_out_above_serial_id.h" +#include "select_wire_out_above_serial_id_by_account.h" +#include "select_withdraw_amounts_for_kyc_check.h" +#include "select_withdrawals_above_serial_id.h" +#include "set_aml_lock.h" +#include "set_extension_manifest.h" +#include "set_purse_balance.h" +#include "start.h" +#include "start_deferred_wire_out.h" +#include "start_read_committed.h" +#include "start_read_only.h" +#include "store_wire_transfer_out.h" +#include "test_aml_officer.h" +#include "trigger_kyc_rule_for_account.h" +#include "update_aggregation_transient.h" +#include "update_auditor.h" +#include "update_kyc_process_by_row.h" +#include "update_wire.h" +#include "wad_in_insert.h" +#include "wire_prepare_data_get.h" +#include "wire_prepare_data_insert.h" +#include "wire_prepare_data_mark_failed.h" +#include "wire_prepare_data_mark_finished.h" #include "plugin_exchangedb_common.h" #include "plugin_exchangedb_postgres.h" #include "taler/taler_dbevents.h" @@ -275,20 +275,14 @@ * @return NULL on error, otherwise a `struct * TALER_EXCHANGEDB_Plugin` */ -void * -libtaler_plugin_exchangedb_postgres_init (void *cls); - -/* Declaration used to squash compiler warning */ -void * -libtaler_plugin_exchangedb_postgres_init (void *cls) +struct EXCHANGEDB_PostgresContext * +EXCHANGEDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, + bool skip_preflight) { - const struct GNUNET_CONFIGURATION_Handle *cfg = cls; - struct PostgresClosure *pg; - struct TALER_EXCHANGEDB_Plugin *plugin; + struct EXCHANGEDB_PostgresContext *pg; unsigned long long dpl; - pg = GNUNET_new (struct PostgresClosure); - plugin = GNUNET_new (struct TALER_EXCHANGEDB_Plugin); + pg = GNUNET_new (struct EXCHANGEDB_PostgresContext); pg->cfg = cfg; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, @@ -327,7 +321,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) GNUNET_CONFIGURATION_get_value_time (cfg, "exchangedb", "MAX_AML_PROGRAM_RUNTIME", - &plugin->max_aml_program_runtime)) + &pg->max_aml_program_runtime)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "exchangedb", @@ -378,427 +372,22 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) { goto fail; } - plugin->cls = pg; - plugin->do_reserve_open - = &TEH_PG_do_reserve_open; - plugin->drop_tables - = &TEH_PG_drop_tables; - 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; - plugin->get_expired_reserves - = &TEH_PG_get_expired_reserves; - plugin->get_purse_request - = &TEH_PG_get_purse_request; - plugin->get_reserve_history - = &TEH_PG_get_reserve_history; - plugin->get_unfinished_close_requests - = &TEH_PG_get_unfinished_close_requests; - plugin->insert_records_by_table - = &TEH_PG_insert_records_by_table; - plugin->insert_reserve_open_deposit - = &TEH_PG_insert_reserve_open_deposit; - plugin->insert_close_request - = &TEH_PG_insert_close_request; - plugin->delete_aggregation_transient - = &TEH_PG_delete_aggregation_transient; - plugin->iterate_reserve_close_info - = &TEH_PG_iterate_reserve_close_info; - plugin->iterate_kyc_reference - = &TEH_PG_iterate_kyc_reference; - plugin->lookup_records_by_table - = &TEH_PG_lookup_records_by_table; - plugin->lookup_serial_by_table - = &TEH_PG_lookup_serial_by_table; - 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_all_purse_deletions_above_serial_id - = &TEH_PG_select_all_purse_deletions_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; - plugin->select_reserve_close_info - = &TEH_PG_select_reserve_close_info; - 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; - plugin->insert_purse_request - = &TEH_PG_insert_purse_request; - plugin->iterate_active_signkeys - = &TEH_PG_iterate_active_signkeys; - plugin->commit - = &TEH_PG_commit; - plugin->preflight - = &TEH_PG_preflight; - plugin->select_aggregation_amounts_for_kyc_check - = &TEH_PG_select_aggregation_amounts_for_kyc_check; - plugin->get_kyc_rules - = &TEH_PG_get_kyc_rules; - plugin->get_kyc_rules2 - = &TEH_PG_get_kyc_rules2; - plugin->kyc_provider_account_lookup - = &TEH_PG_kyc_provider_account_lookup; - 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->do_purse_merge - = &TEH_PG_do_purse_merge; - plugin->do_purse_delete - = &TEH_PG_do_purse_delete; - 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->lookup_wire_fee_by_time - = &TEH_PG_lookup_wire_fee_by_time; - plugin->start - = &TEH_PG_start; - plugin->rollback - = &TEH_PG_rollback; - plugin->create_tables - = &TEH_PG_create_tables; - plugin->event_listen - = &TEH_PG_event_listen; - plugin->event_listen_cancel - = &TEH_PG_event_listen_cancel; - plugin->event_notify - = &TEH_PG_event_notify; - plugin->get_denomination_info - = &TEH_PG_get_denomination_info; - plugin->get_denomination_by_serial - = &TEH_PG_get_denomination_by_serial; - plugin->iterate_denomination_info - = &TEH_PG_iterate_denomination_info; - plugin->iterate_denominations - = &TEH_PG_iterate_denominations; - plugin->iterate_active_auditors - = &TEH_PG_iterate_active_auditors; - plugin->iterate_auditor_denominations - = &TEH_PG_iterate_auditor_denominations; - plugin->lookup_rules_by_access_token - = &TEH_PG_lookup_rules_by_access_token; - plugin->reserves_get - = &TEH_PG_reserves_get; - plugin->reserves_get_origin - = &TEH_PG_reserves_get_origin; - plugin->drain_kyc_alert - = &TEH_PG_drain_kyc_alert; - plugin->reserves_in_insert - = &TEH_PG_reserves_in_insert; - plugin->do_withdraw - = &TEH_PG_do_withdraw; - plugin->get_withdraw - = &TEH_PG_get_withdraw; - plugin->wad_in_insert - = &TEH_PG_wad_in_insert; - plugin->kycauth_in_insert - = &TEH_PG_kycauth_in_insert; - plugin->get_policy_details - = &TEH_PG_get_policy_details; - plugin->persist_policy_details - = &TEH_PG_persist_policy_details; - plugin->do_deposit - = &TEH_PG_do_deposit; - plugin->get_wire_hash_for_contract - = &TEH_PG_get_wire_hash_for_contract; - plugin->add_policy_fulfillment_proof - = &TEH_PG_add_policy_fulfillment_proof; - plugin->do_refresh - = &TEH_PG_do_refresh; - plugin->mark_refresh_reveal_success - = &TEH_PG_mark_refresh_reveal_success; - plugin->do_refund - = &TEH_PG_do_refund; - plugin->do_recoup - = &TEH_PG_do_recoup; - plugin->do_recoup_refresh - = &TEH_PG_do_recoup_refresh; - plugin->get_reserve_balance - = &TEH_PG_get_reserve_balance; - plugin->count_known_coins - = &TEH_PG_count_known_coins; - plugin->ensure_coin_known - = &TEH_PG_ensure_coin_known; - plugin->get_known_coin - = &TEH_PG_get_known_coin; - plugin->get_signature_for_known_coin - = &TEH_PG_get_signature_for_known_coin; - plugin->get_coin_denomination - = &TEH_PG_get_coin_denomination; - plugin->have_deposit2 - = &TEH_PG_have_deposit2; - plugin->aggregate - = &TEH_PG_aggregate; - plugin->create_aggregation_transient - = &TEH_PG_create_aggregation_transient; - plugin->select_aggregation_transient - = &TEH_PG_select_aggregation_transient; - plugin->find_aggregation_transient - = &TEH_PG_find_aggregation_transient; - plugin->update_aggregation_transient - = &TEH_PG_update_aggregation_transient; - plugin->get_ready_deposit - = &TEH_PG_get_ready_deposit; - plugin->insert_refund - = &TEH_PG_insert_refund; - plugin->select_refunds_by_coin - = &TEH_PG_select_refunds_by_coin; - plugin->select_aml_measures - = &TEH_PG_select_aml_measures; - plugin->get_refresh - = &TEH_PG_get_refresh; - plugin->lookup_wire_transfer - = &TEH_PG_lookup_wire_transfer; - plugin->lookup_transfer_by_deposit - = &TEH_PG_lookup_transfer_by_deposit; - plugin->insert_wire_fee - = &TEH_PG_insert_wire_fee; - plugin->insert_global_fee - = &TEH_PG_insert_global_fee; - plugin->get_wire_fee - = &TEH_PG_get_wire_fee; - plugin->get_global_fee - = &TEH_PG_get_global_fee; - plugin->get_global_fees - = &TEH_PG_get_global_fees; - plugin->insert_reserve_closed - = &TEH_PG_insert_reserve_closed; - plugin->wire_prepare_data_insert - = &TEH_PG_wire_prepare_data_insert; - plugin->wire_prepare_data_mark_finished - = &TEH_PG_wire_prepare_data_mark_finished; - plugin->wire_prepare_data_mark_failed - = &TEH_PG_wire_prepare_data_mark_failed; - plugin->wire_prepare_data_get - = &TEH_PG_wire_prepare_data_get; - plugin->start_deferred_wire_out - = &TEH_PG_start_deferred_wire_out; - plugin->store_wire_transfer_out - = &TEH_PG_store_wire_transfer_out; - plugin->gc - = &TEH_PG_gc; - plugin->select_coin_deposits_above_serial_id - = &TEH_PG_select_coin_deposits_above_serial_id; - plugin->lookup_aml_file_number - = &TEH_PG_lookup_aml_file_number; - plugin->lookup_aml_history - = &TEH_PG_lookup_aml_history; - plugin->lookup_kyc_history - = &TEH_PG_lookup_kyc_history; - plugin->select_purse_decisions_above_serial_id - = &TEH_PG_select_purse_decisions_above_serial_id; - plugin->select_purse_deposits_by_purse - = &TEH_PG_select_purse_deposits_by_purse; - plugin->select_refreshes_above_serial_id - = &TEH_PG_select_refreshes_above_serial_id; - plugin->select_refunds_above_serial_id - = &TEH_PG_select_refunds_above_serial_id; - plugin->select_reserves_in_above_serial_id - = &TEH_PG_select_reserves_in_above_serial_id; - plugin->select_reserves_in_above_serial_id_by_account - = &TEH_PG_select_reserves_in_above_serial_id_by_account; - plugin->select_withdrawals_above_serial_id - = &TEH_PG_select_withdrawals_above_serial_id; - plugin->select_wire_out_above_serial_id - = &TEH_PG_select_wire_out_above_serial_id; - plugin->select_wire_out_above_serial_id_by_account - = &TEH_PG_select_wire_out_above_serial_id_by_account; - plugin->select_recoup_above_serial_id - = &TEH_PG_select_recoup_above_serial_id; - plugin->select_recoup_refresh_above_serial_id - = &TEH_PG_select_recoup_refresh_above_serial_id; - plugin->get_reserve_by_h_planchets - = &TEH_PG_get_reserve_by_h_planchets; - plugin->get_old_coin_by_h_blind - = &TEH_PG_get_old_coin_by_h_blind; - plugin->insert_denomination_revocation - = &TEH_PG_insert_denomination_revocation; - plugin->get_denomination_revocation - = &TEH_PG_get_denomination_revocation; - plugin->select_batch_deposits_missing_wire - = &TEH_PG_select_batch_deposits_missing_wire; - plugin->select_aggregations_above_serial - = &TEH_PG_select_aggregations_above_serial; - plugin->lookup_auditor_timestamp - = &TEH_PG_lookup_auditor_timestamp; - plugin->lookup_auditor_status - = &TEH_PG_lookup_auditor_status; - plugin->insert_auditor - = &TEH_PG_insert_auditor; - plugin->lookup_wire_timestamp - = &TEH_PG_lookup_wire_timestamp; - plugin->insert_wire - = &TEH_PG_insert_wire; - plugin->update_wire - = &TEH_PG_update_wire; - plugin->get_wire_accounts - = &TEH_PG_get_wire_accounts; - plugin->get_wire_fees - = &TEH_PG_get_wire_fees; - plugin->select_aml_decisions - = &TEH_PG_select_aml_decisions; - plugin->select_deposit_amounts_for_kyc_check - = &TEH_PG_select_deposit_amounts_for_kyc_check; - plugin->do_check_deposit_idempotent - = &TEH_PG_do_check_deposit_idempotent; - plugin->insert_signkey_revocation - = &TEH_PG_insert_signkey_revocation; - plugin->select_aml_attributes - = &TEH_PG_select_aml_attributes; - plugin->select_aml_statistics - = &TEH_PG_select_aml_statistics; - plugin->lookup_signkey_revocation - = &TEH_PG_lookup_signkey_revocation; - plugin->lookup_denomination_key - = &TEH_PG_lookup_denomination_key; - plugin->lookup_completed_legitimization - = &TEH_PG_lookup_completed_legitimization; - plugin->lookup_pending_legitimization - = &TEH_PG_lookup_pending_legitimization; - plugin->lookup_active_legitimization - = &TEH_PG_lookup_active_legitimization; - plugin->insert_auditor_denom_sig - = &TEH_PG_insert_auditor_denom_sig; - plugin->select_auditor_denom_sig - = &TEH_PG_select_auditor_denom_sig; - plugin->select_kyc_accounts - = &TEH_PG_select_kyc_accounts; - plugin->add_denomination_key - = &TEH_PG_add_denomination_key; - plugin->lookup_signing_key - = &TEH_PG_lookup_signing_key; - plugin->lookup_h_payto_by_access_token - = &TEH_PG_lookup_h_payto_by_access_token; - plugin->insert_sanction_list_hit - = &TEH_PG_insert_sanction_list_hit; - plugin->select_exchange_debit_transfers - = &TEH_PG_select_exchange_debit_transfers; - plugin->select_exchange_credit_transfers - = &TEH_PG_select_exchange_credit_transfers; - plugin->select_exchange_kycauth_transfers - = &TEH_PG_select_exchange_kycauth_transfers; - plugin->select_all_kyc_attributes - = &TEH_PG_select_all_kyc_attributes; - plugin->begin_shard - = &TEH_PG_begin_shard; - plugin->abort_shard - = &TEH_PG_abort_shard; - plugin->insert_kyc_failure - = &TEH_PG_insert_kyc_failure; - plugin->complete_shard - = &TEH_PG_complete_shard; - plugin->release_revolving_shard - = &TEH_PG_release_revolving_shard; - plugin->delete_shard_locks - = &TEH_PG_delete_shard_locks; - plugin->set_extension_manifest - = &TEH_PG_set_extension_manifest; - plugin->insert_partner - = &TEH_PG_insert_partner; - plugin->expire_purse - = &TEH_PG_expire_purse; - plugin->select_purse_by_merge_pub - = &TEH_PG_select_purse_by_merge_pub; - plugin->set_purse_balance - = &TEH_PG_set_purse_balance; - plugin->get_pending_kyc_requirement_process - = &TEH_PG_get_pending_kyc_requirement_process; - plugin->select_kyc_attributes - = &TEH_PG_select_kyc_attributes; - plugin->insert_aml_officer - = &TEH_PG_insert_aml_officer; - plugin->enable_rules - = &TEH_PG_enable_rules; - plugin->disable_rules - = &TEH_PG_disable_rules; - plugin->test_aml_officer - = &TEH_PG_test_aml_officer; - plugin->lookup_aml_officer - = &TEH_PG_lookup_aml_officer; - plugin->insert_active_legitimization_measure - = &TEH_PG_insert_active_legitimization_measure; - plugin->insert_aml_decision - = &TEH_PG_insert_aml_decision; - plugin->lookup_kyc_requirement_by_row - = &TEH_PG_lookup_kyc_requirement_by_row; - plugin->trigger_kyc_rule_for_account - = &TEH_PG_trigger_kyc_rule_for_account; - plugin->lookup_kyc_status_by_token - = &TEH_PG_lookup_kyc_status_by_token; - plugin->batch_ensure_coin_known - = &TEH_PG_batch_ensure_coin_known; - plugin->inject_auditor_triggers - = &TEH_PG_inject_auditor_triggers; - plugin->insert_successor_measure - = &TEH_PG_insert_successor_measure; - plugin->insert_aml_program_failure - = &TEH_PG_insert_aml_program_failure; - plugin->persist_kyc_attributes - = &TEH_PG_persist_kyc_attributes; - plugin->clear_aml_lock - = &TEH_PG_clear_aml_lock; - plugin->set_aml_lock - = &TEH_PG_set_aml_lock; - - return plugin; + if (! skip_preflight) + { + if (GNUNET_OK != + EXCHANGEDB_internal_setup (pg, + false)) + { + goto fail; + } + } + return pg; fail: GNUNET_free (pg->exchange_url); GNUNET_free (pg->sql_dir); + GNUNET_free (pg->currency); GNUNET_free (pg); - GNUNET_free (plugin); return NULL; } @@ -809,16 +398,11 @@ fail: * @param cls a `struct TALER_EXCHANGEDB_Plugin` * @return NULL (always) */ -void * -libtaler_plugin_exchangedb_postgres_done (void *cls); - -/* Declaration used to squash compiler warning */ -void * -libtaler_plugin_exchangedb_postgres_done (void *cls) +void +EXCHANGEDB_disconnect (struct EXCHANGEDB_PostgresContext *pg) { - struct TALER_EXCHANGEDB_Plugin *plugin = cls; - struct PostgresClosure *pg = plugin->cls; - + if (NULL == pg) + return; if (NULL != pg->conn) { GNUNET_PQ_disconnect (pg->conn); @@ -828,8 +412,6 @@ libtaler_plugin_exchangedb_postgres_done (void *cls) GNUNET_free (pg->sql_dir); GNUNET_free (pg->currency); GNUNET_free (pg); - GNUNET_free (plugin); - return NULL; } diff --git a/src/exchangedb/preflight.c b/src/exchangedb/preflight.c @@ -0,0 +1,122 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/preflight.c + * @brief Implementation of the preflight function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "preflight.h" +#include "pg_helper.h" +#include "plugin_exchangedb_postgres.h" + + +/** + * Connect to the database if the connection does not exist yet + * and check that we are ready to operate. + * + * @param ctx the plugin-specific state + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +internal_setup (struct EXCHANGEDB_PostgresContext *ctx) +{ + if (NULL == ctx->conn) + { +#if AUTO_EXPLAIN + /* Enable verbose logging to see where queries do not + properly use indices */ + struct GNUNET_PQ_ExecuteStatement es[] = { + 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;"), + /* 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;"), + GNUNET_PQ_make_try_execute ("SET enable_sort=OFF;"), + GNUNET_PQ_make_try_execute ("SET enable_seqscan=OFF;"), + GNUNET_PQ_make_try_execute ("SET search_path TO exchange;"), + /* Mergejoin causes issues, see Postgres #18380 */ + GNUNET_PQ_make_try_execute ("SET enable_mergejoin=OFF;"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; +#else + 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;"), + /* Mergejoin causes issues, see Postgres #18380 */ + GNUNET_PQ_make_try_execute ("SET enable_mergejoin=OFF;"), + GNUNET_PQ_make_try_execute ("SET search_path TO exchange;"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; +#endif + struct GNUNET_PQ_Context *db_conn; + + db_conn = GNUNET_PQ_connect_with_cfg2 (ctx->cfg, + "exchangedb-postgres", + "exchange-", /* load_path_suffix */ + es, + NULL /* prepared statements */, + GNUNET_PQ_FLAG_CHECK_CURRENT); + if (NULL == db_conn) + return GNUNET_SYSERR; + + ctx->prep_gen++; + ctx->conn = db_conn; + } + if (NULL == ctx->transaction_name) + GNUNET_PQ_reconnect_if_down (ctx->conn); + return GNUNET_OK; +} + + +enum GNUNET_GenericReturnValue +EXCHANGEDB_preflight (struct EXCHANGEDB_PostgresContext *ctx) +{ + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ("ROLLBACK"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + if (GNUNET_OK != + internal_setup (ctx)) + return GNUNET_SYSERR; + if (NULL == ctx->transaction_name) + return GNUNET_OK; /* all good */ + if (GNUNET_OK == + GNUNET_PQ_exec_statements (ctx->conn, + es)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "BUG: Preflight check rolled back transaction `%s'!\n", + ctx->transaction_name); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "BUG: Preflight check failed to rollback transaction `%s'!\n", + ctx->transaction_name); + } + ctx->transaction_name = NULL; + return GNUNET_NO; +} diff --git a/src/exchangedb/profit_drains_get_pending.c b/src/exchangedb/profit_drains_get_pending.c @@ -0,0 +1,77 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/profit_drains_get_pending.c + * @brief Implementation of the profit_drains_get_pending function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "profit_drains_get_pending.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_profit_drains_get_pending (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t *serial, + struct TALER_WireTransferIdentifierRawP *wtid, + char **account_section, + struct TALER_FullPayto *payto_uri, + struct GNUNET_TIME_Timestamp *request_timestamp, + struct TALER_Amount *amount, + struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("profit_drain_serial_id", + serial), + GNUNET_PQ_result_spec_auto_from_type ("wtid", + wtid), + GNUNET_PQ_result_spec_string ("account_section", + account_section), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri->full_payto), + GNUNET_PQ_result_spec_timestamp ("trigger_date", + request_timestamp), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + amount), + GNUNET_PQ_result_spec_auto_from_type ("master_sig", + master_sig), + GNUNET_PQ_result_spec_end + }; + /* Used in #postgres_profit_drains_get_pending() */ + PREPARE (ctx, + "get_ready_profit_drain", + "SELECT" + " profit_drain_serial_id" + ",wtid" + ",account_section" + ",payto_uri" + ",trigger_date" + ",amount" + ",master_sig" + " FROM profit_drains" + " WHERE NOT executed" + " ORDER BY trigger_date ASC;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "get_ready_profit_drain", + params, + rs); +} diff --git a/src/exchangedb/profit_drains_set_finished.c b/src/exchangedb/profit_drains_set_finished.c @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/profit_drains_set_finished.c + * @brief Implementation of the profit_drains_set_finished function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "profit_drains_set_finished.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_profit_drains_set_finished (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "drain_profit_set_finished", + "UPDATE profit_drains" + " SET" + " executed=TRUE" + " WHERE profit_drain_serial_id=$1;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "drain_profit_set_finished", + params); +} diff --git a/src/exchangedb/release_revolving_shard.c b/src/exchangedb/release_revolving_shard.c @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/release_revolving_shard.c + * @brief Implementation of the release_revolving_shard function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "release_revolving_shard.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_release_revolving_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + uint32_t start_row, + uint32_t end_row) +{ + 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 + }; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Releasing revolving shard %s %u-%u\n", + job_name, + (unsigned int) start_row, + (unsigned int) end_row); + + + PREPARE (ctx, + "release_revolving_shard", + "UPDATE revolving_work_shards" + " SET active=FALSE" + " WHERE job_name=$1" + " AND start_row=$2" + " AND end_row=$3"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "release_revolving_shard", + params); +} diff --git a/src/exchangedb/reserves_get.c b/src/exchangedb/reserves_get.c @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/reserves_get.c + * @brief Implementation of the reserves_get function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "reserves_get.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_reserves_get (struct EXCHANGEDB_PostgresContext *ctx, + struct TALER_EXCHANGEDB_Reserve *reserve) +{ + 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", + ctx->currency, + &reserve->balance), + GNUNET_PQ_result_spec_timestamp ("expiration_date", + &reserve->expiry), + GNUNET_PQ_result_spec_timestamp ("gc_date", + &reserve->gc), + GNUNET_PQ_result_spec_end + }; + /* Used in #postgres_reserves_get() */ + PREPARE (ctx, + "reserves_get", + "SELECT" + " current_balance" + ",expiration_date" + ",gc_date" + " FROM reserves" + " WHERE reserve_pub=$1" + " LIMIT 1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "reserves_get", + params, + rs); +} diff --git a/src/exchangedb/reserves_get_origin.c b/src/exchangedb/reserves_get_origin.c @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/reserves_get_origin.c + * @brief Implementation of the reserves_get_origin function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "reserves_get_origin.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_reserves_get_origin (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_FullPaytoHashP *h_payto, + struct TALER_FullPayto *payto_uri) +{ + 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_string ( + "payto_uri", + &payto_uri->full_payto), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "get_h_wire_source_of_reserve", + "SELECT" + " rt.wire_source_h_payto" + ",wt.payto_uri" + " FROM reserves_in rt" + " JOIN wire_targets wt" + " ON (rt.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE rt.reserve_pub=$1"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "get_h_wire_source_of_reserve", + params, + rs); +} diff --git a/src/exchangedb/reserves_in_insert.c b/src/exchangedb/reserves_in_insert.c @@ -0,0 +1,377 @@ +/* + This file is part of TALER + Copyright (C) 2022-2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/reserves_in_insert.c + * @brief Implementation of the reserves_in_insert function for Postgres + * @author Christian Grothoff + * @author Joseph Xu + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "reserves_in_insert.h" +#include "pg_helper.h" +#include "pg_start.h" +#include "pg_start_read_committed.h" +#include "pg_commit.h" +#include "pg_preflight.h" +#include "pg_rollback.h" +#include "pg_event_notify.h" + + +/** + * Generate event notification for the reserve change. + * + * @param reserve_pub reserve to notfiy on + * @return string to pass to postgres for the notification + */ +static char * +compute_notify_on_reserve (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 + }; + + return GNUNET_PQ_get_event_notify_channel (&rep.header); +} + + +/** + * Closure for our helper_cb() + */ +struct Context +{ + /** + * Array of reserve UUIDs to initialize. + */ + uint64_t *reserve_uuids; + + /** + * Array with entries set to 'true' for duplicate transactions. + */ + bool *transaction_duplicates; + + /** + * Array with entries set to 'true' for rows with conflicts. + */ + bool *conflicts; + + /** + * Set to #GNUNET_SYSERR on failures. + */ + enum GNUNET_GenericReturnValue status; + + /** + * Single value (no array) set to true if we need + * to follow-up with an update. + */ + bool needs_update; +}; + + +/** + * 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 Context *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct Context *ctx = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ( + "transaction_duplicate", + &ctx->transaction_duplicates[i]), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ("ruuid", + &ctx->reserve_uuids[i]), + &ctx->conflicts[i]), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->status = GNUNET_SYSERR; + return; + } + if (! ctx->transaction_duplicates[i]) + ctx->needs_update |= ctx->conflicts[i]; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_reserves_in_insert (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_ReserveInInfo *reserves, + unsigned int reserves_length, + enum GNUNET_DB_QueryStatus *results) +{ + unsigned int dups = 0; + + struct TALER_FullPaytoHashP h_full_paytos[ + GNUNET_NZL (reserves_length)]; + struct TALER_NormalizedPaytoHashP h_normalized_paytos[ + GNUNET_NZL (reserves_length)]; + char *notify_s[GNUNET_NZL (reserves_length)]; + struct TALER_ReservePublicKeyP reserve_pubs[GNUNET_NZL (reserves_length)]; + struct TALER_Amount balances[GNUNET_NZL (reserves_length)]; + struct GNUNET_TIME_Timestamp execution_times[GNUNET_NZL (reserves_length)]; + const char *sender_account_details[GNUNET_NZL (reserves_length)]; + const char *exchange_account_names[GNUNET_NZL (reserves_length)]; + uint64_t wire_references[GNUNET_NZL (reserves_length)]; + uint64_t reserve_uuids[GNUNET_NZL (reserves_length)]; + bool transaction_duplicates[GNUNET_NZL (reserves_length)]; + bool conflicts[GNUNET_NZL (reserves_length)]; + struct GNUNET_TIME_Timestamp reserve_expiration + = GNUNET_TIME_relative_to_timestamp (ctx->idle_reserve_expiration_time); + struct GNUNET_TIME_Timestamp gc + = GNUNET_TIME_relative_to_timestamp (ctx->legal_reserve_expiration_time); + enum GNUNET_DB_QueryStatus qs; + bool need_update; + + for (unsigned int i = 0; i<reserves_length; i++) + { + const struct TALER_EXCHANGEDB_ReserveInInfo *reserve = &reserves[i]; + + TALER_full_payto_hash (reserve->sender_account_details, + &h_full_paytos[i]); + TALER_full_payto_normalize_and_hash (reserve->sender_account_details, + &h_normalized_paytos[i]); + notify_s[i] = compute_notify_on_reserve (reserve->reserve_pub); + reserve_pubs[i] = *reserve->reserve_pub; + balances[i] = *reserve->balance; + execution_times[i] = reserve->execution_time; + sender_account_details[i] = reserve->sender_account_details.full_payto; + exchange_account_names[i] = reserve->exchange_account_name; + wire_references[i] = reserve->wire_reference; + } + + /* NOTE: kind-of pointless to explicitly start a transaction here... */ + if (GNUNET_OK != + EXCHANGEDB_preflight (ctx)) + { + GNUNET_break (0); + qs = GNUNET_DB_STATUS_HARD_ERROR; + goto finished; + } + if (GNUNET_OK != + EXCHANGEDB_start_read_committed (ctx, + "READ_COMMITED")) + { + GNUNET_break (0); + qs = GNUNET_DB_STATUS_HARD_ERROR; + goto finished; + } + PREPARE (ctx, + "reserves_insert_with_array", + "SELECT" + " transaction_duplicate" + ",ruuid" + " FROM exchange_do_array_reserves_insert" + " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);"); + { + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&gc), + GNUNET_PQ_query_param_timestamp (&reserve_expiration), + GNUNET_PQ_query_param_array_auto_from_type (reserves_length, + reserve_pubs, + ctx->conn), + GNUNET_PQ_query_param_array_uint64 (reserves_length, + wire_references, + ctx->conn), + TALER_PQ_query_param_array_amount ( + reserves_length, + balances, + ctx->conn), + GNUNET_PQ_query_param_array_ptrs_string ( + reserves_length, + (const char **) exchange_account_names, + ctx->conn), + GNUNET_PQ_query_param_array_timestamp ( + reserves_length, + execution_times, + ctx->conn), + GNUNET_PQ_query_param_array_auto_from_type ( + reserves_length, + h_full_paytos, + ctx->conn), + GNUNET_PQ_query_param_array_auto_from_type ( + reserves_length, + h_normalized_paytos, + ctx->conn), + GNUNET_PQ_query_param_array_ptrs_string ( + reserves_length, + (const char **) sender_account_details, + ctx->conn), + GNUNET_PQ_query_param_array_ptrs_string ( + reserves_length, + (const char **) notify_s, + ctx->conn), + GNUNET_PQ_query_param_end + }; + struct Context ctx = { + .reserve_uuids = reserve_uuids, + .transaction_duplicates = transaction_duplicates, + .conflicts = conflicts, + .needs_update = false, + .status = GNUNET_OK + }; + + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "reserves_insert_with_array", + params, + &helper_cb, + &ctx); + GNUNET_PQ_cleanup_query_params_closures (params); + if ( (qs < 0) || + (GNUNET_OK != ctx.status) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to insert into reserves (%d)\n", + qs); + goto finished; + } + need_update = ctx.needs_update; + } + + { + enum GNUNET_DB_QueryStatus cs; + + cs = EXCHANGEDB_commit (ctx); + if (cs < 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to commit\n"); + qs = cs; + goto finished; + } + } + + for (unsigned int i = 0; i<reserves_length; i++) + { + if (transaction_duplicates[i]) + dups++; + results[i] = transaction_duplicates[i] + ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS + : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } + + if (! need_update) + { + qs = reserves_length; + goto finished; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Reserve update needed for some reserves in the batch\n"); + PREPARE (ctx, + "reserves_update", + "SELECT" + " out_duplicate AS duplicate " + "FROM exchange_do_batch_reserves_update" + " ($1,$2,$3,$4,$5,$6,$7);"); + + if (GNUNET_OK != + EXCHANGEDB_start (ctx, + "reserve-insert-continued")) + { + GNUNET_break (0); + qs = GNUNET_DB_STATUS_HARD_ERROR; + goto finished; + } + + for (unsigned int i = 0; i<reserves_length; i++) + { + if (transaction_duplicates[i]) + continue; + if (! conflicts[i]) + continue; + { + bool duplicate; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (&reserve_pubs[i]), + GNUNET_PQ_query_param_timestamp (&reserve_expiration), + GNUNET_PQ_query_param_uint64 (&wire_references[i]), + TALER_PQ_query_param_amount (ctx->conn, + &balances[i]), + GNUNET_PQ_query_param_string (exchange_account_names[i]), + GNUNET_PQ_query_param_auto_from_type (&h_full_paytos[i]), + GNUNET_PQ_query_param_string (notify_s[i]), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("duplicate", + &duplicate), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qsi; + + qsi = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "reserves_update", + params, + rs); + if (qsi < 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to update reserves (%d)\n", + qsi); + results[i] = qsi; + goto finished; + } + results[i] = duplicate + ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS + : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } + } + { + enum GNUNET_DB_QueryStatus cs; + + cs = EXCHANGEDB_commit (ctx); + if (cs < 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to commit\n"); + qs = cs; + goto finished; + } + } +finished: + for (unsigned int i = 0; i<reserves_length; i++) + GNUNET_free (notify_s[i]); + if (qs < 0) + return qs; + GNUNET_PQ_event_do_poll (ctx->conn); + if (0 != dups) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "%u/%u duplicates among incoming transactions. Try increasing WIREWATCH_IDLE_SLEEP_INTERVAL in the [exchange] configuration section (if this happens a lot).\n", + dups, + reserves_length); + return qs; +} diff --git a/src/exchangedb/reserves_update.c b/src/exchangedb/reserves_update.c @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/reserves_update.c + * @brief Implementation of the reserves_update function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "reserves_update.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_reserves_update (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_Reserve *reserve) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&reserve->expiry), + GNUNET_PQ_query_param_timestamp (&reserve->gc), + TALER_PQ_query_param_amount (ctx->conn, + &reserve->balance), + GNUNET_PQ_query_param_auto_from_type (&reserve->pub), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "reserve_update", + "UPDATE reserves" + " SET" + " expiration_date=$1" + ",gc_date=$2" + ",current_balance=$3" + " WHERE reserve_pub=$4;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "reserve_update", + params); +} diff --git a/src/exchangedb/rollback.c b/src/exchangedb/rollback.c @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/rollback.c + * @brief Implementation of the rollback function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "rollback.h" +#include "pg_helper.h" + + +void +EXCHANGEDB_rollback (struct EXCHANGEDB_PostgresContext *ctx) +{ + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ("ROLLBACK"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + if (NULL == ctx->transaction_name) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Skipping rollback, no transaction active\n"); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Rolling back transaction\n"); + GNUNET_break (GNUNET_OK == + GNUNET_PQ_exec_statements (ctx->conn, + es)); + ctx->transaction_name = NULL; +} diff --git a/src/exchangedb/select_account_merges_above_serial_id.c b/src/exchangedb/select_account_merges_above_serial_id.c @@ -0,0 +1,190 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_account_merges_above_serial_id.c + * @brief Implementation of the select_account_merges_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_account_merges_above_serial_id.h" +#include "pg_helper.h" + + +/** + * Closure for #account_merge_serial_helper_cb(). + */ +struct AccountMergeSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_AccountMergeCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct AccountMergeSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +account_merge_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AccountMergeSerialContext *dsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = dsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_PrivateContractHashP h_contract_terms; + struct GNUNET_TIME_Timestamp purse_expiration; + struct TALER_Amount amount; + uint32_t min_age; + uint32_t flags32; + enum TALER_WalletAccountMergeFlags flags; + struct TALER_Amount purse_fee; + struct GNUNET_TIME_Timestamp merge_timestamp; + struct TALER_ReserveSignatureP reserve_sig; + uint64_t rowid; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee", + &purse_fee), + GNUNET_PQ_result_spec_uint32 ("flags", + &flags32), + GNUNET_PQ_result_spec_uint32 ("age_limit", + &min_age), + GNUNET_PQ_result_spec_timestamp ("purse_expiration", + &purse_expiration), + GNUNET_PQ_result_spec_timestamp ("merge_timestamp", + &merge_timestamp), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &h_contract_terms), + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &purse_pub), + GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", + &reserve_sig), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + GNUNET_PQ_result_spec_uint64 ("account_merge_request_serial_id", + &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; + } + flags = (enum TALER_WalletAccountMergeFlags) flags32; + ret = dsc->cb (dsc->cb_cls, + rowid, + &reserve_pub, + &purse_pub, + &h_contract_terms, + purse_expiration, + &amount, + min_age, + flags, + &purse_fee, + merge_timestamp, + &reserve_sig); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_account_merges_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_AccountMergeCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct AccountMergeSerialContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "audit_get_account_merge_incr", + "SELECT" + " am.account_merge_request_serial_id" + ",am.reserve_pub" + ",am.purse_pub" + ",pr.h_contract_terms" + ",pr.purse_expiration" + ",pr.amount_with_fee" + ",pr.age_limit" + ",pr.flags" + ",pr.purse_fee" + ",pm.merge_timestamp" + ",am.reserve_sig" + " FROM account_merges am" + " JOIN purse_requests pr USING (purse_pub)" + " JOIN purse_merges pm USING (purse_pub)" + " WHERE (" + " (account_merge_request_serial_id>=$1)" + " )" + " ORDER BY account_merge_request_serial_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_account_merge_incr", + params, + &account_merge_serial_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_aggregation_amounts_for_kyc_check.c b/src/exchangedb/select_aggregation_amounts_for_kyc_check.c @@ -0,0 +1,156 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_aggregation_amounts_for_kyc_check.c + * @brief Implementation of the select_aggregation_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_aggregation_amounts_for_kyc_check.h" +#include "pg_helper.h" + + +/** + * Closure for #get_kyc_amounts_cb(). + */ +struct KycAmountCheckContext +{ + /** + * Function to call per result. + */ + TALER_EXCHANGEDB_KycAmountCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + + +/** + * Invoke the callback for each result. + * + * @param cls a `struct KycAmountCheckContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +get_kyc_amounts_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct KycAmountCheckContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct GNUNET_TIME_Absolute date; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_absolute_time ("date", + &date), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->status = GNUNET_SYSERR; + return; + } + ret = ctx->cb (ctx->cb_cls, + &amount, + date); + GNUNET_PQ_cleanup_result (rs); + switch (ret) + { + case GNUNET_OK: + continue; + case GNUNET_NO: + break; + case GNUNET_SYSERR: + ctx->status = GNUNET_SYSERR; + break; + } + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aggregation_amounts_for_kyc_check (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_absolute_time (&time_limit), + GNUNET_PQ_query_param_end + }; + struct KycAmountCheckContext ctx = { + .cb = kac, + .cb_cls = kac_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_kyc_relevant_aggregation_events", + "SELECT" + " amount" + ",execution_date AS date" + " FROM wire_out" + " WHERE wire_target_h_payto IN" + " (SELECT wire_target_h_payto" + " FROM wire_targets" + " WHERE h_normalized_payto=$1" + " )" + " AND execution_date >= $2" + " ORDER BY execution_date DESC"); + + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_kyc_relevant_aggregation_events", + params, + &get_kyc_amounts_cb, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_aggregation_transient.c b/src/exchangedb/select_aggregation_transient.c @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_aggregation_transient.c + * @brief Implementation of the select_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_aggregation_transient.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const char *exchange_account_section, + struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_Amount *total) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_auto_from_type (merchant_pub), + 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 + }; + + PREPARE (ctx, + "select_aggregation_transient", + "SELECT" + " amount" + " ,wtid_raw" + " FROM aggregation_transient" + " WHERE wire_target_h_payto=$1" + " AND merchant_pub=$2" + " AND exchange_account_section=$3;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "select_aggregation_transient", + params, + rs); +} diff --git a/src/exchangedb/select_aggregations_above_serial.c b/src/exchangedb/select_aggregations_above_serial.c @@ -0,0 +1,139 @@ +/* + This file is part of TALER + Copyright (C) 2023, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_aggregations_above_serial.c + * @brief Implementation of the select_aggregations_above_serial function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_aggregations_above_serial.h" +#include "pg_helper.h" + +/** + * Closure for #aggregation_serial_helper_cb(). + */ +struct AggregationSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_AggregationCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct AggregationSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +aggregation_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AggregationSerialContext *dsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = dsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t tracking_rowid; + uint64_t batch_deposit_serial_id; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("total_amount", + &amount), + GNUNET_PQ_result_spec_uint64 ("aggregation_serial_id", + &tracking_rowid), + GNUNET_PQ_result_spec_uint64 ("batch_deposit_serial_id", + &batch_deposit_serial_id), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + dsc->status = GNUNET_SYSERR; + return; + } + dsc->cb (dsc->cb_cls, + &amount, + tracking_rowid, + batch_deposit_serial_id); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aggregations_above_serial (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t min_tracking_serial_id, + TALER_EXCHANGEDB_AggregationCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&min_tracking_serial_id), + GNUNET_PQ_query_param_end + }; + struct AggregationSerialContext asc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + /* Fetch aggregations with rowid '\geq' the given parameter */ + PREPARE (ctx, + "select_aggregations_above_serial", + "SELECT" + " aggregation_serial_id" + ",batch_deposit_serial_id" + ",total_amount" + " FROM exchange_do_select_aggregations_above_serial($1);"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "select_aggregations_above_serial", + params, + &aggregation_serial_helper_cb, + &asc); + if (GNUNET_OK != asc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_all_kyc_attributes.c b/src/exchangedb/select_all_kyc_attributes.c @@ -0,0 +1,170 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_all_kyc_attributes.c + * @brief Implementation of the select_all_kyc_attributes function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_all_kyc_attributes.h" +#include "pg_helper.h" + +/** + * Closure for #get_all_attributes_cb(). + */ +struct GetAttributesContext +{ + /** + * Function to call per result. + */ + TALER_EXCHANGEDB_AllAttributesCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + +/** + * Invoke the callback for each result. + * + * @param cls a `struct GetAttributesContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +get_attributes_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct GetAttributesContext *ctx = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t rowid; + struct GNUNET_TIME_Timestamp collection_time; + struct GNUNET_TIME_Timestamp expiration_time; + struct TALER_NormalizedPaytoHashP h_payto; + json_t *properties = NULL; + size_t enc_attributes_size; + void *enc_attributes; + char *provider; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("provider_name", + &provider), + GNUNET_PQ_result_spec_uint64 ("kyc_attributes_serial_id", + &rowid), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("jproperties", + &properties), + NULL), + GNUNET_PQ_result_spec_timestamp ("collection_time", + &collection_time), + GNUNET_PQ_result_spec_timestamp ("expiration_time", + &expiration_time), + GNUNET_PQ_result_spec_auto_from_type ("h_payto", + &h_payto), + GNUNET_PQ_result_spec_variable_size ("encrypted_attributes", + &enc_attributes, + &enc_attributes_size), + 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, + rowid, + &h_payto, + provider, + collection_time, + expiration_time, + properties, + enc_attributes_size, + enc_attributes); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_all_kyc_attributes (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t min_row_id, + TALER_EXCHANGEDB_AllAttributesCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&min_row_id), + GNUNET_PQ_query_param_end + }; + struct GetAttributesContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_all_kyc_attributes", + "SELECT " + " lp.provider_name" + ",ka.h_payto" + ",ka.kyc_attributes_serial_id" + ",lo.jproperties::TEXT" + ",ka.collection_time" + ",ka.expiration_time" + ",ka.encrypted_attributes" + " FROM kyc_attributes ka" + " JOIN legitimization_processes lp" + " ON (ka.legitimization_serial = lp.legitimization_process_serial_id)" + " LEFT JOIN legitimization_outcomes lo" + " ON (ka.h_payto = lo.h_payto)" + /* **IF** we joined with 'lo', the lo must be active */ + " WHERE COALESCE(lo.is_active,TRUE)" + " AND kyc_attributes_serial_id > $1" + " ORDER BY kyc_attributes_serial_id ASC" + ); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_all_kyc_attributes", + params, + &get_attributes_cb, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_all_purse_decisions_above_serial_id.c b/src/exchangedb/select_all_purse_decisions_above_serial_id.c @@ -0,0 +1,144 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_all_purse_decisions_above_serial_id.c + * @brief Implementation of the select_all_purse_decisions_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_all_purse_decisions_above_serial_id.h" +#include "pg_helper.h" + + +/** + * Closure for #all_purse_decision_serial_helper_cb(). + */ +struct AllPurseDecisionSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_AllPurseDecisionCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct PurseRefundSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +all_purse_decision_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AllPurseDecisionSerialContext *dsc = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_PurseContractPublicKeyP purse_pub; + bool refunded; + uint64_t rowid; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &purse_pub), + GNUNET_PQ_result_spec_bool ("refunded", + &refunded), + GNUNET_PQ_result_spec_uint64 ("purse_decision_serial_id", + &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, + refunded); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_all_purse_decisions_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_AllPurseDecisionCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct AllPurseDecisionSerialContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "audit_select_all_purse_decisions_above_serial_id", + "SELECT" + " purse_pub" + ",refunded" + ",purse_decision_serial_id" + " FROM purse_decision" + " WHERE purse_decision_serial_id>=$1" + " ORDER BY purse_decision_serial_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "audit_select_all_purse_decisions_above_serial_id", + params, + &all_purse_decision_serial_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_all_purse_deletions_above_serial_id.c b/src/exchangedb/select_all_purse_deletions_above_serial_id.c @@ -0,0 +1,144 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_all_purse_deletions_above_serial_id.c + * @brief Implementation of the select_all_purse_deletions_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_all_purse_deletions_above_serial_id.h" +#include "pg_helper.h" + + +/** + * Closure for #all_purse_deletion_serial_helper_cb(). + */ +struct AllPurseDeletionSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_AllPurseDeletionsCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct PurseRefundSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +all_purse_deletion_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AllPurseDeletionSerialContext *dsc = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_PurseContractSignatureP purse_sig; + uint64_t rowid; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &purse_pub), + GNUNET_PQ_result_spec_auto_from_type ("purse_sig", + &purse_sig), + GNUNET_PQ_result_spec_uint64 ("purse_deletion_serial_id", + &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, + &purse_sig); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_all_purse_deletions_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_AllPurseDeletionsCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct AllPurseDeletionSerialContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "audit_select_all_purse_deletions_above_serial_id", + "SELECT" + " purse_pub" + ",purse_sig" + ",purse_deletion_serial_id" + " FROM purse_deletion" + " WHERE purse_deletion_serial_id>=$1" + " ORDER BY purse_deletion_serial_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "audit_select_all_purse_deletions_above_serial_id", + params, + &all_purse_deletion_serial_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_aml_attributes.c b/src/exchangedb/select_aml_attributes.c @@ -0,0 +1,191 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_aml_attributes.c + * @brief Implementation of the select_aml_attributes function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_aml_attributes.h" +#include "pg_helper.h" + + +/** + * Closure for #handle_aml_result. + */ +struct AmlAttributeResultContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlAttributeCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #EXCHANGEDB_select_aml_attributes(). + * + * @param cls closure of type `struct AmlAttributeResultContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_aml_attributes (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AmlAttributeResultContext *ctx = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct GNUNET_TIME_Timestamp collection_time; + char *officer_name = NULL; + bool by_aml_officer; + size_t enc_attributes_size; + void *enc_attributes; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("kyc_attributes_serial_id", + &rowid), + GNUNET_PQ_result_spec_timestamp ("collection_time", + &collection_time), + GNUNET_PQ_result_spec_bool ("by_aml_officer", + &by_aml_officer), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("decider_name", + &officer_name), + NULL), + GNUNET_PQ_result_spec_variable_size ("encrypted_attributes", + &enc_attributes, + &enc_attributes_size), + 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, + rowid, + collection_time, + by_aml_officer, + officer_name, + enc_attributes_size, + enc_attributes); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aml_attributes (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlAttributeCallback cb, + void *cb_cls) +{ + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_end + }; + struct AmlAttributeResultContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + const char *stmt = (limit > 0) + ? "select_aml_attributes_inc" + : "select_aml_attributes_dec"; + + PREPARE (ctx, + "select_aml_attributes_inc", + "SELECT" + " ka.kyc_attributes_serial_id" + ",ka.collection_time" + ",ka.by_aml_officer" + ",astaff.decider_name" + ",ka.encrypted_attributes" + " FROM kyc_attributes ka" + " LEFT JOIN legitimization_processes lp" + " ON (ka.by_aml_officer AND" + " (ka.legitimization_serial = lp.legitimization_process_serial_id))" + " LEFT JOIN aml_staff astaff" + " ON (ka.by_aml_officer AND" + " (DECODE(lp.provider_user_id, 'base64') = astaff.decider_pub))" + " WHERE ka.h_payto=$1" + " AND ka.kyc_attributes_serial_id > $2" + " ORDER BY ka.kyc_attributes_serial_id ASC" + " LIMIT $3"); + PREPARE (ctx, + "select_aml_attributes_dec", + "SELECT" + " ka.kyc_attributes_serial_id" + ",ka.collection_time" + ",ka.by_aml_officer" + ",astaff.decider_name" + ",ka.encrypted_attributes" + " FROM kyc_attributes ka" + " LEFT JOIN legitimization_processes lp" + " ON (ka.by_aml_officer AND" + " (ka.legitimization_serial = lp.legitimization_process_serial_id))" + " LEFT JOIN aml_staff astaff" + " ON (ka.by_aml_officer AND" + " (DECODE(lp.provider_user_id, 'base64') = astaff.decider_pub))" + " WHERE ka.h_payto=$1" + " AND ka.kyc_attributes_serial_id < $2" + " ORDER BY ka.kyc_attributes_serial_id DESC" + " LIMIT $3"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + stmt, + params, + &handle_aml_attributes, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_aml_decisions.c b/src/exchangedb/select_aml_decisions.c @@ -0,0 +1,250 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_aml_decisions.c + * @brief Implementation of the select_aml_decisions function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_aml_decisions.h" +#include "pg_helper.h" + + +/** + * Closure for #handle_aml_result. + */ +struct AmlProcessResultContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlDecisionCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #EXCHANGEDB_select_aml_decisions(). + * + * @param cls closure of type `struct AmlProcessResultContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_aml_result (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct AmlProcessResultContext *ctx = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_NormalizedPaytoHashP h_payto; + uint64_t rowid; + char *justification = NULL; + struct GNUNET_TIME_Timestamp decision_time; + struct GNUNET_TIME_Absolute expiration_time; + json_t *jproperties = NULL; + bool is_wallet; + bool to_investigate; + bool is_active; + json_t *account_rules; + struct TALER_FullPayto payto; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("outcome_serial_id", + &rowid), + GNUNET_PQ_result_spec_auto_from_type ("h_payto", + &h_payto), + GNUNET_PQ_result_spec_bool ("is_wallet", + &is_wallet), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("justification", + &justification), + NULL), + GNUNET_PQ_result_spec_timestamp ("decision_time", + &decision_time), + GNUNET_PQ_result_spec_absolute_time ("expiration_time", + &expiration_time), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("jproperties", + &jproperties), + NULL), + TALER_PQ_result_spec_json ("jnew_rules", + &account_rules), + GNUNET_PQ_result_spec_bool ("to_investigate", + &to_investigate), + GNUNET_PQ_result_spec_bool ("is_active", + &is_active), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto.full_payto), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->status = GNUNET_SYSERR; + return; + } + if (GNUNET_TIME_absolute_is_past (expiration_time)) + is_active = false; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Returning AML decisions for `%s' (%s)\n", + TALER_B2S (&h_payto), + is_wallet + ? "wallet" + : "account"); + ctx->cb (ctx->cb_cls, + rowid, + justification, + &h_payto, + decision_time, + expiration_time, + jproperties, + to_investigate, + is_active, + is_wallet, + payto, + account_rules); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aml_decisions (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + enum TALER_EXCHANGE_YesNoAll investigation_only, + enum TALER_EXCHANGE_YesNoAll active_only, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlDecisionCallback cb, + void *cb_cls) +{ + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_bool (NULL == h_payto), + NULL == h_payto + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_ALL == + investigation_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_YES == + investigation_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_ALL == + active_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_YES == + active_only)), + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_end + }; + struct AmlProcessResultContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + const char *stmt = (limit > 0) + ? "select_aml_decisions_inc" + : "select_aml_decisions_dec"; + + PREPARE (ctx, + "select_aml_decisions_inc", + "SELECT" + " lo.outcome_serial_id" + ",lo.h_payto" + ",ah.justification" + ",lo.decision_time" + ",lo.expiration_time" + ",lo.jproperties::TEXT" + ",lo.to_investigate" + ",lo.is_active" + ",lo.jnew_rules::TEXT" + ",kt.is_wallet" + ",wt.payto_uri" + " FROM legitimization_outcomes lo" + " JOIN kyc_targets kt" + " ON (lo.h_payto = kt.h_normalized_payto)" + " JOIN wire_targets wt" + " ON (lo.h_payto = wt.h_normalized_payto)" + " LEFT JOIN aml_history ah" + " USING (outcome_serial_id)" + " WHERE (outcome_serial_id > $7)" + " AND ($1 OR (lo.h_payto = $2))" + " AND ($3 OR (lo.to_investigate = $4))" + " AND ($5 OR (lo.is_active = $6))" + " ORDER BY lo.outcome_serial_id ASC" + " LIMIT $8"); + PREPARE (ctx, + "select_aml_decisions_dec", + "SELECT" + " lo.outcome_serial_id" + ",lo.h_payto" + ",ah.justification" + ",lo.decision_time" + ",lo.expiration_time" + ",lo.jproperties::TEXT" + ",lo.to_investigate" + ",lo.is_active" + ",lo.jnew_rules::TEXT" + ",kt.is_wallet" + ",wt.payto_uri" + " FROM legitimization_outcomes lo" + " JOIN kyc_targets kt" + " ON (lo.h_payto = kt.h_normalized_payto)" + " JOIN wire_targets wt" + " ON (lo.h_payto = wt.h_normalized_payto)" + " LEFT JOIN aml_history ah" + " USING (outcome_serial_id)" + " WHERE lo.outcome_serial_id < $7" + " AND ($1 OR (lo.h_payto = $2))" + " AND ($3 OR (lo.to_investigate = $4))" + " AND ($5 OR (lo.is_active = $6))" + " ORDER BY lo.outcome_serial_id DESC" + " LIMIT $8"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + stmt, + params, + &handle_aml_result, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_aml_measures.c b/src/exchangedb/select_aml_measures.c @@ -0,0 +1,187 @@ +/* + This file is part of TALER + Copyright (C) 2024, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_aml_measures.c + * @brief Implementation of the select_aml_measures function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_aml_measures.h" +#include "pg_helper.h" + + +/** + * Closure for #handle_aml_result. + */ +struct LegiMeasureResultContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_LegitimizationMeasureCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #EXCHANGEDB_select_aml_measures(). + * + * @param cls closure of type `struct LegiMeasureResultContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_aml_result (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct LegiMeasureResultContext *ctx = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_NormalizedPaytoHashP h_payto; + uint64_t rowid; + struct GNUNET_TIME_Absolute start_time; + json_t *jmeasures; + bool is_finished; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("legitimization_measure_serial_id", + &rowid), + GNUNET_PQ_result_spec_auto_from_type ("h_normalized_payto", + &h_payto), + GNUNET_PQ_result_spec_absolute_time ("start_time", + &start_time), + TALER_PQ_result_spec_json ("jmeasures", + &jmeasures), + GNUNET_PQ_result_spec_bool ("is_finished", + &is_finished), + 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, + &h_payto, + start_time, + jmeasures, + is_finished, + rowid); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aml_measures (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + enum TALER_EXCHANGE_YesNoAll active_only, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_LegitimizationMeasureCallback cb, + void *cb_cls) +{ + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_bool (NULL == h_payto), + NULL == h_payto + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_ALL == + active_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_NO == + active_only)), + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_end + }; + struct LegiMeasureResultContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + const char *stmt = (limit > 0) + ? "select_aml_measures_inc" + : "select_aml_measures_dec"; + + PREPARE (ctx, + "select_aml_measures_inc", + "SELECT" + " lm.legitimization_measure_serial_id" + ",kt.h_normalized_payto" + ",lm.jmeasures::TEXT" + ",lm.start_time" + ",lm.is_finished" + " FROM kyc_targets kt" + " JOIN legitimization_measures lm" + " USING (access_token)" + " WHERE (legitimization_measure_serial_id > $5)" + " AND ($1 OR (kt.h_normalized_payto = $2))" + " AND ($3 OR (lm.is_finished = $4))" + " ORDER BY lm.legitimization_measure_serial_id ASC" + " LIMIT $6"); + PREPARE (ctx, + "select_aml_measures_dec", + "SELECT" + " lm.legitimization_measure_serial_id" + ",kt.h_normalized_payto" + ",lm.jmeasures::TEXT" + ",lm.start_time" + ",lm.is_finished" + " FROM kyc_targets kt" + " JOIN legitimization_measures lm" + " USING (access_token)" + " WHERE (legitimization_measure_serial_id < $5)" + " AND ($1 OR (kt.h_normalized_payto = $2))" + " AND ($3 OR (lm.is_finished = $4))" + " ORDER BY lm.legitimization_measure_serial_id DESC" + " LIMIT $6"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + stmt, + params, + &handle_aml_result, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_aml_statistics.c b/src/exchangedb/select_aml_statistics.c @@ -0,0 +1,144 @@ +/* + This file is part of TALER + Copyright (C) 2024, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_aml_statistics.c + * @brief Implementation of the select_aml_statistics function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_aml_statistics.h" +#include "pg_helper.h" + + +/** + * Closure for #get_statistics_cb(). + */ +struct GetStatisticsContext +{ + /** + * Function to call per result. + */ + TALER_EXCHANGEDB_AmlStatisticsCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + + +/** + * Invoke the callback for each result. + * + * @param cls a `struct GetStatisticsContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +get_statistics_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct GetStatisticsContext *ctx = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t val; + char *name; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("name", + &name), + GNUNET_PQ_result_spec_uint64 ("value", + &val), + 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, + name, + val); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aml_statistics (struct EXCHANGEDB_PostgresContext *ctx, + size_t num_names, + const char *names[static num_names], + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + TALER_EXCHANGEDB_AmlStatisticsCallback cb, + void *cb_cls) +{ + struct GetStatisticsContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_array_ptrs_string (num_names, + names, + ctx->conn), + GNUNET_PQ_query_param_timestamp (&start_date), + GNUNET_PQ_query_param_timestamp (&end_date), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_aml_statistics", + "SELECT " + " event_type AS name" + ",COUNT(*) AS value" + " FROM kyc_events" + " WHERE event_type = ANY ($1)" + " AND event_timestamp >= $2" + " AND event_timestamp < $3" + " GROUP BY event_type;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "select_aml_statistics", + params, + &get_statistics_cb, + &ctx); + GNUNET_PQ_cleanup_query_params_closures (params); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_auditor_denom_sig.c b/src/exchangedb/select_auditor_denom_sig.c @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_auditor_denom_sig.c + * @brief Implementation of the select_auditor_denom_sig function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_auditor_denom_sig.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_auditor_denom_sig (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_AuditorPublicKeyP *auditor_pub, + struct TALER_AuditorSignatureP *auditor_sig) +{ + 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 + }; + + PREPARE (ctx, + "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" + " WHERE denom_pub_hash=$2);"); + + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "select_auditor_denom_sig", + params, + rs); +} diff --git a/src/exchangedb/select_batch_deposits_missing_wire.c b/src/exchangedb/select_batch_deposits_missing_wire.c @@ -0,0 +1,142 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_batch_deposits_missing_wire.c + * @brief Implementation of the select_batch_deposits_missing_wire function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_batch_deposits_missing_wire.h" +#include "pg_helper.h" + +/** + * Closure for #missing_wire_cb(). + */ +struct MissingWireContext +{ + /** + * Function to call per result. + */ + TALER_EXCHANGEDB_WireMissingCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on error. + */ + 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 +missing_wire_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct MissingWireContext *mwc = cls; + struct EXCHANGEDB_PostgresContext *ctx = mwc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t batch_deposit_serial_id; + struct GNUNET_TIME_Timestamp deadline; + struct TALER_FullPaytoHashP wire_target_h_payto; + struct TALER_Amount total_amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("batch_deposit_serial_id", + &batch_deposit_serial_id), + GNUNET_PQ_result_spec_auto_from_type ("wire_target_h_payto", + &wire_target_h_payto), + GNUNET_PQ_result_spec_timestamp ("deadline", + &deadline), + TALER_PQ_RESULT_SPEC_AMOUNT ("total_amount", + &total_amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + mwc->status = GNUNET_SYSERR; + return; + } + mwc->cb (mwc->cb_cls, + batch_deposit_serial_id, + &total_amount, + &wire_target_h_payto, + deadline); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_batch_deposits_missing_wire (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t min_batch_deposit_serial_id, + TALER_EXCHANGEDB_WireMissingCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&min_batch_deposit_serial_id), + GNUNET_PQ_query_param_end + }; + struct MissingWireContext mwc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "deposits_get_deposits_missing_wire", + "SELECT" + " batch_deposit_serial_id" + ",wire_target_h_payto" + ",deadline" + ",total_amount" + " FROM exchange_do_select_deposits_missing_wire" + " ($1);"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "deposits_get_deposits_missing_wire", + params, + &missing_wire_cb, + &mwc); + if (GNUNET_OK != mwc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_coin_deposits_above_serial_id.c b/src/exchangedb/select_coin_deposits_above_serial_id.c @@ -0,0 +1,202 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_coin_deposits_above_serial_id.c + * @brief Implementation of the select_coin_deposits_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_coin_deposits_above_serial_id.h" +#include "pg_helper.h" + +/** + * Closure for #deposit_serial_helper_cb(). + */ +struct CoinDepositSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_DepositCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct CoinDepositSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +coin_deposit_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct CoinDepositSerialContext *dsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = dsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_Deposit deposit; + struct GNUNET_TIME_Timestamp exchange_timestamp; + struct TALER_DenominationPublicKey denom_pub; + bool done; + uint64_t rowid; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &deposit.amount_with_fee), + GNUNET_PQ_result_spec_timestamp ("wallet_timestamp", + &deposit.timestamp), + GNUNET_PQ_result_spec_timestamp ("exchange_timestamp", + &exchange_timestamp), + GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", + &deposit.merchant_pub), + TALER_PQ_result_spec_denom_pub ("denom_pub", + &denom_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", + &deposit.coin.coin_pub), + 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), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("wallet_data_hash", + &deposit.wallet_data_hash), + &deposit.no_wallet_data_hash), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &deposit.csig), + GNUNET_PQ_result_spec_timestamp ("refund_deadline", + &deposit.refund_deadline), + GNUNET_PQ_result_spec_timestamp ("wire_deadline", + &deposit.wire_deadline), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &deposit.h_contract_terms), + GNUNET_PQ_result_spec_auto_from_type ("wire_salt", + &deposit.wire_salt), + GNUNET_PQ_result_spec_string ("receiver_wire_account", + &deposit.receiver_wire_account.full_payto), + GNUNET_PQ_result_spec_bool ("done", + &done), + GNUNET_PQ_result_spec_uint64 ("coin_deposit_serial_id", + &rowid), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + memset (&deposit, + 0, + sizeof (deposit)); + 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, + exchange_timestamp, + &deposit, + &denom_pub, + done); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_coin_deposits_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_DepositCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct CoinDepositSerialContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + /* Fetch deposits with rowid '\geq' the given parameter */ + PREPARE (ctx, + "audit_get_coin_deposits_incr", + "SELECT" + " cdep.amount_with_fee" + ",bdep.wallet_timestamp" + ",bdep.exchange_timestamp" + ",bdep.merchant_pub" + ",bdep.wallet_data_hash" + ",denom.denom_pub" + ",kc.coin_pub" + ",kc.age_commitment_hash" + ",cdep.coin_sig" + ",bdep.refund_deadline" + ",bdep.wire_deadline" + ",bdep.h_contract_terms" + ",bdep.wire_salt" + ",wt.payto_uri AS receiver_wire_account" + ",bdep.done" + ",cdep.coin_deposit_serial_id" + " FROM coin_deposits cdep" + " JOIN batch_deposits bdep" + " USING (batch_deposit_serial_id)" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " JOIN known_coins kc" + " USING (coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " WHERE (coin_deposit_serial_id>=$1)" + " ORDER BY coin_deposit_serial_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_coin_deposits_incr", + params, + &coin_deposit_serial_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_contract.c b/src/exchangedb/select_contract.c @@ -0,0 +1,65 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_contract.c + * @brief Implementation of the select_contract function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_contract.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_contract (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ContractDiffiePublicP *pub_ckey, + struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseContractSignatureP *econtract_sig, + size_t *econtract_size, + void **econtract) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (pub_ckey), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + purse_pub), + GNUNET_PQ_result_spec_auto_from_type ("contract_sig", + econtract_sig), + GNUNET_PQ_result_spec_variable_size ("e_contract", + econtract, + econtract_size), + GNUNET_PQ_result_spec_end + }; + + /* Used in #postgres_select_contract */ + PREPARE (ctx, + "select_contract", + "SELECT " + " purse_pub" + ",e_contract" + ",contract_sig" + " FROM contracts" + " WHERE pub_ckey=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "select_contract", + params, + rs); + +} diff --git a/src/exchangedb/select_contract_by_purse.c b/src/exchangedb/select_contract_by_purse.c @@ -0,0 +1,61 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_contract_by_purse.c + * @brief Implementation of the select_contract_by_purse function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_contract_by_purse.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_contract_by_purse (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_EncryptedContract *econtract) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("pub_ckey", + &econtract->contract_pub), + GNUNET_PQ_result_spec_auto_from_type ("contract_sig", + &econtract->econtract_sig), + GNUNET_PQ_result_spec_variable_size ("e_contract", + &econtract->econtract, + &econtract->econtract_size), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "select_contract_by_purse", + "SELECT " + " pub_ckey" + ",e_contract" + ",contract_sig" + " FROM contracts" + " WHERE purse_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "select_contract_by_purse", + params, + rs); + +} diff --git a/src/exchangedb/select_deposit_amounts_for_kyc_check.c b/src/exchangedb/select_deposit_amounts_for_kyc_check.c @@ -0,0 +1,155 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_deposit_amounts_for_kyc_check.c + * @brief Implementation of the select_deposit_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_deposit_amounts_for_kyc_check.h" +#include "pg_helper.h" + +/** + * Closure for #get_kyc_amounts_cb(). + */ +struct KycAmountCheckContext +{ + /** + * Function to call per result. + */ + TALER_EXCHANGEDB_KycAmountCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + +/** + * Invoke the callback for each result. + * + * @param cls a `struct KycAmountCheckContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +get_kyc_amounts_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct KycAmountCheckContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct GNUNET_TIME_Absolute date; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_absolute_time ("date", + &date), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->status = GNUNET_SYSERR; + return; + } + ret = ctx->cb (ctx->cb_cls, + &amount, + date); + GNUNET_PQ_cleanup_result (rs); + switch (ret) + { + case GNUNET_OK: + continue; + case GNUNET_NO: + break; + case GNUNET_SYSERR: + ctx->status = GNUNET_SYSERR; + break; + } + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_deposit_amounts_for_kyc_check (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_absolute_time (&time_limit), + GNUNET_PQ_query_param_end + }; + struct KycAmountCheckContext ctx = { + .cb = kac, + .cb_cls = kac_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_kyc_relevant_deposit_events", + "SELECT" + " cd.amount_with_fee AS amount" + ",bd.exchange_timestamp AS date" + " FROM batch_deposits bd" + " JOIN coin_deposits cd" + " USING (batch_deposit_serial_id)" + " WHERE wire_target_h_payto IN (" + " SELECT wire_target_h_payto" + " FROM wire_targets" + " WHERE h_normalized_payto=$1" + " )" + " AND bd.exchange_timestamp >= $2" + " ORDER BY bd.exchange_timestamp DESC"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_kyc_relevant_deposit_events", + params, + &get_kyc_amounts_cb, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_exchange_credit_transfers.c b/src/exchangedb/select_exchange_credit_transfers.c @@ -0,0 +1,182 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_exchange_credit_transfers.c + * @brief Implementation of the select_exchange_credit_transfers function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_exchange_credit_transfers.h" +#include "pg_helper.h" + +/** + * Closure for #handle_aml_result. + */ +struct SelectTransferContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlTransferCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #EXCHANGEDB_select_exchange_debit_transfers(). + * + * @param cls closure of type `struct SelectTransferContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_transfer_result (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct SelectTransferContext *stc = cls; + struct EXCHANGEDB_PostgresContext *ctx = stc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + char *payto_uri; + uint64_t rowid; + struct GNUNET_TIME_Absolute execution_time; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial_id", + &rowid), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri), + GNUNET_PQ_result_spec_absolute_time ("execution_time", + &execution_time), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + stc->status = GNUNET_SYSERR; + return; + } + stc->cb (stc->cb_cls, + rowid, + payto_uri, + execution_time, + &amount); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_exchange_credit_transfers (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls) +{ + struct SelectTransferContext stc = { + .ctx = ctx, + .cb = cb, + .cb_cls = cb_cls, + .status = GNUNET_OK + }; + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + TALER_PQ_query_param_amount (ctx->conn, + threshold), + NULL != h_payto + ? GNUNET_PQ_query_param_auto_from_type (h_payto) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_exchange_credit_transfers_inc", + "SELECT" + " ri.reserve_in_serial_id AS serial_id" + ",wt.payto_uri" + ",ri.execution_date AS execution_time" + ",ri.credit AS amount" + " FROM reserves_in ri" + " LEFT JOIN wire_targets wt" + " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE (ri.reserve_in_serial_id > $1)" + " AND ( ($4::BYTEA IS NULL) OR (wt.h_normalized_payto=$4) )" + " AND ( ( (ri.credit).val > ($3::taler_amount).val)" + " OR ( ( (ri.credit).val >= ($3::taler_amount).val)" + " AND ( (ri.credit).frac >= ($3::taler_amount).frac) ) )" + " ORDER BY ri.reserve_in_serial_id ASC" + " LIMIT $2"); + PREPARE (ctx, + "select_exchange_credit_transfers_dec", + "SELECT" + " ri.reserve_in_serial_id AS serial_id" + ",wt.payto_uri" + ",ri.execution_date AS execution_time" + ",ri.credit AS amount" + " FROM reserves_in ri" + " LEFT JOIN wire_targets wt" + " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE (ri.reserve_in_serial_id < $1)" + " AND ( ($4::BYTEA IS NULL) OR (wt.h_normalized_payto=$4) )" + " AND ( ( (ri.credit).val > ($3::taler_amount).val)" + " OR ( ( (ri.credit).val >= ($3::taler_amount).val)" + " AND ( (ri.credit).frac >= ($3::taler_amount).frac) ) )" + " ORDER BY ri.reserve_in_serial_id DESC" + " LIMIT $2"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "select_exchange_credit_transfers_inc" + : "select_exchange_credit_transfers_dec", + params, + &handle_transfer_result, + &stc); + if (GNUNET_OK != stc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_exchange_debit_transfers.c b/src/exchangedb/select_exchange_debit_transfers.c @@ -0,0 +1,183 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_exchange_debit_transfers.c + * @brief Implementation of the select_exchange_debit_transfers function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_exchange_debit_transfers.h" +#include "pg_helper.h" + + +/** + * Closure for #handle_aml_result. + */ +struct SelectTransferContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlTransferCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #EXCHANGEDB_select_exchange_debit_transfers(). + * + * @param cls closure of type `struct SelectTransferContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_transfer_result (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct SelectTransferContext *stc = cls; + struct EXCHANGEDB_PostgresContext *ctx = stc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + char *payto_uri; + uint64_t rowid; + struct GNUNET_TIME_Absolute execution_time; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial_id", + &rowid), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri), + GNUNET_PQ_result_spec_absolute_time ("execution_time", + &execution_time), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + stc->status = GNUNET_SYSERR; + return; + } + stc->cb (stc->cb_cls, + rowid, + payto_uri, + execution_time, + &amount); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_exchange_debit_transfers (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls) +{ + struct SelectTransferContext stc = { + .ctx = ctx, + .cb = cb, + .cb_cls = cb_cls, + .status = GNUNET_OK + }; + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + TALER_PQ_query_param_amount (ctx->conn, + threshold), + NULL != h_payto + ? GNUNET_PQ_query_param_auto_from_type (h_payto) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_exchange_debit_transfers_inc", + "SELECT" + " wo.wireout_uuid AS serial_id" + ",wt.payto_uri" + ",wo.execution_date AS execution_time" + ",wo.amount" + " FROM wire_out wo" + " LEFT JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " WHERE (wo.wireout_uuid > $1)" + " AND ( ($4::BYTEA IS NULL) OR (wt.h_normalized_payto=$4) )" + " AND ( ( (wo.amount).val > ($3::taler_amount).val)" + " OR ( ( (wo.amount).val >= ($3::taler_amount).val)" + " AND ( (wo.amount).frac >= ($3::taler_amount).frac) ) )" + " ORDER BY wo.wireout_uuid ASC" + " LIMIT $2"); + PREPARE (ctx, + "select_exchange_debit_transfers_dec", + "SELECT" + " wo.wireout_uuid AS serial_id" + ",wt.payto_uri" + ",wo.execution_date AS execution_time" + ",wo.amount" + " FROM wire_out wo" + " LEFT JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " WHERE (wo.wireout_uuid < $1)" + " AND ( ($4::BYTEA IS NULL) OR (wt.h_normalized_payto=$4) )" + " AND ( ( (wo.amount).val > ($3::taler_amount).val)" + " OR ( ( (wo.amount).val >= ($3::taler_amount).val)" + " AND ( (wo.amount).frac >= ($3::taler_amount).frac) ) )" + " ORDER BY wo.wireout_uuid DESC" + " LIMIT $2"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "select_exchange_debit_transfers_inc" + : "select_exchange_debit_transfers_dec", + params, + &handle_transfer_result, + &stc); + if (GNUNET_OK != stc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_exchange_kycauth_transfers.c b/src/exchangedb/select_exchange_kycauth_transfers.c @@ -0,0 +1,182 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_exchange_kycauth_transfers.c + * @brief Implementation of the select_exchange_kycauth_transfers function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_exchange_kycauth_transfers.h" +#include "pg_helper.h" + +/** + * Closure for #handle_aml_result. + */ +struct SelectTransferContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlTransferCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #EXCHANGEDB_select_exchange_debit_transfers(). + * + * @param cls closure of type `struct SelectTransferContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_transfer_result (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct SelectTransferContext *stc = cls; + struct EXCHANGEDB_PostgresContext *ctx = stc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + char *payto_uri; + uint64_t rowid; + struct GNUNET_TIME_Absolute execution_time; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("serial_id", + &rowid), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri), + GNUNET_PQ_result_spec_absolute_time ("execution_time", + &execution_time), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + stc->status = GNUNET_SYSERR; + return; + } + stc->cb (stc->cb_cls, + rowid, + payto_uri, + execution_time, + &amount); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_exchange_kycauth_transfers (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls) +{ + struct SelectTransferContext stc = { + .ctx = ctx, + .cb = cb, + .cb_cls = cb_cls, + .status = GNUNET_OK + }; + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + TALER_PQ_query_param_amount (ctx->conn, + threshold), + NULL != h_payto + ? GNUNET_PQ_query_param_auto_from_type (h_payto) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_exchange_kycauth_transfers_inc", + "SELECT" + " ki.kycauth_in_serial_id AS serial_id" + ",wt.payto_uri" + ",ki.execution_date AS execution_time" + ",ki.credit AS amount" + " FROM kycauths_in ki" + " LEFT JOIN wire_targets wt" + " ON (ki.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE (ki.kycauth_in_serial_id > $1)" + " AND ( ($4::BYTEA IS NULL) OR (wt.h_normalized_payto=$4) )" + " AND ( ( (ki.credit).val > ($3::taler_amount).val)" + " OR ( ( (ki.credit).val >= ($3::taler_amount).val)" + " AND ( (ki.credit).frac >= ($3::taler_amount).frac) ) )" + " ORDER BY ki.kycauth_in_serial_id ASC" + " LIMIT $2"); + PREPARE (ctx, + "select_exchange_kycauth_transfers_dec", + "SELECT" + " ki.kycauth_in_serial_id AS serial_id" + ",wt.payto_uri" + ",ki.execution_date AS execution_time" + ",ki.credit AS amount" + " FROM kycauths_in ki" + " LEFT JOIN wire_targets wt" + " ON (ki.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE (ki.kycauth_in_serial_id < $1)" + " AND ( ($4::BYTEA IS NULL) OR (wt.h_normalized_payto=$4) )" + " AND ( ( (ki.credit).val > ($3::taler_amount).val)" + " OR ( ( (ki.credit).val >= ($3::taler_amount).val)" + " AND ( (ki.credit).frac >= ($3::taler_amount).frac) ) )" + " ORDER BY ki.kycauth_in_serial_id DESC" + " LIMIT $2"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + (limit > 0) + ? "select_exchange_kycauth_transfers_inc" + : "select_exchange_kycauth_transfers_dec", + params, + &handle_transfer_result, + &stc); + if (GNUNET_OK != stc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_kyc_accounts.c b/src/exchangedb/select_kyc_accounts.c @@ -0,0 +1,237 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_kyc_accounts.c + * @brief Implementation of the select_kyc_accounts function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_kyc_accounts.h" +#include "pg_helper.h" + + +/** + * Closure for #handle_aml_result. + */ +struct KycAccountResultContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlAccountListCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Set to #GNUNET_SYSERR on serious errors. + */ + enum GNUNET_GenericReturnValue status; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. Helper function + * for #EXCHANGEDB_select_kyc_accounts(). + * + * @param cls closure of type `struct KycAccountResultContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_kyc_account_result (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct KycAccountResultContext *ctx = cls; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct TALER_NormalizedPaytoHashP h_payto; + char *comments = NULL; + struct GNUNET_TIME_Timestamp open_time + = GNUNET_TIME_UNIT_FOREVER_TS; + struct GNUNET_TIME_Timestamp close_time + = GNUNET_TIME_UNIT_FOREVER_TS; + bool to_investigate; + bool high_risk; + struct TALER_FullPayto payto; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("kyc_target_serial_id", + &rowid), + GNUNET_PQ_result_spec_auto_from_type ("h_payto", + &h_payto), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("comments", + &comments), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_timestamp ("open_time", + &open_time), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_timestamp ("close_time", + &close_time), + NULL), + GNUNET_PQ_result_spec_bool ("to_investigate", + &to_investigate), + GNUNET_PQ_result_spec_bool ("high_risk", + &high_risk), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto.full_payto), + 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, + rowid, + &h_payto, + open_time, + close_time, + comments, + high_risk, + to_investigate, + payto); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_kyc_accounts (struct EXCHANGEDB_PostgresContext *ctx, + enum TALER_EXCHANGE_YesNoAll investigation_only, + enum TALER_EXCHANGE_YesNoAll open_only, + enum TALER_EXCHANGE_YesNoAll high_risk_only, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlAccountListCallback cb, + void *cb_cls) +{ + uint64_t ulimit = (limit > 0) ? limit : -limit; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&offset), + GNUNET_PQ_query_param_uint64 (&ulimit), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_ALL == + investigation_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_YES == + investigation_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_ALL == + open_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_YES == + open_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_ALL == + high_risk_only)), + GNUNET_PQ_query_param_bool ((TALER_EXCHANGE_YNA_YES == + high_risk_only)), + GNUNET_PQ_query_param_end + }; + struct KycAccountResultContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + const char *stmt = (limit > 0) + ? "select_kyc_accounts_inc" + : "select_kyc_accounts_dec"; + + PREPARE (ctx, + "select_kyc_accounts_inc", + "SELECT" + " kt.kyc_target_serial_id" + ",kt.h_normalized_payto AS h_payto" + ",kt.open_time" + ",kt.close_time" + ",lo.jproperties ->> 'FILE_NOTE' AS comments" + ",lo.jproperties ->> 'open_date' AS open_time" + ",COALESCE(lo.to_investigate,FALSE) AS to_investigate" + ",COALESCE((lo.jproperties ->> 'HIGH_RISK_CUSTOMER')::bool,FALSE) AS high_risk" + ",wt.payto_uri" + " FROM kyc_targets kt" + " JOIN wire_targets wt" + " ON (wt.h_normalized_payto = kt.h_normalized_payto)" + " LEFT JOIN legitimization_outcomes lo" + " ON (lo.h_payto = kt.h_normalized_payto)" + " WHERE (kyc_target_serial_id > $1)" + // select most recent outcomes only + " AND COALESCE (lo.is_active, TRUE)" + " AND ($3 OR (COALESCE(lo.to_investigate,FALSE) = $4))" + // Account is open if we had an AML outcome + " AND ($5 OR ((lo.outcome_serial_id IS NULL) = $6))" + " AND ($7 OR ((COALESCE((lo.jproperties ->>'high_risk')::bool,FALSE) = $8)))" + " ORDER BY kt.kyc_target_serial_id ASC" + " LIMIT $2"); + PREPARE (ctx, + "select_kyc_accounts_dec", + "SELECT" + " kt.kyc_target_serial_id" + ",kt.h_normalized_payto AS h_payto" + ",kt.open_time" + ",kt.close_time" + ",lo.jproperties ->> 'FILE_NOTE' AS comments" + ",lo.jproperties ->> 'open_date' AS open_time" + ",COALESCE(lo.to_investigate,FALSE) AS to_investigate" + ",COALESCE((lo.jproperties ->> 'HIGH_RISK_CUSTOMER')::bool,FALSE) AS high_risk" + ",wt.payto_uri" + " FROM kyc_targets kt" + " LEFT JOIN legitimization_outcomes lo" + " ON (lo.h_payto = kt.h_normalized_payto)" + " LEFT JOIN LATERAL (" + " SELECT payto_uri" + " FROM wire_targets" + " WHERE h_normalized_payto = kt.h_normalized_payto" + " ORDER BY wire_target_serial_id DESC" + " LIMIT 1" + " ) wt ON true" + " WHERE (kyc_target_serial_id < $1)" + // select most recent outcomes only + " AND COALESCE (lo.is_active, TRUE)" + " AND ($3 OR (COALESCE(lo.to_investigate,FALSE) = $4))" + // Account is open if we had an AML outcome + " AND ($5 OR ((lo.outcome_serial_id IS NULL) = $6))" + " AND ($7 OR ((COALESCE((lo.jproperties ->>'high_risk')::bool,FALSE) = $8)))" + " ORDER BY kt.kyc_target_serial_id DESC" + " LIMIT $2"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + stmt, + params, + &handle_kyc_account_result, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_kyc_attributes.c b/src/exchangedb/select_kyc_attributes.c @@ -0,0 +1,156 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_kyc_attributes.c + * @brief Implementation of the select_kyc_attributes function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_kyc_attributes.h" +#include "pg_helper.h" + + +/** + * Closure for #get_attributes_cb(). + */ +struct GetAttributesContext +{ + /** + * Function to call per result. + */ + TALER_EXCHANGEDB_AttributeCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Key of our query. + */ + const struct TALER_NormalizedPaytoHashP *h_payto; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + + +/** + * Invoke the callback for each result. + * + * @param cls a `struct GetAttributesContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +get_attributes_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct GetAttributesContext *ctx = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + struct GNUNET_TIME_Timestamp collection_time; + struct GNUNET_TIME_Timestamp expiration_time; + size_t enc_attributes_size; + void *enc_attributes; + char *provider; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("provider_name", + &provider), + GNUNET_PQ_result_spec_timestamp ("collection_time", + &collection_time), + GNUNET_PQ_result_spec_timestamp ("expiration_time", + &expiration_time), + GNUNET_PQ_result_spec_variable_size ("encrypted_attributes", + &enc_attributes, + &enc_attributes_size), + 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, + ctx->h_payto, + provider, + collection_time, + expiration_time, + enc_attributes_size, + enc_attributes); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_kyc_attributes (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_AttributeCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + struct GetAttributesContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .h_payto = h_payto, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_kyc_attributes", + "SELECT " + " lp.provider_name" + ",ka.collection_time" + ",ka.expiration_time" + ",ka.encrypted_attributes" + " FROM kyc_attributes ka" + " JOIN legitimization_processes lp" + " ON (ka.legitimization_serial = lp.legitimization_process_serial_id)" + " WHERE ka.h_payto=$1"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_kyc_attributes", + params, + &get_attributes_cb, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_merge_amounts_for_kyc_check.c b/src/exchangedb/select_merge_amounts_for_kyc_check.c @@ -0,0 +1,154 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_merge_amounts_for_kyc_check.c + * @brief Implementation of the select_merge_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_merge_amounts_for_kyc_check.h" +#include "pg_helper.h" + + +/** + * Closure for #get_kyc_amounts_cb(). + */ +struct KycAmountCheckContext +{ + /** + * Function to call per result. + */ + TALER_EXCHANGEDB_KycAmountCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + +/** + * Invoke the callback for each result. + * + * @param cls a `struct KycAmountCheckContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +get_kyc_amounts_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct KycAmountCheckContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct GNUNET_TIME_Absolute date; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_absolute_time ("date", + &date), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->status = GNUNET_SYSERR; + return; + } + ret = ctx->cb (ctx->cb_cls, + &amount, + date); + GNUNET_PQ_cleanup_result (rs); + switch (ret) + { + case GNUNET_OK: + continue; + case GNUNET_NO: + break; + case GNUNET_SYSERR: + ctx->status = GNUNET_SYSERR; + break; + } + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_merge_amounts_for_kyc_check (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_absolute_time (&time_limit), + GNUNET_PQ_query_param_end + }; + struct KycAmountCheckContext ctx = { + .cb = kac, + .cb_cls = kac_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_kyc_relevant_merge_events", + "SELECT" + " amount_with_fee AS amount" + ",merge_timestamp AS date" + " FROM account_merges" + " JOIN purse_merges USING (purse_pub)" + " JOIN purse_requests USING (purse_pub)" + " JOIN purse_decision USING (purse_pub)" + " WHERE wallet_h_payto=$1" + " AND merge_timestamp >= $2" + " AND NOT refunded" + " ORDER BY merge_timestamp DESC"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_kyc_relevant_merge_events", + params, + &get_kyc_amounts_cb, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_purse.c b/src/exchangedb/select_purse.c @@ -0,0 +1,92 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_purse.c + * @brief Implementation of the select_purse function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp *purse_creation, + struct GNUNET_TIME_Timestamp *purse_expiration, + struct TALER_Amount *amount, + struct TALER_Amount *deposited, + struct TALER_PrivateContractHashP *h_contract_terms, + struct GNUNET_TIME_Timestamp *merge_timestamp, + bool *purse_deleted, + bool *purse_refunded) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_timestamp ("purse_expiration", + purse_expiration), + GNUNET_PQ_result_spec_timestamp ("purse_creation", + purse_creation), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + deposited), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + h_contract_terms), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_timestamp ("merge_timestamp", + merge_timestamp), + NULL), + GNUNET_PQ_result_spec_bool ("purse_deleted", + purse_deleted), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_bool ("purse_refunded", + purse_refunded), + NULL), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "select_purse", + "SELECT " + " pr.merge_pub" + ",pr.purse_creation" + ",pr.purse_expiration" + ",pr.h_contract_terms" + ",pr.amount_with_fee" + ",pr.balance" + ",pm.merge_timestamp" + ",pd.purse_sig IS NOT NULL AS purse_deleted" + ",pc.refunded AS purse_refunded" + " FROM purse_requests pr" + " LEFT JOIN purse_merges pm ON (pm.purse_pub = pr.purse_pub)" + " LEFT JOIN purse_decision pc ON (pc.purse_pub = pr.purse_pub)" + " LEFT JOIN purse_deletion pd ON (pd.purse_pub = pr.purse_pub)" + " WHERE pr.purse_pub=$1;"); + *merge_timestamp = GNUNET_TIME_UNIT_FOREVER_TS; + *purse_refunded = false; + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "select_purse", + params, + rs); +} diff --git a/src/exchangedb/select_purse_by_merge_pub.c b/src/exchangedb/select_purse_by_merge_pub.c @@ -0,0 +1,77 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_purse_by_merge_pub.c + * @brief Implementation of the select_purse_by_merge_pub function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse_by_merge_pub.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_by_merge_pub (struct EXCHANGEDB_PostgresContext *ctx, + 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) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (merge_pub), + GNUNET_PQ_query_param_end + }; + 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 + }; + + PREPARE (ctx, + "select_purse_by_merge_pub", + "SELECT " + " purse_pub" + ",purse_expiration" + ",h_contract_terms" + ",age_limit" + ",amount_with_fee" + ",balance" + ",purse_sig" + " FROM purse_requests" + " WHERE merge_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "select_purse_by_merge_pub", + params, + rs); +} diff --git a/src/exchangedb/select_purse_decisions_above_serial_id.c b/src/exchangedb/select_purse_decisions_above_serial_id.c @@ -0,0 +1,160 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_purse_decisions_above_serial_id.c + * @brief Implementation of the select_purse_decisions_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse_decisions_above_serial_id.h" +#include "pg_helper.h" + +/** + * Closure for #purse_decision_serial_helper_cb(). + */ +struct PurseDecisionSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_PurseDecisionCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct PurseRefundSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +purse_decision_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PurseDecisionSerialContext *dsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = dsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_ReservePublicKeyP reserve_pub; + bool no_reserve = true; + uint64_t rowid; + struct TALER_Amount val; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &purse_pub), + 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_decision_serial_id", + &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, + no_reserve ? NULL : &reserve_pub, + &val); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_decisions_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + bool refunded, + TALER_EXCHANGEDB_PurseDecisionCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_bool (refunded), + GNUNET_PQ_query_param_end + }; + struct PurseDecisionSerialContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "audit_get_purse_decisions_incr", + "SELECT" + " pd.purse_pub" + ",pm.reserve_pub" + ",pd.purse_decision_serial_id" + ",pr.amount_with_fee" + " 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)" + " WHERE (" + " (purse_decision_serial_id>=$1) AND " + " (refunded=$2)" + " )" + " ORDER BY purse_decision_serial_id ASC;"); + + + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_purse_decisions_incr", + params, + &purse_decision_serial_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_purse_deposits_above_serial_id.c b/src/exchangedb/select_purse_deposits_above_serial_id.c @@ -0,0 +1,200 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_purse_deposits_above_serial_id.c + * @brief Implementation of the select_purse_deposits_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse_deposits_above_serial_id.h" +#include "pg_helper.h" + +/** + * Closure for #purse_deposit_serial_helper_cb(). + */ +struct PurseDepositSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_PurseDepositCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct DepositSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +purse_deposit_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PurseDepositSerialContext *dsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = dsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_PurseDeposit deposit = { + .exchange_base_url = NULL + }; + struct TALER_DenominationPublicKey denom_pub; + uint64_t rowid; + uint32_t flags32; + struct TALER_ReservePublicKeyP reserve_pub; + bool not_merged = false; + struct TALER_Amount purse_balance; + struct TALER_Amount purse_total; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &deposit.amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + &purse_balance), + TALER_PQ_RESULT_SPEC_AMOUNT ("total", + &purse_total), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + &deposit.deposit_fee), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("partner_base_url", + &deposit.exchange_base_url), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + &not_merged), + TALER_PQ_result_spec_denom_pub ("denom_pub", + &denom_pub), + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &deposit.purse_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &deposit.coin_sig), + GNUNET_PQ_result_spec_uint32 ("flags", + &flags32), + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", + &deposit.coin_pub), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &deposit.h_age_commitment), + &deposit.no_age_commitment), + GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id", + &rowid), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + memset (&deposit, + 0, + sizeof (deposit)); + 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, + &deposit, + not_merged ? NULL : &reserve_pub, + (enum TALER_WalletAccountMergeFlags) flags32, + &purse_balance, + &purse_total, + &denom_pub); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_deposits_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_PurseDepositCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct PurseDepositSerialContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "audit_get_purse_deposits_incr", + "SELECT" + " pd.amount_with_fee" + ",pr.amount_with_fee AS total" + ",pr.balance" + ",pr.flags" + ",pd.purse_pub" + ",pd.coin_sig" + ",partner_base_url" + ",denom.denom_pub" + ",denom.fee_deposit" + ",pm.reserve_pub" + ",kc.coin_pub" + ",kc.age_commitment_hash" + ",pd.purse_deposit_serial_id" + " FROM purse_deposits pd" + " LEFT JOIN partners USING (partner_serial_id)" + " LEFT JOIN purse_merges pm USING (purse_pub)" + " JOIN purse_requests pr USING (purse_pub)" + " JOIN known_coins kc USING (coin_pub)" + " JOIN denominations denom USING (denominations_serial)" + " WHERE (" + " (purse_deposit_serial_id>=$1)" + " )" + " ORDER BY purse_deposit_serial_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_purse_deposits_incr", + params, + &purse_deposit_serial_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_purse_deposits_by_purse.c b/src/exchangedb/select_purse_deposits_by_purse.c @@ -0,0 +1,151 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_purse_deposits_by_purse.c + * @brief Implementation of the select_purse_deposits_by_purse function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse_deposits_by_purse.h" +#include "pg_helper.h" + +/** + * Closure for #purse_refund_coin_helper_cb(). + */ +struct PurseRefundCoinContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_PurseRefundCoinCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct PurseRefundCoinContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +purse_refund_coin_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PurseRefundCoinContext *dsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = dsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_Amount amount_with_fee; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_DenominationPublicKey denom_pub; + uint64_t rowid; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_denom_pub ("denom_pub", + &denom_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &amount_with_fee), + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", + &coin_pub), + GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id", + &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, + &amount_with_fee, + &coin_pub, + &denom_pub); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_deposits_by_purse (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + TALER_EXCHANGEDB_PurseRefundCoinCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + struct PurseRefundCoinContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "audit_get_purse_deposits_by_purse", + "SELECT" + " pd.purse_deposit_serial_id" + ",pd.amount_with_fee" + ",pd.coin_pub" + ",denom.denom_pub" + " FROM purse_deposits pd" + " JOIN known_coins kc" + " USING (coin_pub)" + " JOIN denominations denom" + " USING (denominations_serial)" + " WHERE purse_pub=$1;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_purse_deposits_by_purse", + params, + &purse_refund_coin_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_purse_merge.c b/src/exchangedb/select_purse_merge.c @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_purse_merge.c + * @brief Implementation of the select_purse_merge function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse_merge.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_merge (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseMergeSignatureP *merge_sig, + struct GNUNET_TIME_Timestamp *merge_timestamp, + char **partner_url, + struct TALER_ReservePublicKeyP *reserve_pub, + bool *refunded) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("merge_sig", + merge_sig), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + reserve_pub), + GNUNET_PQ_result_spec_timestamp ("merge_timestamp", + merge_timestamp), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("partner_base_url", + partner_url), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_bool ("refunded", + refunded), + NULL), + GNUNET_PQ_result_spec_end + }; + + *partner_url = NULL; + *refunded = false; + PREPARE (ctx, + "select_purse_merge", + "SELECT " + " pm.reserve_pub" + ",pm.merge_sig" + ",pm.merge_timestamp" + ",pr.partner_base_url" + ",pd.refunded" + " FROM purse_merges pm" + " LEFT JOIN purse_decision pd USING (purse_pub)" + " LEFT JOIN partners pr USING (partner_serial_id)" + " WHERE pm.purse_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "select_purse_merge", + params, + rs); +} diff --git a/src/exchangedb/select_purse_merges_above_serial_id.c b/src/exchangedb/select_purse_merges_above_serial_id.c @@ -0,0 +1,188 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_purse_merges_above_serial_id.c + * @brief Implementation of the select_purse_merges_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse_merges_above_serial_id.h" +#include "pg_helper.h" + + +/** + * Closure for #purse_deposit_serial_helper_cb(). + */ +struct PurseMergeSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_PurseMergeCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct PurseMergeSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +purse_merges_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PurseMergeSerialContext *dsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = dsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + char *partner_base_url = NULL; + struct TALER_Amount amount; + struct TALER_Amount balance; + uint32_t flags32; + enum TALER_WalletAccountMergeFlags flags; + struct TALER_PurseMergePublicKeyP merge_pub; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_PurseMergeSignatureP merge_sig; + struct TALER_PurseContractPublicKeyP purse_pub; + struct GNUNET_TIME_Timestamp merge_timestamp; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &amount), + TALER_PQ_RESULT_SPEC_AMOUNT ("balance", + &balance), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("partner_base_url", + &partner_base_url), + NULL), + GNUNET_PQ_result_spec_uint32 ("flags", + &flags32), + GNUNET_PQ_result_spec_timestamp ("merge_timestamp", + &merge_timestamp), + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &purse_pub), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ("merge_sig", + &merge_sig), + GNUNET_PQ_result_spec_auto_from_type ("merge_pub", + &merge_pub), + GNUNET_PQ_result_spec_uint64 ("purse_merge_request_serial_id", + &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; + } + flags = (enum TALER_WalletAccountMergeFlags) flags32; + ret = dsc->cb (dsc->cb_cls, + rowid, + partner_base_url, + &amount, + &balance, + flags, + &merge_pub, + &reserve_pub, + &merge_sig, + &purse_pub, + merge_timestamp); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_merges_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_PurseMergeCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct PurseMergeSerialContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "audit_get_purse_merge_incr", + "SELECT" + " pm.purse_merge_request_serial_id" + ",partner_base_url" + ",pr.amount_with_fee" + ",pr.balance" + ",pr.flags" + ",pr.merge_pub" + ",pm.reserve_pub" + ",pm.merge_sig" + ",pm.purse_pub" + ",pm.merge_timestamp" + " FROM purse_merges pm" + " JOIN purse_requests pr USING (purse_pub)" + " LEFT JOIN partners USING (partner_serial_id)" + " WHERE (" + " (purse_merge_request_serial_id>=$1)" + " )" + " ORDER BY purse_merge_request_serial_id ASC;"); + + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_purse_merge_incr", + params, + &purse_merges_serial_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_purse_requests_above_serial_id.c b/src/exchangedb/select_purse_requests_above_serial_id.c @@ -0,0 +1,176 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_purse_requests_above_serial_id.c + * @brief Implementation of the select_purse_requests_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_purse_requests_above_serial_id.h" +#include "pg_helper.h" + + +/** + * Closure for #purse_deposit_serial_helper_cb(). + */ +struct PurseRequestsSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_PurseRequestCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct PurseRequestsSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +purse_requests_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PurseRequestsSerialContext *dsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = dsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct TALER_Amount target_amount; + uint32_t age_limit; + struct TALER_PurseMergePublicKeyP merge_pub; + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_PrivateContractHashP h_contract_terms; + struct TALER_PurseContractSignatureP purse_sig; + struct GNUNET_TIME_Timestamp purse_creation; + struct GNUNET_TIME_Timestamp purse_expiration; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &target_amount), + GNUNET_PQ_result_spec_uint32 ("age_limit", + &age_limit), + GNUNET_PQ_result_spec_timestamp ("purse_creation", + &purse_creation), + GNUNET_PQ_result_spec_timestamp ("purse_expiration", + &purse_expiration), + GNUNET_PQ_result_spec_auto_from_type ("purse_pub", + &purse_pub), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &h_contract_terms), + GNUNET_PQ_result_spec_auto_from_type ("purse_sig", + &purse_sig), + GNUNET_PQ_result_spec_auto_from_type ("merge_pub", + &merge_pub), + GNUNET_PQ_result_spec_uint64 ("purse_requests_serial_id", + &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, + &merge_pub, + purse_creation, + purse_expiration, + &h_contract_terms, + age_limit, + &target_amount, + &purse_sig); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_requests_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_PurseRequestCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct PurseRequestsSerialContext dsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "audit_get_purse_requests_incr", + "SELECT" + " purse_requests_serial_id" + ",purse_pub" + ",amount_with_fee" + ",age_limit" + ",h_contract_terms" + ",purse_creation" + ",purse_expiration" + ",merge_pub" + ",purse_sig" + " FROM purse_requests" + " WHERE (" + " (purse_requests_serial_id>=$1)" + " )" + " ORDER BY purse_requests_serial_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_purse_requests_incr", + params, + &purse_requests_serial_helper_cb, + &dsc); + if (GNUNET_OK != dsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_recoup_above_serial_id.c b/src/exchangedb/select_recoup_above_serial_id.c @@ -0,0 +1,186 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_recoup_above_serial_id.c + * @brief Implementation of the select_recoup_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_recoup_above_serial_id.h" +#include "pg_helper.h" + + +/** + * Closure for #recoup_serial_helper_cb(). + */ +struct RecoupSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_RecoupCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct RecoupSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +recoup_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct RecoupSerialContext *psc = cls; + struct EXCHANGEDB_PostgresContext *ctx = psc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_CoinPublicInfo coin; + struct TALER_CoinSpendSignatureP coin_sig; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; + struct TALER_Amount amount; + struct TALER_DenominationPublicKey denom_pub; + struct GNUNET_TIME_Timestamp timestamp; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("recoup_uuid", + &rowid), + GNUNET_PQ_result_spec_timestamp ("recoup_timestamp", + &timestamp), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", + &coin.coin_pub), + TALER_PQ_result_spec_denom_pub ("denom_pub", + &denom_pub), + 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 ("denom_pub_hash", + &coin.denom_pub_hash), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &coin.h_age_commitment), + &coin.no_age_commitment), + TALER_PQ_result_spec_denom_sig ("denom_sig", + &coin.denom_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + int ret; + + 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, + &reserve_pub, + &coin, + &denom_pub, + &coin_sig, + &coin_blind); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_recoup_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_RecoupCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct RecoupSerialContext psc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "recoup_get_incr", + "SELECT" + " recoup_uuid" + ",recoup_timestamp" + ",withdraw.reserve_pub" + ",coins.coin_pub" + ",coin_sig" + ",coin_blind" + ",denoms.denom_pub_hash" + ",coins.denom_sig" + ",coins.age_commitment_hash" + ",denoms.denom_pub" + ",amount" + " FROM recoup" + " JOIN known_coins coins" + " USING (coin_pub)" + " JOIN withdraw" + " USING (withdraw_id)" + " JOIN denominations denoms" + " ON (coins.denominations_serial = denoms.denominations_serial)" + " WHERE recoup_uuid>=$1" + " ORDER BY recoup_uuid ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "recoup_get_incr", + params, + &recoup_serial_helper_cb, + &psc); + if (GNUNET_OK != psc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_recoup_refresh_above_serial_id.c b/src/exchangedb/select_recoup_refresh_above_serial_id.c @@ -0,0 +1,206 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_recoup_refresh_above_serial_id.c + * @brief Implementation of the select_recoup_refresh_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_recoup_refresh_above_serial_id.h" +#include "pg_helper.h" + + +/** + * Closure for #recoup_refresh_serial_helper_cb(). + */ +struct RecoupRefreshSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_RecoupRefreshCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct RecoupRefreshSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +recoup_refresh_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct RecoupRefreshSerialContext *psc = cls; + struct EXCHANGEDB_PostgresContext *ctx = psc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct TALER_CoinSpendPublicKeyP old_coin_pub; + struct TALER_CoinPublicInfo coin; + struct TALER_CoinSpendSignatureP coin_sig; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; + struct TALER_DenominationPublicKey denom_pub; + struct TALER_DenominationHashP old_denom_pub_hash; + struct TALER_Amount amount; + struct TALER_BlindedCoinHashP h_blind_ev; + struct GNUNET_TIME_Timestamp timestamp; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("recoup_refresh_uuid", + &rowid), + GNUNET_PQ_result_spec_timestamp ("recoup_timestamp", + &timestamp), + GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub", + &old_coin_pub), + GNUNET_PQ_result_spec_auto_from_type ("old_denom_pub_hash", + &old_denom_pub_hash), + 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), + TALER_PQ_result_spec_denom_pub ("denom_pub", + &denom_pub), + 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), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash", + &coin.h_age_commitment), + &coin.no_age_commitment), + TALER_PQ_result_spec_denom_sig ("denom_sig", + &coin.denom_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + 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, + &old_denom_pub_hash, + &coin, + &denom_pub, + &coin_sig, + &coin_blind); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_recoup_refresh_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_RecoupRefreshCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct RecoupRefreshSerialContext psc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_recoup_refresh_above_serial_id", + "SELECT" + " rr.recoup_refresh_uuid" + ",rr.recoup_timestamp" + ",rr.coin_sig" + ",rr.coin_blind" + ",rr.amount" + ",rrc.h_coin_ev AS h_blind_ev" // FIXME:-#9828 r.rc? r.selected_h? Old logic wanted a TALER_BlindedCoinHash, which we now need to derive (from rr.coin_blind) + ",new_coins.age_commitment_hash" + ",new_coins.coin_pub AS coin_pub" + ",new_denoms.denom_pub AS denom_pub" + ",new_denoms.denom_pub_hash" + ",new_coins.denom_sig AS denom_sig" + ",old_coins.coin_pub AS old_coin_pub" + ",old_denoms.denom_pub_hash AS old_denom_pub_hash" + " FROM recoup_refresh rr" + " INNER JOIN refresh_revealed_coins rrc" // FIXME-#9828: no such table anymore! + // but we have 'refresh_id" which is an FK into 'refresh'! + " USING (rrc_serial)" + " INNER JOIN refresh r" + // but we have 'refresh_id" which is an FK into 'refresh'! + " USING (refresh_id)" + " INNER JOIN known_coins old_coins" + " ON (r.old_coin_pub = old_coins.coin_pub)" + " INNER JOIN known_coins new_coins" + " ON (rr.coin_pub == new_coins.coin_pub)" + " INNER JOIN refresh_commitments rfc" + " ON (rrc.melt_serial_id = rfc.melt_serial_id)" + " 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" + " ORDER BY recoup_refresh_uuid ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_recoup_refresh_above_serial_id", + params, + &recoup_refresh_serial_helper_cb, + &psc); + if (GNUNET_OK != psc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_refreshes_above_serial_id.c b/src/exchangedb/select_refreshes_above_serial_id.c @@ -0,0 +1,182 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_refreshes_above_serial_id.c + * @brief Implementation of the select_refreshes_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_refreshes_above_serial_id.h" +#include "pg_helper.h" + + +/** + * Closure for #refreshs_serial_helper_cb(). + */ +struct RefreshsSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_RefreshesCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct RefreshsSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +refreshs_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct RefreshsSerialContext *rsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_DenominationPublicKey old_denom_pub; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinSpendSignatureP coin_sig; + struct TALER_AgeCommitmentHashP h_age_commitment; + bool ac_isnull; + struct TALER_Amount amount_with_fee; + uint64_t rowid; + struct TALER_RefreshCommitmentP rc; + size_t num_nds; + uint64_t *nds; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_denom_pub ("old_denom_pub", + &old_denom_pub), + GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub", + &coin_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_sig", + &coin_sig), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &amount_with_fee), + GNUNET_PQ_result_spec_uint64 ("refresh_id", + &rowid), + GNUNET_PQ_result_spec_auto_from_type ("rc", + &rc), + GNUNET_PQ_result_spec_array_uint64 (ctx->conn, + "new_denominations_serials", + &num_nds, + &nds), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + rsc->status = GNUNET_SYSERR; + return; + } + + ret = rsc->cb (rsc->cb_cls, + rowid, + &old_denom_pub, + &coin_pub, + &coin_sig, + ac_isnull ? NULL : &h_age_commitment, + &amount_with_fee, + num_nds, + nds, + &rc); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_refreshes_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_RefreshesCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct RefreshsSerialContext rsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_refreshes_above_serial_id", + "SELECT" + " denom.denom_pub AS old_denom_pub" + ",r.old_coin_pub" + ",kc.age_commitment_hash" + ",r.old_coin_sig" + ",r.amount_with_fee" + ",r.refresh_id" + ",r.rc" + ",r.denom_serials AS new_denominations_serials" + " FROM refresh r" + " JOIN known_coins kc" + " ON (r.old_coin_pub = kc.coin_pub)" + " JOIN denominations denom" + " ON (kc.denominations_serial = denom.denominations_serial)" + " WHERE refresh_id>=$1" + " ORDER BY refresh_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_refreshes_above_serial_id", + params, + &refreshs_serial_helper_cb, + &rsc); + if (GNUNET_OK != rsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_refunds_above_serial_id.c b/src/exchangedb/select_refunds_above_serial_id.c @@ -0,0 +1,221 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_refunds_above_serial_id.c + * @brief Implementation of the select_refunds_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_refunds_above_serial_id.h" +#include "pg_helper.h" + +/** + * Closure for #refunds_serial_helper_cb(). + */ +struct RefundsSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_RefundCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct RefundsSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +refunds_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct RefundsSerialContext *rsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_EXCHANGEDB_Refund refund; + struct TALER_DenominationPublicKey denom_pub; + uint64_t rowid; + bool full_refund; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", + &refund.details.merchant_pub), + GNUNET_PQ_result_spec_auto_from_type ("merchant_sig", + &refund.details.merchant_sig), + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + &refund.details.h_contract_terms), + GNUNET_PQ_result_spec_uint64 ("rtransaction_id", + &refund.details.rtransaction_id), + TALER_PQ_result_spec_denom_pub ("denom_pub", + &denom_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", + &refund.coin.coin_pub), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &refund.details.refund_amount), + GNUNET_PQ_result_spec_uint64 ("refund_serial_id", + &rowid), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + rsc->status = GNUNET_SYSERR; + return; + } + { + 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 ( + ctx->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); + } + ret = rsc->cb (rsc->cb_cls, + rowid, + &denom_pub, + &refund.coin.coin_pub, + &refund.details.merchant_pub, + &refund.details.merchant_sig, + &refund.details.h_contract_terms, + refund.details.rtransaction_id, + full_refund, + &refund.details.refund_amount); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_refunds_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_RefundCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct RefundsSerialContext rsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + /* Fetch refunds with rowid '\geq' the given parameter */ + PREPARE (ctx, + "audit_get_refunds_incr", + "SELECT" + " bdep.merchant_pub" + ",ref.merchant_sig" + ",bdep.h_contract_terms" + ",ref.rtransaction_id" + ",denom.denom_pub" + ",kc.coin_pub" + ",ref.amount_with_fee" + ",ref.refund_serial_id" + " FROM refunds ref" + " JOIN batch_deposits bdep" + " ON (ref.batch_deposit_serial_id=bdep.batch_deposit_serial_id)" + " JOIN coin_deposits cdep" + " ON (ref.coin_pub=cdep.coin_pub AND ref.batch_deposit_serial_id=cdep.batch_deposit_serial_id)" + " JOIN known_coins kc" + " ON (cdep.coin_pub=kc.coin_pub)" + " JOIN denominations denom" + " ON (kc.denominations_serial=denom.denominations_serial)" + " WHERE ref.refund_serial_id>=$1" + " ORDER BY ref.refund_serial_id ASC;"); + PREPARE (ctx, + "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" + ",cdep.amount_with_fee" + " FROM refunds ref" + " JOIN coin_deposits cdep" + " ON (ref.coin_pub=cdep.coin_pub AND ref.batch_deposit_serial_id=cdep.batch_deposit_serial_id)" + " WHERE ref.refund_serial_id=$1" + " GROUP BY (cdep.amount_with_fee);"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_refunds_incr", + params, + &refunds_serial_helper_cb, + &rsc); + if (GNUNET_OK != rsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_refunds_by_coin.c b/src/exchangedb/select_refunds_by_coin.c @@ -0,0 +1,141 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_refunds_by_coin.c + * @brief Implementation of the select_refunds_by_coin function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_refunds_by_coin.h" +#include "pg_helper.h" + + +/** + * Closure for #get_refunds_cb(). + */ +struct SelectRefundContext +{ + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_RefundCoinCallback cb; + + /** + * Closure for @a cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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_refunds_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct SelectRefundContext *srctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = srctx->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_Amount amount_with_fee; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &amount_with_fee), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + srctx->status = GNUNET_SYSERR; + return; + } + if (GNUNET_OK != + srctx->cb (srctx->cb_cls, + &amount_with_fee)) + return; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_refunds_by_coin (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_PrivateContractHashP *h_contract, + TALER_EXCHANGEDB_RefundCoinCallback cb, + void *cb_cls) +{ + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_auto_from_type (merchant_pub), + GNUNET_PQ_query_param_auto_from_type (h_contract), + GNUNET_PQ_query_param_end + }; + struct SelectRefundContext srctx = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + const char *query = "get_refunds_by_coin_and_contract"; + + PREPARE (ctx, + query, + "SELECT" + " ref.amount_with_fee" + " FROM refunds ref" + " JOIN coin_deposits cdep" + " USING (coin_pub,batch_deposit_serial_id)" + " JOIN batch_deposits bdep" + " ON (ref.batch_deposit_serial_id = bdep.batch_deposit_serial_id)" + " WHERE ref.coin_pub=$1" + " AND bdep.merchant_pub=$2" + " AND bdep.h_contract_terms=$3;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + query, + params, + &get_refunds_cb, + &srctx); + if (GNUNET_SYSERR == srctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_reserve_close_info.c b/src/exchangedb/select_reserve_close_info.c @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_reserve_close_info.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_reserve_close_info.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserve_close_info (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_Amount *balance, + struct TALER_FullPayto *payto_uri) +{ + 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", + ctx->currency, + balance), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri->full_payto), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "select_reserve_close_info", + "SELECT " + " r.current_balance" + ",wt.payto_uri" + " FROM reserves r" + " LEFT JOIN reserves_in ri" + " USING (reserve_pub)" + " LEFT JOIN wire_targets wt" + " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" + " WHERE r.reserve_pub=$1;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "select_reserve_close_info", + params, + rs); +} diff --git a/src/exchangedb/select_reserve_closed_above_serial_id.c b/src/exchangedb/select_reserve_closed_above_serial_id.c @@ -0,0 +1,175 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_reserve_closed_above_serial_id.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_reserve_closed_above_serial_id.h" +#include "plugin_exchangedb_common.h" +#include "pg_helper.h" + +/** + * Closure for #reserve_closed_serial_helper_cb(). + */ +struct ReserveClosedSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_ReserveClosedCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin's context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct ReserveClosedSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserve_closed_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveClosedSerialContext *rcsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rcsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_FullPayto receiver_account; + struct TALER_WireTransferIdentifierRawP wtid; + struct TALER_Amount amount_with_fee; + struct TALER_Amount closing_fee; + struct GNUNET_TIME_Timestamp execution_date; + uint64_t close_request_row; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("close_uuid", + &rowid), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &execution_date), + GNUNET_PQ_result_spec_auto_from_type ("wtid", + &wtid), + GNUNET_PQ_result_spec_string ("receiver_account", + &receiver_account.full_payto), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", + &closing_fee), + GNUNET_PQ_result_spec_uint64 ("close_request_row", + &close_request_row), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + rcsc->status = GNUNET_SYSERR; + return; + } + ret = rcsc->cb (rcsc->cb_cls, + rowid, + execution_date, + &amount_with_fee, + &closing_fee, + &reserve_pub, + receiver_account, + &wtid, + close_request_row); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserve_closed_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_ReserveClosedCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct ReserveClosedSerialContext rcsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE ( + ctx, + "reserves_close_get_incr", + "SELECT" + " close_uuid" + ",reserves.reserve_pub" + ",execution_date" + ",wtid" + ",wt.payto_uri AS receiver_account" + ",amount" + ",closing_fee" + ",close_request_row" + " FROM reserves_close" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " JOIN reserves" + " USING (reserve_pub)" + " WHERE close_uuid>=$1" + " ORDER BY close_uuid ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "reserves_close_get_incr", + params, + &reserve_closed_serial_helper_cb, + &rcsc); + if (GNUNET_OK != rcsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_reserve_open_above_serial_id.c b/src/exchangedb/select_reserve_open_above_serial_id.c @@ -0,0 +1,166 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_reserve_open_above_serial_id.c + * @brief Low-level (statement-level) Postgres database access for the exchange + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_reserve_open_above_serial_id.h" +#include "plugin_exchangedb_common.h" +#include "pg_helper.h" + + +/** + * Closure for #reserve_open_serial_helper_cb(). + */ +struct ReserveOpenSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_ReserveOpenCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin's context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct ReserveOpenSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserve_open_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReserveOpenSerialContext *rcsc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rcsc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_ReserveSignatureP reserve_sig; + uint32_t requested_purse_limit; + struct GNUNET_TIME_Timestamp request_timestamp; + struct GNUNET_TIME_Timestamp reserve_expiration; + struct TALER_Amount reserve_payment; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("open_request_uuid", + &rowid), + 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_timestamp ("request_timestamp", + &request_timestamp), + GNUNET_PQ_result_spec_timestamp ("expiration_date", + &reserve_expiration), + GNUNET_PQ_result_spec_uint32 ("requested_purse_limit", + &requested_purse_limit), + TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_payment", + &reserve_payment), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + rcsc->status = GNUNET_SYSERR; + return; + } + ret = rcsc->cb (rcsc->cb_cls, + rowid, + &reserve_payment, + request_timestamp, + reserve_expiration, + requested_purse_limit, + &reserve_pub, + &reserve_sig); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserve_open_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_ReserveOpenCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct ReserveOpenSerialContext rcsc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE ( + ctx, + "reserves_open_get_incr", + "SELECT" + " open_request_uuid" + ",reserve_pub" + ",request_timestamp" + ",expiration_date" + ",reserve_sig" + ",reserve_payment" + ",requested_purse_limit" + " FROM reserves_open_requests" + " WHERE open_request_uuid>=$1" + " ORDER BY open_request_uuid ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "reserves_open_get_incr", + params, + &reserve_open_serial_helper_cb, + &rcsc); + if (GNUNET_OK != rcsc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_reserves_in_above_serial_id.c b/src/exchangedb/select_reserves_in_above_serial_id.c @@ -0,0 +1,165 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_reserves_in_above_serial_id.c + * @brief Implementation of the select_reserves_in_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_reserves_in_above_serial_id.h" +#include "pg_helper.h" + +/** + * Closure for #reserves_in_serial_helper_cb(). + */ +struct ReservesInSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_ReserveInCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct ReservesInSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserves_in_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReservesInSerialContext *risc = cls; + struct EXCHANGEDB_PostgresContext *ctx = risc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_Amount credit; + struct TALER_FullPayto sender_account_details; + struct GNUNET_TIME_Timestamp execution_date; + uint64_t rowid; + uint64_t wire_reference; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + GNUNET_PQ_result_spec_uint64 ("wire_reference", + &wire_reference), + TALER_PQ_RESULT_SPEC_AMOUNT ("credit", + &credit), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &execution_date), + GNUNET_PQ_result_spec_string ("sender_account_details", + &sender_account_details.full_payto), + GNUNET_PQ_result_spec_uint64 ("reserve_in_serial_id", + &rowid), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + risc->status = GNUNET_SYSERR; + return; + } + ret = risc->cb (risc->cb_cls, + rowid, + &reserve_pub, + &credit, + sender_account_details, + wire_reference, + execution_date); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserves_in_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_ReserveInCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct ReservesInSerialContext risc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_reserves_in_above_serial_id", + "SELECT" + " reserves.reserve_pub" + ",wire_reference" + ",credit" + ",execution_date" + ",wt.payto_uri AS sender_account_details" + ",reserve_in_serial_id" + " FROM reserves_in" + " JOIN reserves" + " USING (reserve_pub)" + " JOIN wire_targets wt" + " ON (wire_source_h_payto = wire_target_h_payto)" + " WHERE reserve_in_serial_id>=$1" + " ORDER BY reserve_in_serial_id;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_reserves_in_above_serial_id", + params, + &reserves_in_serial_helper_cb, + &risc); + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + return qs; + if (GNUNET_OK != risc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_reserves_in_above_serial_id_by_account.c b/src/exchangedb/select_reserves_in_above_serial_id_by_account.c @@ -0,0 +1,167 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_reserves_in_above_serial_id_by_account.c + * @brief Implementation of the select_reserves_in_above_serial_id_by_account function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_reserves_in_above_serial_id_by_account.h" +#include "pg_helper.h" + + +/** + * Closure for #reserves_in_serial_helper_cb(). + */ +struct ReservesInSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_ReserveInCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct ReservesInSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reserves_in_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct ReservesInSerialContext *risc = cls; + struct EXCHANGEDB_PostgresContext *ctx = risc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_Amount credit; + struct TALER_FullPayto sender_account_details; + struct GNUNET_TIME_Timestamp execution_date; + uint64_t rowid; + uint64_t wire_reference; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + GNUNET_PQ_result_spec_uint64 ("wire_reference", + &wire_reference), + TALER_PQ_RESULT_SPEC_AMOUNT ("credit", + &credit), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &execution_date), + GNUNET_PQ_result_spec_string ("sender_account_details", + &sender_account_details.full_payto), + GNUNET_PQ_result_spec_uint64 ("reserve_in_serial_id", + &rowid), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + risc->status = GNUNET_SYSERR; + return; + } + ret = risc->cb (risc->cb_cls, + rowid, + &reserve_pub, + &credit, + sender_account_details, + wire_reference, + execution_date); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserves_in_above_serial_id_by_account (struct EXCHANGEDB_PostgresContext *ctx, + const char *account_name, + uint64_t serial_id, + TALER_EXCHANGEDB_ReserveInCallback cb, + void *cb_cls) +{ + 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, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_reserves_in_above_serial_id_by_account", + "SELECT" + " reserves.reserve_pub" + ",wire_reference" + ",credit" + ",execution_date" + ",wt.payto_uri AS sender_account_details" + ",reserve_in_serial_id" + " FROM reserves_in" + " JOIN reserves " + " USING (reserve_pub)" + " JOIN wire_targets wt" + " ON (wire_source_h_payto = wire_target_h_payto)" + " WHERE reserve_in_serial_id>=$1" + " AND exchange_account_section=$2" + " ORDER BY reserve_in_serial_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_reserves_in_above_serial_id_by_account", + params, + &reserves_in_serial_helper_cb, + &risc); + if (GNUNET_OK != risc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_wire_out_above_serial_id.c b/src/exchangedb/select_wire_out_above_serial_id.c @@ -0,0 +1,156 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_wire_out_above_serial_id.c + * @brief Implementation of the select_wire_out_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_wire_out_above_serial_id.h" +#include "pg_helper.h" + +/** + * Closure for #wire_out_serial_helper_cb(). + */ +struct WireOutSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_WireTransferOutCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Status code, set to #GNUNET_SYSERR on hard errors. + */ + int status; +}; + + +/** + * 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 + * @param num_results the number of results in @a result + */ +static void +wire_out_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct WireOutSerialContext *wosc = cls; + struct EXCHANGEDB_PostgresContext *ctx = wosc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct GNUNET_TIME_Timestamp date; + struct TALER_WireTransferIdentifierRawP wtid; + struct TALER_FullPayto payto_uri; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("wireout_uuid", + &rowid), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &date), + GNUNET_PQ_result_spec_auto_from_type ("wtid_raw", + &wtid), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri.full_payto), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + int ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + wosc->status = GNUNET_SYSERR; + return; + } + ret = wosc->cb (wosc->cb_cls, + rowid, + date, + &wtid, + payto_uri, + &amount); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_wire_out_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_WireTransferOutCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct WireOutSerialContext wosc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_wire_out_above_serial_id", + "SELECT" + " wo.wireout_uuid" + ",wo.execution_date" + ",wo.wtid_raw" + ",wt.payto_uri" + ",wo.amount" + " FROM wire_out wo" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " WHERE wireout_uuid>=$1" + " ORDER BY wireout_uuid ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_wire_out_above_serial_id", + params, + &wire_out_serial_helper_cb, + &wosc); + if (GNUNET_OK != wosc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_wire_out_above_serial_id_by_account.c b/src/exchangedb/select_wire_out_above_serial_id_by_account.c @@ -0,0 +1,159 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_wire_out_above_serial_id_by_account.c + * @brief Implementation of the select_wire_out_above_serial_id_by_account function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_wire_out_above_serial_id_by_account.h" +#include "pg_helper.h" + +/** + * Closure for #wire_out_serial_helper_cb(). + */ +struct WireOutSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_WireTransferOutCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Status code, set to #GNUNET_SYSERR on hard errors. + */ + int status; +}; + + +/** + * 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 + * @param num_results the number of results in @a result + */ +static void +wire_out_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct WireOutSerialContext *wosc = cls; + struct EXCHANGEDB_PostgresContext *ctx = wosc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct GNUNET_TIME_Timestamp date; + struct TALER_WireTransferIdentifierRawP wtid; + struct TALER_FullPayto payto_uri; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("wireout_uuid", + &rowid), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &date), + GNUNET_PQ_result_spec_auto_from_type ("wtid_raw", + &wtid), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri.full_payto), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + int ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + wosc->status = GNUNET_SYSERR; + return; + } + ret = wosc->cb (wosc->cb_cls, + rowid, + date, + &wtid, + payto_uri, + &amount); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_wire_out_above_serial_id_by_account (struct EXCHANGEDB_PostgresContext *ctx, + const char *account_name, + uint64_t serial_id, + TALER_EXCHANGEDB_WireTransferOutCallback cb, + void *cb_cls) +{ + 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, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_wire_out_above_serial_id_by_account", + "SELECT" + " wo.wireout_uuid" + ",wo.execution_date" + ",wo.wtid_raw" + ",wt.payto_uri" + ",wo.amount" + " FROM wire_out wo" + " JOIN wire_targets wt" + " USING (wire_target_h_payto)" + " WHERE wo.wireout_uuid>=$1 " + " AND wo.exchange_account_section=$2" + " ORDER BY wo.wireout_uuid ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_wire_out_above_serial_id_by_account", + params, + &wire_out_serial_helper_cb, + &wosc); + if (GNUNET_OK != wosc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_withdraw_amounts_for_kyc_check.c b/src/exchangedb/select_withdraw_amounts_for_kyc_check.c @@ -0,0 +1,160 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_withdraw_amounts_for_kyc_check.c + * @brief Implementation of the select_withdraw_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_withdraw_amounts_for_kyc_check.h" +#include "pg_select_aggregation_amounts_for_kyc_check.h" +#include "pg_helper.h" + + +/** + * Closure for #get_kyc_amounts_cb(). + */ +struct KycAmountCheckContext +{ + /** + * Function to call per result. + */ + TALER_EXCHANGEDB_KycAmountCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + +/** + * Invoke the callback for each result. + * + * @param cls a `struct KycAmountCheckContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +get_kyc_amounts_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct KycAmountCheckContext *ctx = cls; + struct EXCHANGEDB_PostgresContext *ctx = ctx->ctx; + + for (unsigned int i = 0; i < num_results; i++) + { + struct GNUNET_TIME_Absolute date; + struct TALER_Amount amount; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT ("amount", + &amount), + GNUNET_PQ_result_spec_absolute_time ("date", + &date), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->status = GNUNET_SYSERR; + return; + } + ret = ctx->cb (ctx->cb_cls, + &amount, + date); + GNUNET_PQ_cleanup_result (rs); + switch (ret) + { + case GNUNET_OK: + continue; + case GNUNET_NO: + break; + case GNUNET_SYSERR: + ctx->status = GNUNET_SYSERR; + break; + } + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_withdraw_amounts_for_kyc_check (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_absolute_time (&time_limit), + GNUNET_PQ_query_param_end + }; + struct KycAmountCheckContext ctx = { + .cb = kac, + .cb_cls = kac_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "select_withdraw_amounts_for_kyc_check", + "SELECT" + " wd.amount_with_fee AS amount" + ",wd.execution_date AS date" + " FROM reserves_in ri" + " JOIN reserve_history rh" + " ON (rh.reserve_pub = ri.reserve_pub)" + " JOIN withdraw wd" + " ON (wd.withdraw_id = rh.serial_id)" + " WHERE ri.wire_source_h_payto IN (" + " SELECT wire_target_h_payto" + " FROM wire_targets" + " WHERE h_normalized_payto=$1" + " )" + " AND rh.table_name='withdraw'" + " AND wd.execution_date >= $2" + " ORDER BY rh.reserve_history_serial_id DESC"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + ctx->conn, + "select_withdraw_amounts_for_kyc_check", + params, + &get_kyc_amounts_cb, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/select_withdrawals_above_serial_id.c b/src/exchangedb/select_withdrawals_above_serial_id.c @@ -0,0 +1,214 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/select_withdrawals_above_serial_id.c + * @brief Implementation of the select_withdrawals_above_serial_id function for Postgres + * @author Christian Grothoff + * @author Özgür Kesim + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "select_withdrawals_above_serial_id.h" +#include "pg_helper.h" + +/** + * Closure for #withdraw_serial_helper_cb(). + */ +struct WithdrawSerialContext +{ + + /** + * Callback to call. + */ + TALER_EXCHANGEDB_WithdrawCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct EXCHANGEDB_PostgresContext *ctx; + + /** + * 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. + * + * @param cls closure of type `struct WithdrawSerialContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +withdraw_serial_helper_cb (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct WithdrawSerialContext *rosc = cls; + struct EXCHANGEDB_PostgresContext *ctx = rosc->ctx; + + for (unsigned int i = 0; i<num_results; i++) + { + uint64_t rowid; + struct TALER_HashBlindedPlanchetsP h_planchets; + struct GNUNET_TIME_Timestamp execution_date; + struct TALER_Amount amount_with_fee; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_ReserveSignatureP reserve_sig; + uint16_t max_age; + bool no_max_age; + uint16_t noreveal_index; + bool no_noreveal_index; + struct TALER_HashBlindedPlanchetsP selected_h; + bool no_selected_h; + struct TALER_BlindingMasterSeedP blinding_seed; + bool no_blinding_seed; + size_t num_denom_serials; + uint64_t *denom_serials = NULL; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("withdraw_id", + &rowid), + GNUNET_PQ_result_spec_auto_from_type ("planchets_h", + &h_planchets), + GNUNET_PQ_result_spec_timestamp ("execution_date", + &execution_date), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + &amount_with_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_allow_null ( + GNUNET_PQ_result_spec_uint16 ("max_age", + &max_age), + &no_max_age), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint16 ("noreveal_index", + &noreveal_index), + &no_noreveal_index), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ( + "selected_h", + &selected_h), + &no_selected_h), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ( + "blinding_seed", + &blinding_seed), + &no_blinding_seed), + GNUNET_PQ_result_spec_array_uint64 ( + ctx->conn, + "denom_serials", + &num_denom_serials, + &denom_serials), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_GenericReturnValue ret; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + rosc->status = GNUNET_SYSERR; + GNUNET_PQ_cleanup_result (rs); + return; + } + if ((! no_max_age) && + ((255 <= noreveal_index) || (255 <= max_age))) + { + GNUNET_break (0); + rosc->status = GNUNET_SYSERR; + GNUNET_PQ_cleanup_result (rs); + return; + } + ret = rosc->cb (rosc->cb_cls, + rowid, + num_denom_serials, + denom_serials, + no_selected_h ? NULL : &selected_h, + &h_planchets, + no_blinding_seed ? NULL : &blinding_seed, + ! no_max_age, + (uint8_t) max_age, + (uint8_t) noreveal_index, + &reserve_pub, + &reserve_sig, + execution_date, + &amount_with_fee); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_withdrawals_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_WithdrawCallback cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&serial_id), + GNUNET_PQ_query_param_end + }; + struct WithdrawSerialContext rosc = { + .cb = cb, + .cb_cls = cb_cls, + .ctx = ctx, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + /* Fetch deposits with rowid '\geq' the given parameter */ + PREPARE (ctx, + "audit_get_withdraw_incr", + "SELECT" + " withdraw_id" + ",planchets_h" + ",execution_date" + ",amount_with_fee" + ",reserve_pub" + ",reserve_sig" + ",max_age" + ",noreveal_index" + ",selected_h" + ",blinding_seed" + ",denom_serials" + " FROM withdraw" + " WHERE withdraw_id>=$1" + " ORDER BY withdraw_id ASC;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "audit_get_withdraw_incr", + params, + &withdraw_serial_helper_cb, + &rosc); + if (GNUNET_OK != rosc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/set_aml_lock.c b/src/exchangedb/set_aml_lock.c @@ -0,0 +1,71 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/set_aml_lock.c + * @brief Implementation of the set_aml_lock function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "set_aml_lock.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_set_aml_lock (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Relative lock_duration, + struct GNUNET_TIME_Absolute *existing_lock) +{ + struct GNUNET_TIME_Absolute expires + = GNUNET_TIME_relative_to_absolute (lock_duration); + struct GNUNET_TIME_Absolute now + = GNUNET_TIME_absolute_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_absolute_time (&expires), + GNUNET_PQ_query_param_end + }; + bool nx; /* true if the *account* is not known */ + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_absolute_time ("out_aml_program_lock_timeout", + existing_lock), + &nx), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "set_aml_lock", + "SELECT out_aml_program_lock_timeout" + " FROM exchange_do_set_aml_lock($1,$2,$3);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "set_aml_lock", + params, + rs); + if (qs <= 0) + return qs; + if (nx) + { + *existing_lock = GNUNET_TIME_UNIT_ZERO_ABS; + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + return qs; +} diff --git a/src/exchangedb/set_extension_manifest.c b/src/exchangedb/set_extension_manifest.c @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/set_extension_manifest.c + * @brief Implementation of the set_extension_manifest function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "set_extension_manifest.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_set_extension_manifest (struct EXCHANGEDB_PostgresContext *ctx, + const char *extension_name, + const char *manifest) +{ + struct GNUNET_PQ_QueryParam pcfg = + (NULL == manifest || 0 == *manifest) + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (manifest); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (extension_name), + pcfg, + GNUNET_PQ_query_param_end + }; + + + PREPARE (ctx, + "set_extension_manifest", + "INSERT INTO extensions (name, manifest) VALUES ($1, $2) " + "ON CONFLICT (name) " + "DO UPDATE SET manifest=$2"); + + + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "set_extension_manifest", + params); +} diff --git a/src/exchangedb/set_purse_balance.c b/src/exchangedb/set_purse_balance.c @@ -0,0 +1,50 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/set_purse_balance.c + * @brief Implementation of the set_purse_balance function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "set_purse_balance.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_set_purse_balance (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_Amount *balance) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (purse_pub), + TALER_PQ_query_param_amount (ctx->conn, + balance), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "set_purse_balance", + "UPDATE purse_requests" + " SET balance=$2" + " WHERE purse_pub=$1;"); + + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "set_purse_balance", + params); +} diff --git a/src/exchangedb/start.c b/src/exchangedb/start.c @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/start.c + * @brief Implementation of the start function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "pg_preflight.h" +#include "start.h" +#include "pg_helper.h" + +enum GNUNET_GenericReturnValue +EXCHANGEDB_start (struct EXCHANGEDB_PostgresContext *ctx, + const char *name) +{ + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + GNUNET_assert (NULL != name); + if (GNUNET_SYSERR == + EXCHANGEDB_preflight (ctx)) + return GNUNET_SYSERR; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting transaction `%s'\n", + name); + if (GNUNET_OK != + GNUNET_PQ_exec_statements (ctx->conn, + es)) + { + TALER_LOG_ERROR ("Failed to start transaction\n"); + GNUNET_break (0); + return GNUNET_SYSERR; + } + ctx->transaction_name = name; + return GNUNET_OK; +} diff --git a/src/exchangedb/start_deferred_wire_out.c b/src/exchangedb/start_deferred_wire_out.c @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/start_deferred_wire_out.c + * @brief Implementation of the start_deferred_wire_out function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "start_deferred_wire_out.h" +#include "pg_helper.h" +#include "pg_preflight.h" +#include "pg_rollback.h" + +enum GNUNET_GenericReturnValue +EXCHANGEDB_start_deferred_wire_out (struct EXCHANGEDB_PostgresContext *ctx) +{ + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ( + "START TRANSACTION ISOLATION LEVEL READ COMMITTED;"), + GNUNET_PQ_make_execute ("SET CONSTRAINTS ALL DEFERRED;"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + if (GNUNET_SYSERR == + EXCHANGEDB_preflight (ctx)) + return GNUNET_SYSERR; + if (GNUNET_OK != + GNUNET_PQ_exec_statements (ctx->conn, + es)) + { + TALER_LOG_ERROR ( + "Failed to defer wire_out_ref constraint on transaction\n"); + GNUNET_break (0); + EXCHANGEDB_rollback (ctx); + return GNUNET_SYSERR; + } + ctx->transaction_name = "deferred wire out"; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting READ COMMITTED DEFERRED transaction `%s'\n", + ctx->transaction_name); + return GNUNET_OK; +} diff --git a/src/exchangedb/start_read_committed.c b/src/exchangedb/start_read_committed.c @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/start_read_committed.c + * @brief Implementation of the start_read_committed function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "start_read_committed.h" +#include "pg_preflight.h" +#include "pg_helper.h" + +enum GNUNET_GenericReturnValue +EXCHANGEDB_start_read_committed (struct EXCHANGEDB_PostgresContext *ctx, + const char *name) +{ + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL READ COMMITTED"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + GNUNET_assert (NULL != name); + if (GNUNET_SYSERR == + EXCHANGEDB_preflight (ctx)) + return GNUNET_SYSERR; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting READ COMMITTED transaction `%s`\n", + name); + if (GNUNET_OK != + GNUNET_PQ_exec_statements (ctx->conn, + es)) + { + TALER_LOG_ERROR ("Failed to start transaction\n"); + GNUNET_break (0); + return GNUNET_SYSERR; + } + ctx->transaction_name = name; + return GNUNET_OK; +} diff --git a/src/exchangedb/start_read_only.c b/src/exchangedb/start_read_only.c @@ -0,0 +1,56 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/start_read_only.c + * @brief Implementation of the start_read_only function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "start_read_only.h" +#include "pg_preflight.h" +#include "pg_helper.h" + +enum GNUNET_GenericReturnValue +EXCHANGEDB_start_read_only (struct EXCHANGEDB_PostgresContext *ctx, + const char *name) +{ + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ( + "START TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + GNUNET_assert (NULL != name); + if (GNUNET_SYSERR == + EXCHANGEDB_preflight (ctx)) + return GNUNET_SYSERR; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting READ ONLY transaction `%s`\n", + name); + if (GNUNET_OK != + GNUNET_PQ_exec_statements (ctx->conn, + es)) + { + TALER_LOG_ERROR ("Failed to start transaction\n"); + GNUNET_break (0); + return GNUNET_SYSERR; + } + ctx->transaction_name = name; + return GNUNET_OK; +} diff --git a/src/exchangedb/store_wire_transfer_out.c b/src/exchangedb/store_wire_transfer_out.c @@ -0,0 +1,65 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/store_wire_transfer_out.c + * @brief Implementation of the store_wire_transfer_out function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "store_wire_transfer_out.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_store_wire_transfer_out (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp date, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_FullPaytoHashP *h_payto, + const char *exchange_account_section, + const struct TALER_Amount *amount, + const char *extra_wire_subject_metadata) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_timestamp (&date), + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_string (exchange_account_section), + TALER_PQ_query_param_amount (ctx->conn, + amount), + NULL == extra_wire_subject_metadata + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (extra_wire_subject_metadata), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "insert_wire_out", + "INSERT INTO wire_out " + "(execution_date" + ",wtid_raw" + ",wire_target_h_payto" + ",exchange_account_section" + ",amount" + ",extra_wire_subject_metadata" + ") VALUES " + "($1, $2, $3, $4, $5, $6);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "insert_wire_out", + params); +} diff --git a/src/exchangedb/test_aml_officer.c b/src/exchangedb/test_aml_officer.c @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/test_aml_officer.c + * @brief Implementation of the test_aml_officer function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "test_aml_officer.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_test_aml_officer (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + bool *read_only) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (decider_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("read_only", + read_only), + GNUNET_PQ_result_spec_end + }; + + PREPARE (ctx, + "test_aml_staff", + "SELECT read_only" + " FROM aml_staff" + " WHERE decider_pub=$1" + " AND is_active;"); + return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn, + "test_aml_staff", + params, + rs); +} diff --git a/src/exchangedb/trigger_kyc_rule_for_account.c b/src/exchangedb/trigger_kyc_rule_for_account.c @@ -0,0 +1,100 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/trigger_kyc_rule_for_account.c + * @brief Implementation of the trigger_kyc_rule_for_account function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "trigger_kyc_rule_for_account.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_trigger_kyc_rule_for_account (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + const struct TALER_NormalizedPaytoHashP *h_payto, + const union TALER_AccountPublicKeyP *set_account_pub, + const struct TALER_MerchantPublicKeyP *check_merchant_pub, + const json_t *jmeasures, + uint32_t display_priority, + uint64_t *requirement_row, + bool *bad_kyc_auth) +{ + struct GNUNET_TIME_Absolute now + = GNUNET_TIME_absolute_get (); + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = *h_payto + }; + char *notify_str + = GNUNET_PQ_get_event_notify_channel (&rep.header); + struct TALER_FullPaytoHashP h_full_payto; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + NULL == set_account_pub + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (set_account_pub), + NULL == check_merchant_pub + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (check_merchant_pub), + NULL == payto_uri.full_payto + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (payto_uri.full_payto), + NULL == payto_uri.full_payto + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (&h_full_payto), + GNUNET_PQ_query_param_absolute_time (&now), + TALER_PQ_query_param_json (jmeasures), + GNUNET_PQ_query_param_uint32 (&display_priority), + GNUNET_PQ_query_param_string (notify_str), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ( + "legitimization_measure_serial_id", + requirement_row), + GNUNET_PQ_result_spec_bool ( + "bad_kyc_auth", + bad_kyc_auth), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "trigger_kyc_rule_for_account", + "SELECT" + " out_legitimization_measure_serial_id" + " AS legitimization_measure_serial_id" + " ,out_bad_kyc_auth" + " AS bad_kyc_auth" + " FROM exchange_do_trigger_kyc_rule_for_account" + "($1, $2, $3, $4, $5, $6, $7::TEXT::JSONB, $8, $9);"); + if (NULL != payto_uri.full_payto) + TALER_full_payto_hash (payto_uri, + &h_full_payto); + qs = GNUNET_PQ_eval_prepared_singleton_select ( + ctx->conn, + "trigger_kyc_rule_for_account", + params, + rs); + GNUNET_free (notify_str); + return qs; +} diff --git a/src/exchangedb/update_aggregation_transient.c b/src/exchangedb/update_aggregation_transient.c @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/update_aggregation_transient.c + * @brief Implementation of the update_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_aggregation_transient.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_update_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const struct TALER_WireTransferIdentifierRawP *wtid, + uint64_t kyc_requirement_row, + const struct TALER_Amount *total) +{ + struct GNUNET_PQ_QueryParam params[] = { + TALER_PQ_query_param_amount (ctx->conn, + total), + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_auto_from_type (wtid), + GNUNET_PQ_query_param_uint64 (&kyc_requirement_row), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "update_aggregation_transient", + "UPDATE aggregation_transient" + " SET amount=$1" + " ,legitimization_requirement_serial_id=$4" + " WHERE wire_target_h_payto=$2" + " AND wtid_raw=$3"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "update_aggregation_transient", + params); +} diff --git a/src/exchangedb/update_auditor.c b/src/exchangedb/update_auditor.c @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/update_auditor.c + * @brief Implementation of the update_auditor function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_auditor.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_update_auditor (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const char *auditor_url, + const char *auditor_name, + struct GNUNET_TIME_Timestamp change_date, + bool enabled) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (auditor_pub), + GNUNET_PQ_query_param_string (auditor_url), + GNUNET_PQ_query_param_string (auditor_name), + GNUNET_PQ_query_param_bool (enabled), + GNUNET_PQ_query_param_timestamp (&change_date), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "update_auditor", + "UPDATE auditors" + " SET" + " auditor_url=$2" + " ,auditor_name=$3" + " ,is_active=$4" + " ,last_change=$5" + " WHERE auditor_pub=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "update_auditor", + params); +} diff --git a/src/exchangedb/update_kyc_process_by_row.c b/src/exchangedb/update_kyc_process_by_row.c @@ -0,0 +1,132 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/update_kyc_process_by_row.c + * @brief Implementation of the update_kyc_process_by_row function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_kyc_process_by_row.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_update_kyc_process_by_row (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t process_row, + const char *provider_name, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_account_id, + const char *provider_legitimization_id, + const char *redirect_url, + struct GNUNET_TIME_Absolute expiration, + enum TALER_ErrorCode ec, + const char *error_message_hint, + bool finished) +{ + uint32_t ec32 = (uint32_t) ec; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&process_row), + GNUNET_PQ_query_param_string (provider_name), + GNUNET_PQ_query_param_auto_from_type (h_payto), /*3*/ + (NULL != provider_account_id) + ? GNUNET_PQ_query_param_string (provider_account_id) + : GNUNET_PQ_query_param_null (), /*4*/ + (NULL != provider_legitimization_id) + ? GNUNET_PQ_query_param_string (provider_legitimization_id) + : GNUNET_PQ_query_param_null (), /*5*/ + (NULL != redirect_url) + ? GNUNET_PQ_query_param_string (redirect_url) + : GNUNET_PQ_query_param_null (), /*6*/ + GNUNET_PQ_query_param_absolute_time (&expiration), + GNUNET_PQ_query_param_uint32 (&ec32), /* 8 */ + (NULL != error_message_hint) + ? GNUNET_PQ_query_param_string (error_message_hint) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_bool (finished), /* 10 */ + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Updating KYC data for %llu (%s)\n", + (unsigned long long) process_row, + provider_name); + PREPARE (ctx, + "update_legitimization_process", + "UPDATE legitimization_processes" + " SET provider_user_id=$4" + " ,provider_legitimization_id=$5" + " ,redirect_url=$6" + " ,expiration_time=GREATEST(expiration_time,$7)" + " ,error_code=$8" + " ,error_message=$9" + " ,finished=$10" + " WHERE" + " h_payto=$3" + " AND legitimization_process_serial_id=$1" + " AND provider_name=$2;"); + qs = GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "update_legitimization_process", + params); + if (qs <= 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to update legitimization process %llu: %d\n", + (unsigned long long) process_row, + qs); + return qs; + } + if (GNUNET_TIME_absolute_is_future (expiration)) + { + enum GNUNET_DB_QueryStatus qs2; + struct TALER_KycCompletedEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = *h_payto + }; + uint32_t trigger_type = 1; + struct GNUNET_PQ_QueryParam params2[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_uint32 (&trigger_type), + GNUNET_PQ_query_param_end + }; + + GNUNET_PQ_event_notify (ctx->conn, + &rep.header, + NULL, + 0); + PREPARE (ctx, + "alert_kyc_status_change", + "INSERT INTO kyc_alerts" + " (h_payto" + " ,trigger_type)" + " VALUES" + " ($1,$2);"); + qs2 = GNUNET_PQ_eval_prepared_non_select ( + ctx->conn, + "alert_kyc_status_change", + params2); + if (qs2 < 0) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to store KYC alert: %d\n", + qs2); + } + return qs; +} diff --git a/src/exchangedb/update_wire.c b/src/exchangedb/update_wire.c @@ -0,0 +1,90 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023, 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/update_wire.c + * @brief Implementation of the update_wire function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "update_wire.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_update_wire (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + const char *conversion_url, + const char *open_banking_gateway, + const char *wire_transfer_gateway, + const json_t *debit_restrictions, + const json_t *credit_restrictions, + struct GNUNET_TIME_Timestamp change_date, + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority, + bool enabled) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (payto_uri.full_payto), + GNUNET_PQ_query_param_bool (enabled), + NULL == conversion_url + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (conversion_url), + enabled + ? TALER_PQ_query_param_json (debit_restrictions) + : GNUNET_PQ_query_param_null (), + enabled + ? TALER_PQ_query_param_json (credit_restrictions) + : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_timestamp (&change_date), + NULL == master_sig + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_auto_from_type (master_sig), + NULL == bank_label + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (bank_label), + GNUNET_PQ_query_param_int64 (&priority), + NULL == open_banking_gateway + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (open_banking_gateway), + NULL == wire_transfer_gateway + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (wire_transfer_gateway), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "update_wire", + "UPDATE wire_accounts" + " SET" + " is_active=$2" + " ,conversion_url=$3" + " ,debit_restrictions=$4::TEXT::JSONB" + " ,credit_restrictions=$5::TEXT::JSONB" + " ,last_change=$6" + " ,master_sig=$7" + " ,bank_label=$8" + " ,priority=$9" + " ,open_banking_gateway=$10" + " ,wire_transfer_gateway=$11" + " WHERE payto_uri=$1"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "update_wire", + params); +} diff --git a/src/exchangedb/wad_in_insert.c b/src/exchangedb/wad_in_insert.c @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/wad_in_insert.c + * @brief Implementation of the wad_in_insert function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "wad_in_insert.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wad_in_insert (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_WadIdentifierP *wad_id, + const char *origin_exchange_url, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Timestamp execution_date, + const struct TALER_FullPayto debit_account_uri, + const char *section_name, + uint64_t serial_id) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (wad_id), + GNUNET_PQ_query_param_string (origin_exchange_url), + TALER_PQ_query_param_amount (ctx->conn, + amount), + GNUNET_PQ_query_param_timestamp (&execution_date), + GNUNET_PQ_query_param_end + }; + + // FIXME-#7271: should we keep the account data + serial_id? + PREPARE (ctx, + "wad_in_insert", + "INSERT INTO wads_in " + "(wad_id" + ",origin_exchange_url" + ",amount" + ",arrival_time" + ") VALUES " + "($1, $2, $3, $4);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "wad_in_insert", + params); +} diff --git a/src/exchangedb/wire_prepare_data_get.c b/src/exchangedb/wire_prepare_data_get.c @@ -0,0 +1,139 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/wire_prepare_data_get.c + * @brief Implementation of the wire_prepare_data_get function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "wire_prepare_data_get.h" +#include "pg_helper.h" + +/** + * 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 (struct EXCHANGEDB_PostgresContext *ctx, + PGresult *result, + unsigned int num_results) +{ + struct PrewireContext *pc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + uint64_t prewire_uuid; + char *wire_method; + void *buf = NULL; + size_t buf_size; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("prewire_uuid", + &prewire_uuid), + GNUNET_PQ_result_spec_string ("wire_method", + &wire_method), + 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, + wire_method, + buf, + buf_size); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wire_prepare_data_get (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t start_row, + uint64_t limit, + TALER_EXCHANGEDB_WirePreparationIterator cb, + void *cb_cls) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&start_row), + GNUNET_PQ_query_param_uint64 (&limit), + GNUNET_PQ_query_param_end + }; + struct PrewireContext pc = { + .cb = cb, + .cb_cls = cb_cls, + .status = GNUNET_OK + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (ctx, + "wire_prepare_data_get", + "SELECT" + " prewire_uuid" + ",wire_method" + ",buf" + " FROM prewire" + " WHERE prewire_uuid >= $1" + " AND finished=FALSE" + " AND failed=FALSE" + " ORDER BY prewire_uuid ASC" + " LIMIT $2;"); + qs = GNUNET_PQ_eval_prepared_multi_select (ctx->conn, + "wire_prepare_data_get", + params, + &prewire_cb, + &pc); + if (GNUNET_OK != pc.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/exchangedb/wire_prepare_data_insert.c b/src/exchangedb/wire_prepare_data_insert.c @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/wire_prepare_data_insert.c + * @brief Implementation of the wire_prepare_data_insert function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "wire_prepare_data_insert.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wire_prepare_data_insert (struct EXCHANGEDB_PostgresContext *ctx, + const char *type, + const char *buf, + size_t buf_size) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (type), + GNUNET_PQ_query_param_fixed_size (buf, buf_size), + GNUNET_PQ_query_param_end + }; + + + /* Used in #postgres_wire_prepare_data_insert() to store + wire transfer information before actually committing it with the bank */ + PREPARE (ctx, + "wire_prepare_data_insert", + "INSERT INTO prewire " + "(wire_method" + ",buf" + ") VALUES " + "($1, $2);"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "wire_prepare_data_insert", + params); +} diff --git a/src/exchangedb/wire_prepare_data_mark_failed.c b/src/exchangedb/wire_prepare_data_mark_failed.c @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/wire_prepare_data_mark_failed.c + * @brief Implementation of the wire_prepare_data_mark_failed function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "wire_prepare_data_mark_failed.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wire_prepare_data_mark_failed (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t rowid) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&rowid), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "wire_prepare_data_mark_failed", + "UPDATE prewire" + " SET failed=TRUE" + " WHERE prewire_uuid=$1;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "wire_prepare_data_mark_failed", + params); +} diff --git a/src/exchangedb/wire_prepare_data_mark_finished.c b/src/exchangedb/wire_prepare_data_mark_finished.c @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/exchangedb/wire_prepare_data_mark_finished.c + * @brief Implementation of the wire_prepare_data_mark_finished function for Postgres + * @author Christian Grothoff + */ +#include "taler/platform.h" +#include "taler/taler_error_codes.h" +#include "taler/taler_dbevents.h" +#include "taler/taler_pq_lib.h" +#include "wire_prepare_data_mark_finished.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wire_prepare_data_mark_finished (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t rowid) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&rowid), + GNUNET_PQ_query_param_end + }; + + PREPARE (ctx, + "wire_prepare_data_mark_done", + "UPDATE prewire" + " SET finished=TRUE" + " WHERE prewire_uuid=$1;"); + return GNUNET_PQ_eval_prepared_non_select (ctx->conn, + "wire_prepare_data_mark_done", + params); +} diff --git a/src/include/taler/auditor-database/del_denomination_balance.h b/src/include/taler/auditor-database/del_denomination_balance.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/del_denomination_balance.h + * @brief implementation of the del_denomination_balance function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_DEL_DENOMINATION_BALANCE_H +#define AUDITOR_DATABASE_DEL_DENOMINATION_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + +struct AUDITORDB_PostgresContext; +/** + * Delete information about a denomination key's balances. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param denom_pub_hash hash of the denomination public key + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_del_denomination_balance (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash); + +#endif diff --git a/src/include/taler/auditor-database/del_reserve_info.h b/src/include/taler/auditor-database/del_reserve_info.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_del_reserve_info.h + * @brief implementation of the del_reserve_info function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_DEL_RESERVE_INFO_H +#define AUDITOR_DATABASE_DEL_RESERVE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Delete information about a reserve. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub public key of the reserve + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_del_reserve_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub); + + +#endif diff --git a/src/include/taler/auditor-database/delete_auditor_closure_lag.h b/src/include/taler/auditor-database/delete_auditor_closure_lag.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/delete_auditor_closure_lag.h + * @brief implementation of the delete_auditor_closure_lag function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_DELETE_AUDITOR_CLOSURE_LAG_H +#define AUDITOR_DATABASE_DELETE_AUDITOR_CLOSURE_LAG_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + +struct AUDITORDB_PostgresContext; +/** + * A previously missing wire transfer may have been found. Remove an alert + * (if we raised one). + * + * @param cls plugin closure + * @param amount wire transfer amount + * @param wtid wire transfer subject + * @param credit_account_uri destination account + * @return #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no matching alert was + * found + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_auditor_closure_lag (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_Amount *amount, + const struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_FullPayto credit_account_uri); + +#endif diff --git a/src/include/taler/auditor-database/delete_early_aggregation.h b/src/include/taler/auditor-database/delete_early_aggregation.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/delete_early_aggregation.h + * @brief implementation of the delete_early_aggregation function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_DELETE_EARLY_AGGREGATION_H +#define AUDITOR_DATABASE_DELETE_EARLY_AGGREGATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Delete a row from the early aggregation table. + * Usually done when the expected aggregation + * was finally detected. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param batch_deposit_serial_id which entry to delete + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_early_aggregation (struct AUDITORDB_PostgresContext *ctx, + uint64_t batch_deposit_serial_id); + + +#endif diff --git a/src/include/taler/auditor-database/delete_generic.h b/src/include/taler/auditor-database/delete_generic.h @@ -0,0 +1,39 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_delete_generic.h + * @brief implementation of the delete_generic function + * @author Nic Eigel + */ +#ifndef AUDITOR_DATABASE_DELETE_GENERIC_H +#define AUDITOR_DATABASE_DELETE_GENERIC_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + +struct AUDITORDB_PostgresContext; +/** + // FIXME: add comments + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_generic (struct AUDITORDB_PostgresContext *ctx, + enum TALER_AUDITORDB_DeletableSuppressableTables table, + uint64_t row_id); + +#endif diff --git a/src/include/taler/auditor-database/delete_pending_deposit.h b/src/include/taler/auditor-database/delete_pending_deposit.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/delete_pending_deposit.h + * @brief implementation of the delete_pending_deposit function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_DELETE_PENDING_DEPOSIT_H +#define AUDITOR_DATABASE_DELETE_PENDING_DEPOSIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Delete a row from the pending deposit table. + * Usually done when the respective wire transfer + * was finally detected. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param batch_deposit_serial_id which entry to delete + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_pending_deposit (struct AUDITORDB_PostgresContext *ctx, + uint64_t batch_deposit_serial_id); + + +#endif diff --git a/src/include/taler/auditor-database/delete_purse_info.h b/src/include/taler/auditor-database/delete_purse_info.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/delete_purse_info.h + * @brief implementation of the delete_purse_info function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_DELETE_PURSE_INFO_H +#define AUDITOR_DATABASE_DELETE_PURSE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Delete information about a purse. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the reserve + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_purse_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub); + + +#endif diff --git a/src/include/taler/auditor-database/delete_reserve_in_inconsistency.h b/src/include/taler/auditor-database/delete_reserve_in_inconsistency.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/delete_reserve_in_inconsistency.h + * @brief implementation of the delete_reserve_in_inconsistency function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_DELETE_RESERVE_IN_INCONSISTENCY_H +#define AUDITOR_DATABASE_DELETE_RESERVE_IN_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Delete information about an reserve-in-inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param row_id row of the inconsistency in our table + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + uint64_t row_id); + +#endif diff --git a/src/include/taler/auditor-database/delete_wire_out_inconsistency_if_matching.h b/src/include/taler/auditor-database/delete_wire_out_inconsistency_if_matching.h @@ -0,0 +1,36 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_DELETE_WIRE_OUT_INCONSISTENCY_IF_MATCHING_H +#define AUDITOR_DATABASE_DELETE_WIRE_OUT_INCONSISTENCY_IF_MATCHING_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Delete information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_delete_wire_out_inconsistency_if_matching (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_WireOutInconsistency *dc); + +#endif diff --git a/src/include/taler/auditor-database/get_amount_arithmetic_inconsistency.h b/src/include/taler/auditor-database/get_amount_arithmetic_inconsistency.h @@ -0,0 +1,383 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_AMOUNT_ARITHMETIC_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_AMOUNT_ARITHMETIC_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Information about a signing key of an exchange. + */ +struct TALER_AUDITORDB_ExchangeSigningKey +{ + + /** + * When does @e exchange_pub start to be used? + */ + struct GNUNET_TIME_Timestamp ep_start; + + /** + * When will the exchange stop signing with @e exchange_pub? + */ + struct GNUNET_TIME_Timestamp ep_expire; + + /** + * When does the signing key expire (for legal disputes)? + */ + struct GNUNET_TIME_Timestamp ep_end; + + /** + * What is the public offline signing key this is all about? + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * Signature by the offline master key affirming the above. + */ + struct TALER_MasterSignatureP master_sig; +}; + + +/** + * Information about a deposit confirmation we received from + * a merchant. + */ +struct TALER_AUDITORDB_DepositConfirmation +{ + + /** + * Hash over the contract for which this deposit is made. + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Hash over the policy extension for the deposit. + */ + struct TALER_ExtensionPolicyHashP h_policy; + + /** + * Hash over the wiring information of the merchant. + */ + struct TALER_MerchantWireHashP h_wire; + + /** + * Time when this deposit confirmation was generated by the exchange. + */ + struct GNUNET_TIME_Timestamp exchange_timestamp; + + /** + * How much time does the @e merchant have to issue a refund + * request? Zero if refunds are not allowed. After this time, the + * coin cannot be refunded. Note that the wire transfer will not be + * performed by the exchange until the refund deadline. This value + * is taken from the original deposit request. + */ + struct GNUNET_TIME_Timestamp refund_deadline; + + /** + * How much time does the @e exchange have to wire the funds? + */ + struct GNUNET_TIME_Timestamp wire_deadline; + + /** + * Amount to be deposited, excluding fee. Calculated from the + * amount with fee and the fee from the deposit request. + */ + struct TALER_Amount total_without_fee; + + /** + * Array of the coin public keys involved in the + * batch deposit operation. + */ + const struct TALER_CoinSpendPublicKeyP *coin_pubs; + + /** + * Array of coin deposit signatures from the deposit operation. + */ + const struct TALER_CoinSpendSignatureP *coin_sigs; + + /** + * The Merchant's public key. Allows the merchant to later refund + * the transaction or to inquire about the wire transfer identifier. + */ + struct TALER_MerchantPublicKeyP merchant; + + /** + * Signature from the exchange of type + * #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT. + */ + struct TALER_ExchangeSignatureP exchange_sig; + + /** + * Public signing key from the exchange matching @e exchange_sig. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * Exchange master signature over @e exchange_sig. + */ + struct TALER_MasterSignatureP master_sig; + + /** + * Row of this entry in the auditor database. + */ + uint64_t row_id; + + /** + * Length of the @e coin_pubs and @e coin_sigs arrays. + */ + unsigned int num_coins; + + bool suppressed; + +}; + +// MARK: CRUD + +/** + * Information about a row inconsistency + */ +struct TALER_AUDITORDB_Generic_Update +{ + uint64_t row_id; + bool suppressed; + bool ancient; +}; + +/** + * Information about an arithmetic inconsistency + */ +struct TALER_AUDITORDB_AmountArithmeticInconsistency +{ + uint64_t row_id; + uint64_t problem_row_id; + char *operation; + struct TALER_Amount exchange_amount; + struct TALER_Amount auditor_amount; + bool profitable; + bool suppressed; +}; + +/** + * Information about a coin inconsistency + */ +struct TALER_AUDITORDB_CoinInconsistency +{ + uint64_t row_id; + char *operation; + struct TALER_Amount exchange_amount; + struct TALER_Amount auditor_amount; + struct GNUNET_CRYPTO_EddsaPublicKey coin_pub; + bool profitable; +}; + +/** + * Information about a row inconsistency + */ +struct TALER_AUDITORDB_RowInconsistency +{ + uint64_t row_id; + char *row_table; + char *diagnostic; + bool suppressed; +}; + +/** + * Information about a bad sig loss + */ +struct TALER_AUDITORDB_BadSigLosses +{ + uint64_t row_id; + uint64_t problem_row_id; + char *operation; + struct TALER_Amount loss; + struct GNUNET_CRYPTO_EddsaPublicKey operation_specific_pub; + bool suppressed; +}; + +/** + * Information about a closure lags + */ +struct TALER_AUDITORDB_ClosureLags +{ + uint64_t row_id; + uint64_t problem_row_id; + struct TALER_Amount amount; + struct GNUNET_TIME_Absolute deadline; + struct TALER_WireTransferIdentifierRawP wtid; + struct TALER_FullPayto account; + bool suppressed; +}; + +/** + * Information about a emergency + */ +struct TALER_AUDITORDB_Emergency +{ + uint64_t row_id; + struct TALER_DenominationHashP denompub_h; + struct TALER_Amount denom_risk; + struct TALER_Amount denom_loss; + struct GNUNET_TIME_Absolute deposit_start; + struct GNUNET_TIME_Absolute deposit_end; + struct TALER_Amount value; + bool suppressed; +}; + +/** + * Information about an emergency by count + */ +struct TALER_AUDITORDB_EmergenciesByCount +{ + uint64_t row_id; + struct TALER_DenominationHashP denompub_h; + uint64_t num_issued; + uint64_t num_known; + struct TALER_Amount risk; + struct GNUNET_TIME_Absolute start; + struct GNUNET_TIME_Absolute deposit_end; + struct TALER_Amount value; + bool suppressed; +}; + +/** + * Information about progress of the audit. + */ +struct TALER_AUDITORDB_Progress +{ + char *progress_key; + uint64_t progress_offset; +}; + + +/** + * Information about a fee time inconsistency + */ +struct TALER_AUDITORDB_FeeTimeInconsistency +{ + uint64_t row_id; + uint64_t problem_row_id; + char *type; + struct GNUNET_TIME_Absolute time; + char *diagnostic; +}; + +/** + * Information about a denom key validity withdraw inconsistency + */ +struct TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency +{ + uint64_t row_id; + uint64_t problem_row_id; + struct GNUNET_TIME_Absolute execution_date; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_DenominationHashP denompub_h; + bool suppressed; +}; + +/** + * Information about a purse not closed inconsistencies + */ +struct TALER_AUDITORDB_PurseNotClosedInconsistencies +{ + uint64_t row_id; + struct GNUNET_CRYPTO_EddsaPublicKey purse_pub; + struct TALER_Amount amount; + struct GNUNET_TIME_Absolute expiration_date; + bool suppressed; +}; + +/** + * Information about a reserve balance insufficient inconsistency + */ +struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency +{ + uint64_t row_id; + struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub; + bool inconsistency_gain; + struct TALER_Amount inconsistency_amount; + bool suppressed; +}; + +/** + * Information about a reserve in inconsistency + */ +struct TALER_AUDITORDB_ReserveInInconsistency +{ + uint64_t serial_id; + uint64_t bank_row_id; + struct TALER_Amount amount_exchange_expected; + struct TALER_Amount amount_wired; + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_TIME_Absolute timestamp; + struct TALER_FullPayto account; + char *diagnostic; + bool suppressed; + +}; + +/** + * Information about a balance + */ +struct TALER_AUDITORDB_Balances +{ + uint64_t row_id; + char *balance_key; + struct TALER_Amount balance_value; + bool suppressed; + +}; + +/** + * Function called with arithmetic inconsistencies stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_AmountArithmeticInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_AmountArithmeticInconsistency *dc); + +/** + * Get information about deposit confirmations from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_amount_arithmetic_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_AmountArithmeticInconsistencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_auditor_closure_lags.h b/src/include/taler/auditor-database/get_auditor_closure_lags.h @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_AUDITOR_CLOSURE_LAGS_H +#define AUDITOR_DATABASE_GET_AUDITOR_CLOSURE_LAGS_H + + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with closure lags stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ClosureLagsCallback)( + void *cls, + const struct TALER_AUDITORDB_ClosureLags *dc); + +/** + * Get information about auditor closure lags from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_auditor_closure_lags (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ClosureLagsCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_auditor_progress.h b/src/include/taler/auditor-database/get_auditor_progress.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_auditor_progress.h + * @brief implementation of the get_auditor_progress function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_GET_AUDITOR_PROGRESS_H +#define AUDITOR_DATABASE_GET_AUDITOR_PROGRESS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Get information about the progress of the auditor. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param progress_key name of the progress indicator + * @param[out] progress_offset set to offset until which we have made progress + * @param ... NULL terminated list of additional key-value pairs to fetch + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_auditor_progress (struct AUDITORDB_PostgresContext *ctx, + const char *progress_key, + uint64_t *progress_offset, + ...); + +#endif diff --git a/src/include/taler/auditor-database/get_bad_sig_losses.h b/src/include/taler/auditor-database/get_bad_sig_losses.h @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_GET_BAD_SIG_LOSSES_H +#define AUDITOR_DATABASE_GET_BAD_SIG_LOSSES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with bad signature losses stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_BadSigLossesCallback)( + void *cls, + const struct TALER_AUDITORDB_BadSigLosses *dc); + +/** + * Get information about bad signature losses from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param op_spec_pub public key to filter by; FIXME: replace by pointer + * @param op operation to filter by + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_bad_sig_losses (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + const struct GNUNET_CRYPTO_EddsaPublicKey *op_spec_pub, + const char *op, + TALER_AUDITORDB_BadSigLossesCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_balance.h b/src/include/taler/auditor-database/get_balance.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/get_balance.h + * @brief implementation of the get_balance function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_GET_BALANCE_H +#define AUDITOR_DATABASE_GET_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Get summary information about balance tracked by the auditor. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param balance_key key of the balance to store + * @param[out] balance_value set to amount stored under @a balance_key + * @param ... NULL terminated list of additional key-value pairs to fetch + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_balance (struct AUDITORDB_PostgresContext *ctx, + const char *balance_key, + struct TALER_Amount *balance_value, + ...); + +#endif diff --git a/src/include/taler/auditor-database/get_balances.h b/src/include/taler/auditor-database/get_balances.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_GET_BALANCES_H +#define AUDITOR_DATABASE_GET_BALANCES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_BalancesCallback)( + void *cls, + const struct TALER_AUDITORDB_Balances *dc); + +/** + * Get information about balances from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param balance_key key to filter by, NULL to match all balance keys + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_balances (struct AUDITORDB_PostgresContext *ctx, + const char *balance_key, + TALER_AUDITORDB_BalancesCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_coin_inconsistency.h b/src/include/taler/auditor-database/get_coin_inconsistency.h @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_COIN_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_COIN_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with coin inconsistencies stored in + * the auditor's database. + * + * @param cls closure + * @param serial_id location of the @a dc in the database + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_CoinInconsistencyCallback)( + void *cls, + uint64_t serial_id, + const struct TALER_AUDITORDB_CoinInconsistency *dc); + +/** + * Get information about deposit confirmations from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_coin_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_CoinInconsistencyCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/auditor-database/get_denomination_balance.h b/src/include/taler/auditor-database/get_denomination_balance.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_denomination_balance.h + * @brief implementation of the get_denomination_balance function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_GET_DENOMINATION_BALANCE_H +#define AUDITOR_DATABASE_GET_DENOMINATION_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Get information about a denomination key's balances. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param denom_pub_hash hash of the denomination public key + * @param[out] dcd circulation data to initialize + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_denomination_balance (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + struct TALER_AUDITORDB_DenominationCirculationData *dcd); + +#endif diff --git a/src/include/taler/auditor-database/get_denomination_key_validity_withdraw_inconsistency.h b/src/include/taler/auditor-database/get_denomination_key_validity_withdraw_inconsistency.h @@ -0,0 +1,61 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with fee denomination key validity withdraw inconsistency stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistencyCallback)( + void *cls, + const struct + TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency *dc); + +/** + * Get information about denominations key validity withdraw inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_denomination_key_validity_withdraw_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_denomination_pending.h b/src/include/taler/auditor-database/get_denomination_pending.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_GET_DENOMINATION_PENDING_H +#define AUDITOR_DATABASE_GET_DENOMINATION_PENDING_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_DenominationPendingCallback)( + void *cls, + uint64_t serial_id, + const struct TALER_AUDITORDB_DenominationPending *dc); + +/** + * Get information about denomination-pending from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_denomination_pending (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_DenominationPendingCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_denominations_without_sigs.h b/src/include/taler/auditor-database/get_denominations_without_sigs.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_DENOMINATIONS_WITHOUT_SIGS_H +#define AUDITOR_DATABASE_GET_DENOMINATIONS_WITHOUT_SIGS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_DenominationsWithoutSigsCallback)( + void *cls, + const struct TALER_AUDITORDB_DenominationsWithoutSigs *dc); + +/** + * Get information about denominations-without-sigs from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_denominations_without_sigs (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_DenominationsWithoutSigsCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_deposit_confirmations.h b/src/include/taler/auditor-database/get_deposit_confirmations.h @@ -0,0 +1,292 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_deposit_confirmations.h + * @brief implementation of the get_deposit_confirmations function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_GET_DEPOSIT_CONFIRMATIONS_H +#define AUDITOR_DATABASE_GET_DEPOSIT_CONFIRMATIONS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Balance values for a reserve (or all reserves). + */ +struct TALER_AUDITORDB_ReserveFeeBalance +{ + /** + * Remaining funds. + */ + struct TALER_Amount reserve_balance; + + /** + * Losses from operations that should not have + * happened (e.g. negative balance). + */ + struct TALER_Amount reserve_loss; + + /** + * Fees charged for withdraw. + */ + struct TALER_Amount withdraw_fee_balance; + + /** + * Fees charged for closing. + */ + struct TALER_Amount close_fee_balance; + + /** + * Fees charged for purse creation. + */ + struct TALER_Amount purse_fee_balance; + + /** + * Opening fees charged. + */ + struct TALER_Amount open_fee_balance; + + /** + * History fees charged. + */ + struct TALER_Amount history_fee_balance; +}; + + +/** + * Balance data for denominations in circulation. + */ +struct TALER_AUDITORDB_DenominationCirculationData +{ + /** + * Amount of outstanding coins in circulation. + */ + struct TALER_Amount denom_balance; + + /** + * Amount lost due coins illicitly accepted (effectively, a + * negative @a denom_balance). + */ + struct TALER_Amount denom_loss; + + /** + * Total amount that could still be theoretically lost in the future due to + * recoup operations. (Total put into circulation minus @e recoup_loss). + */ + struct TALER_Amount denom_risk; + + /** + * Amount lost due to recoups. + */ + struct TALER_Amount recoup_loss; + + /** + * Number of coins of this denomination that the exchange signed into + * existence. + */ + uint64_t num_issued; +}; + +struct TALER_AUDITORDB_DenominationsWithoutSigs +{ + uint64_t row_id; + struct TALER_DenominationHashP denompub_h; + struct TALER_Amount value; + struct GNUNET_TIME_Absolute start_time; + struct GNUNET_TIME_Absolute end_time; + bool suppressed; +}; + +struct TALER_AUDITORDB_MisattributionInInconsistency +{ + uint64_t row_id; + struct TALER_Amount amount; + uint64_t bank_row; + struct TALER_ReservePublicKeyP reserve_pub; + bool suppressed; + +}; + +struct TALER_AUDITORDB_Reserves +{ + uint64_t row_id; + uint64_t auditor_reserves_rowid; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_Amount reserve_balance; + struct TALER_Amount reserve_loss; + struct TALER_Amount withdraw_fee_balance; + struct TALER_Amount close_fee_balance; + struct TALER_Amount purse_fee_balance; + struct TALER_Amount open_fee_balance; + struct TALER_Amount history_fee_balance; + struct GNUNET_TIME_Absolute expiration_date; + struct TALER_FullPayto origin_account; + bool suppressed; + +}; + +struct TALER_AUDITORDB_Purses +{ + uint64_t row_id; + uint64_t auditor_purses_rowid; + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_Amount balance; + struct TALER_Amount target; + struct GNUNET_TIME_Absolute expiration_date; + bool suppressed; + +}; + +struct TALER_AUDITORDB_HistoricDenominationRevenue +{ + uint64_t row_id; + struct TALER_DenominationHashP denom_pub_hash; + struct GNUNET_TIME_Absolute revenue_timestamp; + struct TALER_Amount revenue_balance; + struct TALER_Amount loss_balance; + bool suppressed; + +}; + +struct TALER_AUDITORDB_DenominationPending +{ + uint64_t row_id; + struct TALER_DenominationHashP denom_pub_hash; + struct TALER_Amount denom_balance; + struct TALER_Amount denom_loss; + uint64_t num_issued; + struct TALER_Amount denom_risk; + struct TALER_Amount recoup_loss; + bool suppressed; + +}; + +struct TALER_AUDITORDB_HistoricReserveSummary +{ + uint64_t row_id; + struct GNUNET_TIME_Absolute start_date; + struct GNUNET_TIME_Absolute end_date; + struct TALER_Amount reserve_profits; + bool suppressed; + +}; + +struct TALER_AUDITORDB_ExchangeSignkeys +{ + uint64_t row_id; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_MasterSignatureP master_sig; + struct GNUNET_TIME_Absolute ep_valid_from; + struct GNUNET_TIME_Absolute ep_expire_sign; + struct GNUNET_TIME_Absolute ep_expire_legal; + bool suppressed; + +}; + +struct TALER_AUDITORDB_WireFormatInconsistency +{ + uint64_t row_id; + struct TALER_Amount amount; + uint64_t wire_offset; + char *diagnostic; + bool suppressed; + +}; + +struct TALER_AUDITORDB_WireOutInconsistency +{ + uint64_t row_id; + struct TALER_FullPayto destination_account; + char *diagnostic; + uint64_t wire_out_row_id; + struct TALER_Amount expected; + struct TALER_Amount claimed; + bool suppressed; + +}; + +struct TALER_AUDITORDB_RowMinorInconsistencies +{ + uint64_t row_id; + char *row_table; + uint64_t problem_row; + char *diagnostic; + bool suppressed; +}; + + +struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency +{ + uint64_t row_id; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_Amount exchange_amount; + struct TALER_Amount auditor_amount; + bool suppressed; + +}; + +struct TALER_AUDITORDB_ReserveNotClosedInconsistency +{ + uint64_t row_id; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_Amount balance; + struct GNUNET_TIME_Absolute expiration_time; + char *diagnostic; + bool suppressed; + +}; + +/** + * Function called with deposit confirmations stored in + * the auditor's database. + * + * @param cls closure + * @param dc the deposit confirmation itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_DepositConfirmationCallback)( + void *cls, + const struct TALER_AUDITORDB_DepositConfirmation *dc); + +/** + * Get information about deposit confirmations from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_deposit_confirmations (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_DepositConfirmationCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_emergency.h b/src/include/taler/auditor-database/get_emergency.h @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_EMERGENCY_H +#define AUDITOR_DATABASE_GET_EMERGENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with emergencies stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_EmergencyCallback)( + void *cls, + const struct TALER_AUDITORDB_Emergency *dc); + +/** + * Get information about emergency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_emergency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_EmergencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_emergency_by_count.h b/src/include/taler/auditor-database/get_emergency_by_count.h @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_EMERGENCY_BY_COUNT_H +#define AUDITOR_DATABASE_GET_EMERGENCY_BY_COUNT_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with emergencies stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_EmergenciesByCountCallback)( + void *cls, + const struct TALER_AUDITORDB_EmergenciesByCount *dc); + +/** + * Get information about emergency by count from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_emergency_by_count (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_EmergenciesByCountCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_exchange_signkeys.h b/src/include/taler/auditor-database/get_exchange_signkeys.h @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_EXCHANGE_SIGNKEYS_H +#define AUDITOR_DATABASE_GET_EXCHANGE_SIGNKEYS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ExchangeSignkeysCallback)( + void *cls, + uint64_t serial_id, + const struct TALER_AUDITORDB_ExchangeSignkeys *dc); + +/** + * Get information about exchange-signkeys from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_exchange_signkeys (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ExchangeSignkeysCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_fee_time_inconsistency.h b/src/include/taler/auditor-database/get_fee_time_inconsistency.h @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_FEE_TIME_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_FEE_TIME_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with fee time inconsistency stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_FeeTimeInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_FeeTimeInconsistency *dc); + +/** + * Get information about fee time inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_fee_time_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_FeeTimeInconsistencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_misattribution_in_inconsistency.h b/src/include/taler/auditor-database/get_misattribution_in_inconsistency.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_MISATTRIBUTION_IN_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_MISATTRIBUTION_IN_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_MisattributionInInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_MisattributionInInconsistency *dc); + +/** + * Get information about misattribution-in-inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_misattribution_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_MisattributionInInconsistencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_progress_points.h b/src/include/taler/auditor-database/get_progress_points.h @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/get_progress_points.h + * @brief implementation of the get_progress_points function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_GET_PROGRESS_POINTS_H +#define AUDITOR_DATABASE_GET_PROGRESS_POINTS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ProgressPointsCallback)( + void *cls, + const struct TALER_AUDITORDB_Progress *pp); + +/** + * Get information about progress from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param progress_key only return this particular progress point + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_progress_points (struct AUDITORDB_PostgresContext *ctx, + const char *progress_key, + TALER_AUDITORDB_ProgressPointsCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/auditor-database/get_purse_info.h b/src/include/taler/auditor-database/get_purse_info.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/get_purse_info.h + * @brief implementation of the get_purse_info function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_GET_PURSE_INFO_H +#define AUDITOR_DATABASE_GET_PURSE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Get information about a purse. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @param[out] rowid which row did we get the information from + * @param[out] balance set to balance of the purse + * @param[out] expiration_date expiration date of the purse + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_purse_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + uint64_t *rowid, + struct TALER_Amount *balance, + struct GNUNET_TIME_Timestamp *expiration_date); + +#endif diff --git a/src/include/taler/auditor-database/get_purse_not_closed_inconsistencies.h b/src/include/taler/auditor-database/get_purse_not_closed_inconsistencies.h @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_PURSE_NOT_CLOSED_INCONSISTENCIES_H +#define AUDITOR_DATABASE_GET_PURSE_NOT_CLOSED_INCONSISTENCIES_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with purse not closed inconsistencies stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_PurseNotClosedInconsistenciesCallback)( + void *cls, + const struct TALER_AUDITORDB_PurseNotClosedInconsistencies *dc); + +/** + * Get information about purse not closed inconsistencies from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_purse_not_closed_inconsistencies (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_PurseNotClosedInconsistenciesCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_purses.h b/src/include/taler/auditor-database/get_purses.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_GET_PURSES_H +#define AUDITOR_DATABASE_GET_PURSES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_PursesCallback)( + void *cls, + uint64_t serial_id, + const struct TALER_AUDITORDB_Purses *dc); + +/** + * Get information about purses from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_purses (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_PursesCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_reserve_balance_insufficient_inconsistency.h b/src/include/taler/auditor-database/get_reserve_balance_insufficient_inconsistency.h @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with reserve balance insufficient inconsistency stored in + * the auditor's database. + * + * @param cls closure + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ReserveBalanceInsufficientInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency *dc); + +/** + * Get information about reserve balance insufficient inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_balance_insufficient_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ReserveBalanceInsufficientInconsistencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_reserve_balance_summary_wrong_inconsistency.h b/src/include/taler/auditor-database/get_reserve_balance_summary_wrong_inconsistency.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency *dc); + +/** + * Get information about reserve-balance-summary-wrong-inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_balance_summary_wrong_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_reserve_in_inconsistency.h b/src/include/taler/auditor-database/get_reserve_in_inconsistency.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_RESERVE_IN_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_RESERVE_IN_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ReserveInInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_ReserveInInconsistency *dc); + +/** + * Get information about reserve-in-inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ReserveInInconsistencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_reserve_info.h b/src/include/taler/auditor-database/get_reserve_info.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_reserve_info.h + * @brief implementation of the get_reserve_info function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_GET_RESERVE_INFO_H +#define AUDITOR_DATABASE_GET_RESERVE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Get information about a reserve. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub public key of the reserve + * @param[out] rowid which row did we get the information from + * @param[out] rfb where to store the reserve balance summary + * @param[out] expiration_date expiration date of the reserve + * @param[out] sender_account from where did the money in the reserve originally come from + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t *rowid, + struct TALER_AUDITORDB_ReserveFeeBalance *rfb, + struct GNUNET_TIME_Timestamp *expiration_date, + struct TALER_FullPayto *sender_account); + + +#endif diff --git a/src/include/taler/auditor-database/get_reserve_not_closed_inconsistency.h b/src/include/taler/auditor-database/get_reserve_not_closed_inconsistency.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_RESERVE_NOT_CLOSED_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_RESERVE_NOT_CLOSED_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ReserveNotClosedInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_ReserveNotClosedInconsistency *dc); + +/** + * Get information about reserve-not-closed-inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserve_not_closed_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_ReserveNotClosedInconsistencyCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_reserves.h b/src/include/taler/auditor-database/get_reserves.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_GET_RESERVES_H +#define AUDITOR_DATABASE_GET_RESERVES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ReservesCallback)( + void *cls, + uint64_t serial_id, + const struct TALER_AUDITORDB_Reserves *dc); + +/** + * Get information about reserves from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_reserves (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_ReservesCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_row_inconsistency.h b/src/include/taler/auditor-database/get_row_inconsistency.h @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_GET_ROW_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_ROW_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with row inconsistencies stored in + * the auditor's database. + * + * @param cls closure + * @param serial_id location of the @a dc in the database + * @param dc the structure itself + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_RowInconsistencyCallback)( + void *cls, + uint64_t serial_id, + const struct TALER_AUDITORDB_RowInconsistency *dc); + +/** + * Get information about deposit confirmations from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_row_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_RowInconsistencyCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/auditor-database/get_row_minor_inconsistencies.h b/src/include/taler/auditor-database/get_row_minor_inconsistencies.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_ROW_MINOR_INCONSISTENCIES_H +#define AUDITOR_DATABASE_GET_ROW_MINOR_INCONSISTENCIES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_RowMinorInconsistenciesCallback)( + void *cls, + const struct TALER_AUDITORDB_RowMinorInconsistencies *dc); + +/** + * Get information about row-minor-inconsistencies from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_row_minor_inconsistencies (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_RowMinorInconsistenciesCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/get_wire_fee_summary.h b/src/include/taler/auditor-database/get_wire_fee_summary.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_wire_fee_summary.h + * @brief implementation of the get_wire_fee_summary function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_GET_WIRE_FEE_SUMMARY_H +#define AUDITOR_DATABASE_GET_WIRE_FEE_SUMMARY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Get summary information about an exchanges wire fee balance. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param[out] wire_fee_balance set amount the exchange gained in wire fees + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_wire_fee_summary (struct AUDITORDB_PostgresContext *ctx, + struct TALER_Amount *wire_fee_balance); + + +#endif diff --git a/src/include/taler/auditor-database/get_wire_format_inconsistency.h b/src/include/taler/auditor-database/get_wire_format_inconsistency.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_WIRE_FORMAT_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_WIRE_FORMAT_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_WireFormatInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_WireFormatInconsistency *dc); + +/** + * Get information about wire-format-inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_wire_format_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_WireFormatInconsistencyCallback cb, + void *cb_cls); + +#endif // AUDITOR_DATABASE_GET_WIRE_FORMAT_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/get_wire_out_inconsistency.h b/src/include/taler/auditor-database/get_wire_out_inconsistency.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_GET_WIRE_OUT_INCONSISTENCY_H +#define AUDITOR_DATABASE_GET_WIRE_OUT_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_WireOutInconsistencyCallback)( + void *cls, + const struct TALER_AUDITORDB_WireOutInconsistency *dc); + +/** + * Get information about wire-out-inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit number of records to return, negative for descending + * @param offset table row to start from, exclusive, direction determined by @a limit + * @param return_suppressed should suppressed rows be returned anyway? + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_get_wire_out_inconsistency (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_WireOutInconsistencyCallback cb, + void *cb_cls); + +#endif // AUDITOR_DATABASE_GET_WIRE_OUT_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_amount_arithmetic_inconsistency.h b/src/include/taler/auditor-database/insert_amount_arithmetic_inconsistency.h @@ -0,0 +1,37 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_INSERT_AMOUNT_ARITHMETIC_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_AMOUNT_ARITHMETIC_INCONSISTENCY_H + +#include "taler/taler_util.h" +// #include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a deposit confirmation into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_amount_arithmetic_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_AmountArithmeticInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_AMOUNT_ARITHMETIC_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_auditor_closure_lags.h b/src/include/taler/auditor-database/insert_auditor_closure_lags.h @@ -0,0 +1,37 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_AUDITOR_CLOSURE_LAGS_H +#define AUDITOR_DATABASE_INSERT_AUDITOR_CLOSURE_LAGS_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a closure into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_auditor_closure_lags (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ClosureLags *dc); + +#endif // AUDITOR_DATABASE_INSERT_AUDITOR_CLOSURE_LAGS_H diff --git a/src/include/taler/auditor-database/insert_auditor_progress.h b/src/include/taler/auditor-database/insert_auditor_progress.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_auditor_progress.h + * @brief implementation of the insert_auditor_progress function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_AUDITOR_PROGRESS_H +#define AUDITOR_DATABASE_INSERT_AUDITOR_PROGRESS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about the auditor's progress with an exchange's + * data. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param progress_key name of the progress indicator + * @param progress_offset offset until which we have made progress + * @param ... NULL terminated list of additional key-value pairs to insert + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_auditor_progress (struct AUDITORDB_PostgresContext *ctx, + const char *progress_key, + uint64_t progress_offset, + ...); + +#endif diff --git a/src/include/taler/auditor-database/insert_bad_sig_losses.h b/src/include/taler/auditor-database/insert_bad_sig_losses.h @@ -0,0 +1,36 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_INSERT_BAD_SIG_LOSSES_H +#define AUDITOR_DATABASE_INSERT_BAD_SIG_LOSSES_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_bad_sig_losses (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_BadSigLosses *dc); + +#endif // AUDITOR_DATABASE_INSERT_BAD_SIG_LOSSES_H diff --git a/src/include/taler/auditor-database/insert_balance.h b/src/include/taler/auditor-database/insert_balance.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_balance.h + * @brief implementation of the insert_balance function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_BALANCE_H +#define AUDITOR_DATABASE_INSERT_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a balance tracked by the auditor. There must not be an + * existing record. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param balance_key key of the balance to store + * @param balance_value value to store + * @param ... NULL terminated list of additional key-value pairs to insert + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_balance (struct AUDITORDB_PostgresContext *ctx, + const char *balance_key, + const struct TALER_Amount *balance_value, + ...); + + +#endif diff --git a/src/include/taler/auditor-database/insert_coin_inconsistency.h b/src/include/taler/auditor-database/insert_coin_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_COIN_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_COIN_INCONSISTENCY_H + +#include "taler/taler_util.h" +// #include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a deposit confirmation into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_coin_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_CoinInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_COIN_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_denomination_balance.h b/src/include/taler/auditor-database/insert_denomination_balance.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_denomination_balance.h + * @brief implementation of the insert_denomination_balance function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_DENOMINATION_BALANCE_H +#define AUDITOR_DATABASE_INSERT_DENOMINATION_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a denomination key's balances. There + * must not be an existing record for the denomination key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param denom_pub_hash hash of the denomination public key + * @param dcd circulation data to store + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_denomination_balance (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + const struct TALER_AUDITORDB_DenominationCirculationData *dcd); + + +#endif diff --git a/src/include/taler/auditor-database/insert_denomination_key_validity_withdraw_inconsistency.h b/src/include/taler/auditor-database/insert_denomination_key_validity_withdraw_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a denomination key validity withdraw inconsistency into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_denomination_key_validity_withdraw_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct + TALER_AUDITORDB_DenominationKeyValidityWithdrawInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_DENOMINATION_KEY_VALIDITY_WITHDRAW_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_denomination_pending.h b/src/include/taler/auditor-database/insert_denomination_pending.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_DENOMINATION_PENDING_H +#define AUDITOR_DATABASE_INSERT_DENOMINATION_PENDING_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_denomination_pending (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_DenominationPending *dc); + +#endif // AUDITOR_DATABASE_INSERT_DENOMINATION_PENDING_H diff --git a/src/include/taler/auditor-database/insert_denominations_without_sigs.h b/src/include/taler/auditor-database/insert_denominations_without_sigs.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_DENOMINATIONS_WITHOUT_SIGS_H +#define AUDITOR_DATABASE_INSERT_DENOMINATIONS_WITHOUT_SIGS_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_denominations_without_sigs (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_DenominationsWithoutSigs *dc); + +#endif // AUDITOR_DATABASE_INSERT_DENOMINATIONS_WITHOUT_SIGS_H diff --git a/src/include/taler/auditor-database/insert_deposit_confirmation.h b/src/include/taler/auditor-database/insert_deposit_confirmation.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_deposit_confirmation.h + * @brief implementation of the insert_deposit_confirmation function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_DEPOSIT_CONFIRMATION_H +#define AUDITOR_DATABASE_INSERT_DEPOSIT_CONFIRMATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a deposit confirmation into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_deposit_confirmation (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_DepositConfirmation *dc); + + +#endif diff --git a/src/include/taler/auditor-database/insert_early_aggregation.h b/src/include/taler/auditor-database/insert_early_aggregation.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/insert_early_aggregation.h + * @brief implementation of the insert_early_aggregation function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_EARLY_AGGREGATION_H +#define AUDITOR_DATABASE_INSERT_EARLY_AGGREGATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert new row into the early aggregation table. This can happen simply + * because of when the taler-helper-auditor-transfer looks at which of the + * two tables. If it is cleared in the next iteration, this is perfectly + * expected. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param batch_deposit_serial_id where in the batch deposit table are we + * @param tracking_serial_id where in the tracking table are we + * @param total_amount value of all missing deposits, including fees + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_early_aggregation (struct AUDITORDB_PostgresContext *ctx, + uint64_t batch_deposit_serial_id, + uint64_t tracking_serial_id, + const struct TALER_Amount *total_amount); + +#endif diff --git a/src/include/taler/auditor-database/insert_emergency.h b/src/include/taler/auditor-database/insert_emergency.h @@ -0,0 +1,37 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_EMERGENCY_H +#define AUDITOR_DATABASE_INSERT_EMERGENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a emergency into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_emergency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_Emergency *dc); + +#endif // AUDITOR_DATABASE_INSERT_EMERGENCY_H diff --git a/src/include/taler/auditor-database/insert_emergency_by_count.h b/src/include/taler/auditor-database/insert_emergency_by_count.h @@ -0,0 +1,37 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_EMERGENCY_BY_COUNT_H +#define AUDITOR_DATABASE_INSERT_EMERGENCY_BY_COUNT_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a emergency into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_emergency_by_count (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_EmergenciesByCount *dc); + +#endif // AUDITOR_DATABASE_INSERT_EMERGENCY_BY_COUNT_H diff --git a/src/include/taler/auditor-database/insert_exchange_signkey.h b/src/include/taler/auditor-database/insert_exchange_signkey.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_exchange_signkey.h + * @brief implementation of the insert_exchange_signkey function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_EXCHANGE_SIGNKEY_H +#define AUDITOR_DATABASE_INSERT_EXCHANGE_SIGNKEY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a signing key of the exchange. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param sk signing key information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_exchange_signkey (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ExchangeSigningKey *sk); + +#endif diff --git a/src/include/taler/auditor-database/insert_fee_time_inconsistency.h b/src/include/taler/auditor-database/insert_fee_time_inconsistency.h @@ -0,0 +1,37 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_FEE_TIME_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_FEE_TIME_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a fee time inconsistency into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_fee_time_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_FeeTimeInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_FEE_TIME_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_historic_denom_revenue.h b/src/include/taler/auditor-database/insert_historic_denom_revenue.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_historic_denom_revenue.h + * @brief implementation of the insert_historic_denom_revenue function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_HISTORIC_DENOM_REVENUE_H +#define AUDITOR_DATABASE_INSERT_HISTORIC_DENOM_REVENUE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about an exchange's historic + * revenue about a denomination key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param denom_pub_hash hash of the denomination key + * @param revenue_timestamp when did this profit get realized + * @param revenue_balance what was the total profit made from + * deposit fees, melting fees, refresh fees + * and coins that were never returned? + * @param loss_balance total losses suffered by the exchange at the time + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_historic_denom_revenue (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + struct GNUNET_TIME_Timestamp revenue_timestamp, + const struct TALER_Amount *revenue_balance, + const struct TALER_Amount *loss_balance); + +#endif diff --git a/src/include/taler/auditor-database/insert_historic_reserve_revenue.h b/src/include/taler/auditor-database/insert_historic_reserve_revenue.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_historic_reserve_revenue.h + * @brief implementation of the insert_historic_reserve_revenue function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_HISTORIC_RESERVE_REVENUE_H +#define AUDITOR_DATABASE_INSERT_HISTORIC_RESERVE_REVENUE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about an exchange's historic revenue from reserves. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param start_time beginning of aggregated time interval + * @param end_time end of aggregated time interval + * @param reserve_profits total profits made + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_historic_reserve_revenue (struct AUDITORDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp start_time, + struct GNUNET_TIME_Timestamp end_time, + const struct TALER_Amount *reserve_profits); + +#endif diff --git a/src/include/taler/auditor-database/insert_misattribution_in_inconsistency.h b/src/include/taler/auditor-database/insert_misattribution_in_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_MISATTRIBUTION_IN_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_MISATTRIBUTION_IN_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_misattribution_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_MisattributionInInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_MISATTRIBUTION_IN_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_pending_deposit.h b/src/include/taler/auditor-database/insert_pending_deposit.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/insert_pending_deposit.h + * @brief implementation of the insert_pending_deposit function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_PENDING_DEPOSIT_H +#define AUDITOR_DATABASE_INSERT_PENDING_DEPOSIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert new row into the pending deposits table. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param batch_deposit_serial_id where in the table are we + * @param total_amount value of all missing deposits, including fees + * @param wire_target_h_payto hash of the recipient account's payto URI + * @param deadline what was the requested wire transfer deadline + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_pending_deposit (struct AUDITORDB_PostgresContext *ctx, + uint64_t batch_deposit_serial_id, + const struct TALER_FullPaytoHashP *wire_target_h_payto, + const struct TALER_Amount *total_amount, + struct GNUNET_TIME_Timestamp deadline); + + +#endif diff --git a/src/include/taler/auditor-database/insert_purse_info.h b/src/include/taler/auditor-database/insert_purse_info.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/insert_purse_info.h + * @brief implementation of the insert_purse_info function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_PURSE_INFO_H +#define AUDITOR_DATABASE_INSERT_PURSE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a purse. There must not be an + * existing record for the purse. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @param balance balance of the purse + * @param expiration_date expiration date of the purse + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_purse_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_Amount *balance, + struct GNUNET_TIME_Timestamp expiration_date); + +#endif diff --git a/src/include/taler/auditor-database/insert_purse_not_closed_inconsistencies.h b/src/include/taler/auditor-database/insert_purse_not_closed_inconsistencies.h @@ -0,0 +1,37 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_PURSE_NOT_CLOSED_INCONSISTENCIES_H +#define AUDITOR_DATABASE_INSERT_PURSE_NOT_CLOSED_INCONSISTENCIES_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a purse not closed inconsistencies into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_purse_not_closed_inconsistencies (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_PurseNotClosedInconsistencies *dc); + +#endif // AUDITOR_DATABASE_INSERT_PURSE_NOT_CLOSED_INCONSISTENCIES_H diff --git a/src/include/taler/auditor-database/insert_reserve_balance_insufficient_inconsistency.h b/src/include/taler/auditor-database/insert_reserve_balance_insufficient_inconsistency.h @@ -0,0 +1,37 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a reserve balance inconsistency into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_balance_insufficient_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ReserveBalanceInsufficientInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_RESERVE_BALANCE_INSUFFICIENT_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_reserve_balance_summary_wrong_inconsistency.h b/src/include/taler/auditor-database/insert_reserve_balance_summary_wrong_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_balance_summary_wrong_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ReserveBalanceSummaryWrongInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_RESERVE_BALANCE_SUMMARY_WRONG_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_reserve_in_inconsistency.h b/src/include/taler/auditor-database/insert_reserve_in_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_RESERVE_IN_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_RESERVE_IN_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ReserveInInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_RESERVE_IN_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_reserve_info.h b/src/include/taler/auditor-database/insert_reserve_info.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_reserve_info.h + * @brief implementation of the insert_reserve_info function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_INSERT_RESERVE_INFO_H +#define AUDITOR_DATABASE_INSERT_RESERVE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a reserve. There must not be an + * existing record for the reserve. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub public key of the reserve + * @param rfb balance amounts for the reserve + * @param expiration_date when will the reserve expire + * @param origin_account where did the money in the reserve originally come from + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_AUDITORDB_ReserveFeeBalance *rfb, + struct GNUNET_TIME_Timestamp expiration_date, + const struct TALER_FullPayto origin_account); + +#endif diff --git a/src/include/taler/auditor-database/insert_reserve_not_closed_inconsistency.h b/src/include/taler/auditor-database/insert_reserve_not_closed_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_RESERVE_NOT_CLOSED_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_RESERVE_NOT_CLOSED_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_reserve_not_closed_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_ReserveNotClosedInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_RESERVE_NOT_CLOSED_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_row_inconsistency.h b/src/include/taler/auditor-database/insert_row_inconsistency.h @@ -0,0 +1,37 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef AUDITOR_DATABASE_INSERT_ROW_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_ROW_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a deposit confirmation into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_row_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_RowInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_ROW_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_row_minor_inconsistencies.h b/src/include/taler/auditor-database/insert_row_minor_inconsistencies.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_ROW_MINOR_INCONSISTENCIES_H +#define AUDITOR_DATABASE_INSERT_ROW_MINOR_INCONSISTENCIES_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_row_minor_inconsistencies (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_RowMinorInconsistencies *dc); + +#endif // AUDITOR_DATABASE_INSERT_ROW_MINOR_INCONSISTENCIES_H diff --git a/src/include/taler/auditor-database/insert_wire_format_inconsistency.h b/src/include/taler/auditor-database/insert_wire_format_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_WIRE_FORMAT_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_WIRE_FORMAT_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_wire_format_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_WireFormatInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_WIRE_FORMAT_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/insert_wire_out_inconsistency.h b/src/include/taler/auditor-database/insert_wire_out_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +#ifndef AUDITOR_DATABASE_INSERT_WIRE_OUT_INCONSISTENCY_H +#define AUDITOR_DATABASE_INSERT_WIRE_OUT_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a bad sig loss into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param dc deposit confirmation information to store + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_insert_wire_out_inconsistency (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_AUDITORDB_WireOutInconsistency *dc); + +#endif // AUDITOR_DATABASE_INSERT_WIRE_OUT_INCONSISTENCY_H diff --git a/src/include/taler/auditor-database/lookup_reserve_in_inconsistency.h b/src/include/taler/auditor-database/lookup_reserve_in_inconsistency.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +#ifndef AUDITOR_DATABASE_LOOKUP_RESERVE_IN_INCONSISTENCY_H +#define AUDITOR_DATABASE_LOOKUP_RESERVE_IN_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + +struct AUDITORDB_PostgresContext; +/** + * Lookup information about reserve-in-inconsistency from the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param bank_row_id row of the transaction at the bank + * @param[out] dc set to the transaction details + * @return query result status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_lookup_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + uint64_t bank_row_id, + struct TALER_AUDITORDB_ReserveInInconsistency *dc); + +#endif diff --git a/src/include/taler/auditor-database/select_early_aggregations.h b/src/include/taler/auditor-database/select_early_aggregations.h @@ -0,0 +1,99 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/select_early_aggregations.h + * @brief implementation of the select_early_aggregations function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_SELECT_EARLY_AGGREGATIONS_H +#define AUDITOR_DATABASE_SELECT_EARLY_AGGREGATIONS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Information about an early aggregation event. + */ +struct TALER_AUDITORDB_EarlyAggregation +{ + /** + * Row of the event in the auditor database. + */ + uint64_t row_id; + + /** + * Row of the batch deposit in the exchange database. + */ + uint64_t batch_deposit_serial_id; + + /** + * FIXME + */ + uint64_t tracking_serial_id; + + /** + * Total amount involved. + */ + struct TALER_Amount total; + + /** + * True if this report was previously suppressed. + */ + bool suppressed; +}; + + +/** + * Function to call with information about early aggregations. + * + * @param cls closure + * @param ea event data + * @return #GNUNET_OK to continue to iterate + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_EarlyAggregationsCallback)( + void *cls, + const struct TALER_AUDITORDB_EarlyAggregation *ea); + +/** + * Returns all aggregations that were found that were done + * too early. + * + * @param cls closure + * @param limit number of rows to return, negative to iterate backwards + * @param offset starting offset, exclusive + * @param return_suppressed true to also return suppressed events + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_select_early_aggregations (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_EarlyAggregationsCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/auditor-database/select_historic_denom_revenue.h b/src/include/taler/auditor-database/select_historic_denom_revenue.h @@ -0,0 +1,93 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_historic_denom_revenue.h + * @brief implementation of the select_historic_denom_revenue function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_SELECT_HISTORIC_DENOM_REVENUE_H +#define AUDITOR_DATABASE_SELECT_HISTORIC_DENOM_REVENUE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +/* Callback typedefs */ +/** + * @file include/taler/taler_auditordb_plugin.h + * @brief Low-level (statement-level) database access for the auditor + * @author Florian Dold + * @author Christian Grothoff + */ +#ifndef TALER_AUDITORDB_PLUGIN_H +#define TALER_AUDITORDB_PLUGIN_H + +#include <jansson.h> +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_db_lib.h> +#include <taler/taler_util.h> +#include <taler/taler_auditordb_lib.h> +#include <taler/taler_signatures.h> + + + +struct AUDITORDB_PostgresContext; +/** + * Function called with the results of select_historic_denom_revenue() + * + * @param cls closure + * @param serial_id row for the denomination revenue in the auditor database + * @param denom_pub_hash hash of the denomination key + * @param revenue_timestamp when did this profit get realized + * @param revenue_balance what was the total profit made from + * deposit fees, melting fees, refresh fees + * and coins that were never returned? + * @param loss_balance what was the total loss + * @return sets the return value of select_denomination_info(), + * #GNUNET_OK to continue, + * #GNUNET_NO to stop processing further rows + * #GNUNET_SYSERR or other values on error. + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_HistoricDenominationRevenueDataCallback)( + void *cls, + uint64_t serial_id, + const struct TALER_DenominationHashP *denom_pub_hash, + struct GNUNET_TIME_Timestamp revenue_timestamp, + const struct TALER_Amount *revenue_balance, + const struct TALER_Amount *loss_balance); + +/** + * Obtain all of the historic denomination key revenue + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit return at most this number of results, negative to descend from @a offset + * @param offset row from which to return @a limit results + * @param cb function to call with the results + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_select_historic_denom_revenue (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/select_historic_reserve_revenue.h b/src/include/taler/auditor-database/select_historic_reserve_revenue.h @@ -0,0 +1,73 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_historic_reserve_revenue.h + * @brief implementation of the select_historic_reserve_revenue function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_SELECT_HISTORIC_RESERVE_REVENUE_H +#define AUDITOR_DATABASE_SELECT_HISTORIC_RESERVE_REVENUE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with the results of select_historic_reserve_revenue() + * + * @param cls closure + * @param serial_id row ID in the history table + * @param start_time beginning of aggregated time interval + * @param end_time end of aggregated time interval + * @param reserve_profits total profits made + * + * @return sets the return value of select_denomination_info(), + * #GNUNET_OK to continue, + * #GNUNET_NO to stop processing further rows + * #GNUNET_SYSERR or other values on error. + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_HistoricReserveRevenueDataCallback)( + void *cls, + uint64_t serial_id, + struct GNUNET_TIME_Timestamp start_time, + struct GNUNET_TIME_Timestamp end_time, + const struct TALER_Amount *reserve_profits); + +/** + * Return information about an exchange's historic revenue from reserves. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param limit return at most this number of results, negative to descend from @a offset + * @param offset row from which to return @a limit results + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_select_historic_reserve_revenue (struct AUDITORDB_PostgresContext *ctx, + int64_t limit, + uint64_t offset, + TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/auditor-database/select_pending_deposits.h b/src/include/taler/auditor-database/select_pending_deposits.h @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/select_pending_deposits.h + * @brief implementation of the select_pending_deposits function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_SELECT_PENDING_DEPOSITS_H +#define AUDITOR_DATABASE_SELECT_PENDING_DEPOSITS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called on deposits that are past their due date + * and have not yet seen a wire transfer. + * + * @param cls closure + * @param row_id row ID of the alert in the auditor database + * @param batch_deposit_serial_id where in the exchange table are we + * @param total_amount value of all missing deposits, including fees + * @param wire_target_h_payto hash of the recipient account's payto URI + * @param deadline what was the earliest requested wire transfer deadline + * @param suppressed true if this report was suppressed + */ +typedef void +(*TALER_AUDITORDB_WireMissingCallback) ( + void *cls, + uint64_t row_id, + uint64_t batch_deposit_serial_id, + const struct TALER_Amount *total_amount, + const struct TALER_FullPaytoHashP *wire_target_h_payto, + struct GNUNET_TIME_Timestamp deadline, + bool suppressed); + +/** + * Return (batch) deposits for which we have not yet + * seen the required wire transfer. + * + * @param cls closure + * @param deadline only return up to this deadline + * @param limit number of rows to return, negative to iterate backwards + * @param offset starting offset, exclusive + * @param return_suppressed true to also return suppressed events + * @param cb function to call on each entry + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_select_pending_deposits (struct AUDITORDB_PostgresContext *ctx, + struct GNUNET_TIME_Absolute deadline, + int64_t limit, + uint64_t offset, + bool return_suppressed, + TALER_AUDITORDB_WireMissingCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/select_purse_expired.h b/src/include/taler/auditor-database/select_purse_expired.h @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/select_purse_expired.h + * @brief implementation of the select_purse_expired function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_SELECT_PURSE_EXPIRED_H +#define AUDITOR_DATABASE_SELECT_PURSE_EXPIRED_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + + + +struct AUDITORDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called on expired purses. + * + * @param cls closure + * @param purse_pub public key of the purse + * @param balance amount of money in the purse + * @param expiration_date when did the purse expire? + * @return #GNUNET_OK to continue to iterate + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_AUDITORDB_ExpiredPurseCallback)( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_Amount *balance, + struct GNUNET_TIME_Timestamp expiration_date); + +/** + * Get information about expired purses. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param cb function to call on expired purses + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_select_purse_expired (struct AUDITORDB_PostgresContext *ctx, + TALER_AUDITORDB_ExpiredPurseCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/auditor-database/select_reserve_in_inconsistency.h b/src/include/taler/auditor-database/select_reserve_in_inconsistency.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/select_reserve_in_inconsistency.h + * @brief implementation of the select_reserve_in_inconsistency function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_SELECT_RESERVE_IN_INCONSISTENCY_H +#define AUDITOR_DATABASE_SELECT_RESERVE_IN_INCONSISTENCY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Return any reserve incoming inconsistency associated with the + * given @a bank_row_id. + * + * @param cls closure + * @param bank_row_id row to select by + * @param[out] dc details to return + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_select_reserve_in_inconsistency (struct AUDITORDB_PostgresContext *ctx, + uint64_t bank_row_id, + struct TALER_AUDITORDB_ReserveInInconsistency *dc); + + +#endif diff --git a/src/include/taler/auditor-database/template.h b/src/include/taler/auditor-database/template.h @@ -0,0 +1,31 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/template.h + * @brief implementation of the template function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_TEMPLATE_H +#define AUDITOR_DATABASE_TEMPLATE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +#endif diff --git a/src/include/taler/auditor-database/update_auditor_progress.h b/src/include/taler/auditor-database/update_auditor_progress.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_auditor_progress.h + * @brief implementation of the update_auditor_progress function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_UPDATE_AUDITOR_PROGRESS_H +#define AUDITOR_DATABASE_UPDATE_AUDITOR_PROGRESS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Update information about the progress of the auditor. There + * must be an existing record for the exchange. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param progress_key name of the progress indicator + * @param progress_offset offset until which we have made progress + * @param ... NULL terminated list of additional key-value pairs to update + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_update_auditor_progress (struct AUDITORDB_PostgresContext *ctx, + const char *progress_key, + uint64_t progress_offset, + ...); + +#endif diff --git a/src/include/taler/auditor-database/update_balance.h b/src/include/taler/auditor-database/update_balance.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/update_balance.h + * @brief implementation of the update_balance function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_UPDATE_BALANCE_H +#define AUDITOR_DATABASE_UPDATE_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about a balance tracked by the auditor. Destructively updates an + * existing record, which must already exist. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param balance_key key of the balance to store + * @param balance_amount value to store + * @param ... NULL terminated list of additional key-value pairs to update + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_update_balance (struct AUDITORDB_PostgresContext *ctx, + const char *balance_key, + const struct TALER_Amount *balance_amount, + ...); + + +#endif diff --git a/src/include/taler/auditor-database/update_denomination_balance.h b/src/include/taler/auditor-database/update_denomination_balance.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_denomination_balance.h + * @brief implementation of the update_denomination_balance function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_UPDATE_DENOMINATION_BALANCE_H +#define AUDITOR_DATABASE_UPDATE_DENOMINATION_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Update information about a denomination key's balances. There + * must be an existing record for the denomination key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param denom_pub_hash hash of the denomination public key + * @param dcd circulation data to store + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_update_denomination_balance (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + const struct TALER_AUDITORDB_DenominationCirculationData *dcd); + + +#endif diff --git a/src/include/taler/auditor-database/update_generic_suppressed.h b/src/include/taler/auditor-database/update_generic_suppressed.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_auditor_progress.h + * @brief implementation of the update_auditor_progress function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_UPDATE_GENERIC_SUPPRESSED_H +#define AUDITOR_DATABASE_UPDATE_GENERIC_SUPPRESSED_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + // FIXME: add comments + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_update_generic_suppressed (struct AUDITORDB_PostgresContext *ctx, + enum TALER_AUDITORDB_DeletableSuppressableTables table, + uint64_t row_id, + bool suppressed); + +#endif diff --git a/src/include/taler/auditor-database/update_purse_info.h b/src/include/taler/auditor-database/update_purse_info.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/auditor-database/update_purse_info.h + * @brief implementation of the update_purse_info function for Postgres + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_UPDATE_PURSE_INFO_H +#define AUDITOR_DATABASE_UPDATE_PURSE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Update information about a purse. Destructively updates an + * existing record, which must already exist. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @param balance new balance for the purse + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_update_purse_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_Amount *balance); + + +#endif diff --git a/src/include/taler/auditor-database/update_reserve_info.h b/src/include/taler/auditor-database/update_reserve_info.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_reserve_info.h + * @brief implementation of the update_reserve_info function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_UPDATE_RESERVE_INFO_H +#define AUDITOR_DATABASE_UPDATE_RESERVE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Update information about a reserve. Destructively updates an + * existing record, which must already exist. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub public key of the reserve + * @param rfb amounts for the reserve + * @param expiration_date expiration date of the reserve + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_update_reserve_info (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_AUDITORDB_ReserveFeeBalance *rfb, + struct GNUNET_TIME_Timestamp expiration_date); + +#endif diff --git a/src/include/taler/auditor-database/update_wire_fee_summary.h b/src/include/taler/auditor-database/update_wire_fee_summary.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_update_wire_fee_summary.h + * @brief implementation of the update_wire_fee_summary function + * @author Christian Grothoff + */ +#ifndef AUDITOR_DATABASE_UPDATE_WIRE_FEE_SUMMARY_H +#define AUDITOR_DATABASE_UPDATE_WIRE_FEE_SUMMARY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_auditordb_plugin.h" + + + +struct AUDITORDB_PostgresContext; +/** + * Insert information about exchange's wire fee balance. Destructively updates an + * existing record, which must already exist. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param wire_fee_balance amount the exchange gained in wire fees + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +AUDITORDB_update_wire_fee_summary (struct AUDITORDB_PostgresContext *ctx, + const struct TALER_Amount *wire_fee_balance); + +#endif diff --git a/src/include/taler/exchange-database/abort_shard.h b/src/include/taler/exchange-database/abort_shard.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/abort_shard.h + * @brief implementation of the abort_shard function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ABORT_SHARD_H +#define EXCHANGE_DATABASE_ABORT_SHARD_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_abort_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + uint64_t start_row, + uint64_t end_row); + +#endif diff --git a/src/include/taler/exchange-database/activate_signing_key.h b/src/include/taler/exchange-database/activate_signing_key.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/activate_signing_key.h + * @brief implementation of the activate_signing_key function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ACTIVATE_SIGNING_KEY_H +#define EXCHANGE_DATABASE_ACTIVATE_SIGNING_KEY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Add signing key. + * + * @param cls closure + * @param exchange_pub the exchange online signing public key + * @param meta meta data about @a exchange_pub + * @param master_sig master signature to add + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_activate_signing_key (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_EXCHANGEDB_SignkeyMetaData *meta, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/add_denomination_key.h b/src/include/taler/exchange-database/add_denomination_key.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/add_denomination_key.h + * @brief implementation of the add_denomination_key function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ADD_DENOMINATION_KEY_H +#define EXCHANGE_DATABASE_ADD_DENOMINATION_KEY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Activate denomination key, turning it into a "current" or "valid" + * denomination key by adding the master signature. + * + * @param cls closure + * @param h_denom_pub hash of the denomination public key + * @param denom_pub the actual denomination key + * @param meta meta data about the denomination + * @param master_sig master signature to add + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_add_denomination_key (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/add_policy_fulfillment_proof.h b/src/include/taler/exchange-database/add_policy_fulfillment_proof.h @@ -0,0 +1,40 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/add_policy_fulfillment_proof.h + * @brief implementation of the add_policy_fulfillment_proof function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ADD_POLICY_FULFILLMENT_PROOF_H +#define EXCHANGE_DATABASE_ADD_POLICY_FULFILLMENT_PROOF_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Add a proof of fulfillment into the policy_fulfillments table + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param fulfillment fullfilment transaction data to be added + * @return query execution status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_add_policy_fulfillment_proof (struct EXCHANGEDB_PostgresContext *ctx, + struct TALER_PolicyFulfillmentTransactionData *fulfillment); + +#endif diff --git a/src/include/taler/exchange-database/aggregate.h b/src/include/taler/exchange-database/aggregate.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/aggregate.h + * @brief implementation of the aggregate function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_AGGREGATE_H +#define EXCHANGE_DATABASE_AGGREGATE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_aggregate (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_Amount *total); + +#endif diff --git a/src/include/taler/exchange-database/batch_ensure_coin_known.h b/src/include/taler/exchange-database/batch_ensure_coin_known.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/batch_ensure_coin_known.h + * @brief implementation of the batch_ensure_coin_known function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_BATCH_ENSURE_COIN_KNOWN_H +#define EXCHANGE_DATABASE_BATCH_ENSURE_COIN_KNOWN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Make sure the array of given @a coin is known to the database. + * + * @param cls database connection plugin state + * @param coin array of coins that must be made known + * @param[out] result array where to store information about each coin + * @param coin_length length of the @a coin and @a result arraysf + * @param batch_size desired (maximum) batch size + * @return database transaction status, non-negative on success + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_batch_ensure_coin_known (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo *coin, + struct TALER_EXCHANGEDB_CoinInfo *result, + unsigned int coin_length, + unsigned int batch_size); + +#endif diff --git a/src/include/taler/exchange-database/begin_revolving_shard.h b/src/include/taler/exchange-database/begin_revolving_shard.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/begin_revolving_shard.h + * @brief implementation of the begin_revolving_shard function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_BEGIN_REVOLVING_SHARD_H +#define EXCHANGE_DATABASE_BEGIN_REVOLVING_SHARD_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to grab a revolving work shard on an operation @a op. Runs + * in its own transaction. Returns the oldest inactive shard. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param job_name name of the operation to grab a revolving shard for + * @param shard_size desired shard size + * @param shard_limit exclusive end of the shard range + * @param[out] start_row inclusive start row of the shard (returned) + * @param[out] end_row inclusive end row of the shard (returned) + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_begin_revolving_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + uint32_t shard_size, + uint32_t shard_limit, + uint32_t *start_row, + uint32_t *end_row); + +#endif diff --git a/src/include/taler/exchange-database/begin_shard.h b/src/include/taler/exchange-database/begin_shard.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/begin_shard.h + * @brief implementation of the begin_shard function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_BEGIN_SHARD_H +#define EXCHANGE_DATABASE_BEGIN_SHARD_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to grab a work shard on an operation @a op. Runs in its + * own transaction. + * + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_begin_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + struct GNUNET_TIME_Relative delay, + uint64_t shard_size, + uint64_t *start_row, + uint64_t *end_row); + +#endif diff --git a/src/include/taler/exchange-database/clear_aml_lock.h b/src/include/taler/exchange-database/clear_aml_lock.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/clear_aml_lock.h + * @brief implementation of the clear_aml_lock function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_CLEAR_AML_LOCK_H +#define EXCHANGE_DATABASE_CLEAR_AML_LOCK_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Clear a lock on running AML programs for the @a h_payto + * account. Returns 0 if @a h_payto is not known; does not + * actually care if there was a lock. Also does not by + * itself notify clients waiting for the lock, that + * notification the caller must do separately after finishing + * the database update. + * + * @param cls closure + * @param h_payto account to clear the lock for + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_clear_aml_lock (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto); + +#endif diff --git a/src/include/taler/exchange-database/commit.h b/src/include/taler/exchange-database/commit.h @@ -0,0 +1,39 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/commit.h + * @brief implementation of the commit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_COMMIT_H +#define EXCHANGE_DATABASE_COMMIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Commit the current transaction of a database connection. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @return final transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_commit (struct EXCHANGEDB_PostgresContext *ctx); + +#endif diff --git a/src/include/taler/exchange-database/complete_shard.h b/src/include/taler/exchange-database/complete_shard.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/complete_shard.h + * @brief implementation of the complete_shard function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_COMPLETE_SHARD_H +#define EXCHANGE_DATABASE_COMPLETE_SHARD_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 +EXCHANGEDB_complete_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + uint64_t start_row, + uint64_t end_row); + +#endif diff --git a/src/include/taler/exchange-database/compute_shard.h b/src/include/taler/exchange-database/compute_shard.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/compute_shard.h + * @brief implementation of the compute_shard function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_COMPUTE_SHARD_H +#define EXCHANGE_DATABASE_COMPUTE_SHARD_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Compute the shard number of a given @a merchant_pub. + * + * @param merchant_pub merchant public key to compute shard for + * @return shard number + */ +uint64_t +EXCHANGEDB_compute_shard (const struct TALER_MerchantPublicKeyP *merchant_pub); + + +#endif diff --git a/src/include/taler/exchange-database/count_known_coins.h b/src/include/taler/exchange-database/count_known_coins.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/count_known_coins.h + * @brief implementation of the count_known_coins function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_COUNT_KNOWN_COINS_H +#define EXCHANGE_DATABASE_COUNT_KNOWN_COINS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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` + */ +long long +EXCHANGEDB_count_known_coins (struct EXCHANGEDB_PostgresContext *ctx, + const struct + TALER_DenominationHashP *denom_pub_hash); + +#endif diff --git a/src/include/taler/exchange-database/create_aggregation_transient.h b/src/include/taler/exchange-database/create_aggregation_transient.h @@ -0,0 +1,50 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/create_aggregation_transient.h + * @brief implementation of the create_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_CREATE_AGGREGATION_TRANSIENT_H +#define EXCHANGE_DATABASE_CREATE_AGGREGATION_TRANSIENT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @param merchant_pub public key of the merchant receiving the transfer + * @param wtid the raw wire transfer identifier to be used + * @param kyc_requirement_row row in legitimization_requirements that need to be satisfied to continue, or 0 for none + * @param total amount to be wired in the future + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_create_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const char *exchange_account_section, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_WireTransferIdentifierRawP *wtid, + uint64_t kyc_requirement_row, + const struct TALER_Amount *total); + +#endif diff --git a/src/include/taler/exchange-database/create_tables.h b/src/include/taler/exchange-database/create_tables.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/create_tables.h + * @brief implementation of the create_tables function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_CREATE_TABLES_H +#define EXCHANGE_DATABASE_CREATE_TABLES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Create the necessary tables if they are not present + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param support_partitions true to enable partitioning support (disables foreign key constraints) + * @param num_partitions number of partitions to create, + * (0 to not actually use partitions, 1 to only + * setup a default partition, >1 for real partitions) + * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_create_tables (struct EXCHANGEDB_PostgresContext *ctx, + bool support_partitions, + uint32_t num_partitions); + + +#endif diff --git a/src/include/taler/exchange-database/delete_aggregation_transient.h b/src/include/taler/exchange-database/delete_aggregation_transient.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/delete_aggregation_transient.h + * @brief implementation of the delete_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DELETE_AGGREGATION_TRANSIENT_H +#define EXCHANGE_DATABASE_DELETE_AGGREGATION_TRANSIENT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Delete 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 + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_delete_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const struct TALER_WireTransferIdentifierRawP *wtid); + +#endif diff --git a/src/include/taler/exchange-database/delete_shard_locks.h b/src/include/taler/exchange-database/delete_shard_locks.h @@ -0,0 +1,40 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/delete_shard_locks.h + * @brief implementation of the delete_shard_locks function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DELETE_SHARD_LOCKS_H +#define EXCHANGE_DATABASE_DELETE_SHARD_LOCKS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 +EXCHANGEDB_delete_shard_locks (struct EXCHANGEDB_PostgresContext *ctx); + +#endif diff --git a/src/include/taler/exchange-database/disable_rules.h b/src/include/taler/exchange-database/disable_rules.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/disable_rules.h + * @brief implementation of the disable_rules function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DISABLE_RULES_H +#define EXCHANGE_DATABASE_DISABLE_RULES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Disable (delete/drop) customization rule schema from a deployment. + * + * @param cls closure + * @param schema name of the schema with customization rules to remove + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_disable_rules (struct EXCHANGEDB_PostgresContext *ctx, + const char *schema); + +#endif diff --git a/src/include/taler/exchange-database/do_check_deposit_idempotent.h b/src/include/taler/exchange-database/do_check_deposit_idempotent.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_check_deposit_idempotent.h + * @brief implementation of the do_check_deposit_idempotent function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_CHECK_DEPOSIT_IDEMPOTENT_H +#define EXCHANGE_DATABASE_DO_CHECK_DEPOSIT_IDEMPOTENT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Check ifdeposit operation is idempotent to existing one. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param bd batch deposit operation details + * @param[in,out] exchange_timestamp time to use for the deposit (possibly updated) + * @param[out] is_idempotent set to true if the request is idempotent + * @return query execution status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_check_deposit_idempotent (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_BatchDeposit *bd, + struct GNUNET_TIME_Timestamp *exchange_timestamp, + bool *is_idempotent); + +#endif diff --git a/src/include/taler/exchange-database/do_deposit.h b/src/include/taler/exchange-database/do_deposit.h @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2026 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_deposit.h + * @brief implementation of the do_deposit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_DEPOSIT_H +#define EXCHANGE_DATABASE_DO_DEPOSIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Perform deposit operation, checking for sufficient balance + * of the coins and possibly persisting the deposit details. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param bd batch deposit operation details + * @param deposit_fees array of "bd->num_cids" deposit fees + * of the respective coins + * @param[in,out] exchange_timestamp time to use for the deposit (possibly updated) + * @param[out] accumulated_total_without_fee set to the sum of all deposits + * made for this merchant and contract (minus deposit fees) + * @param[out] balance_ok set to true if the balance was sufficient + * @param[out] bad_balance_index set to the first index of a coin for which the balance was insufficient, + * only used if @a balance_ok is set to false. + * @param[out] in_conflict set to true if the deposit conflicted + * @return query execution status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_BatchDeposit *bd, + const struct TALER_Amount deposit_fees[], + struct GNUNET_TIME_Timestamp *exchange_timestamp, + struct TALER_Amount *accumulated_total_without_fee, + bool *balance_ok, + uint32_t *bad_balance_index, + bool *in_conflict); + +#endif diff --git a/src/include/taler/exchange-database/do_purse_delete.h b/src/include/taler/exchange-database/do_purse_delete.h @@ -0,0 +1,50 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_purse_delete.h + * @brief implementation of the do_purse_delete function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_PURSE_DELETE_H +#define EXCHANGE_DATABASE_DO_PURSE_DELETE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to explicitly delete a purse. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to delete + * @param purse_sig signature affirming the deletion + * @param[out] decided set to true if the purse was + * already decided and thus could not be deleted + * @param[out] found set to true if the purse was found + * (if false, purse could not be deleted) + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_purse_delete (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig, + bool *decided, + bool *found); + +#endif diff --git a/src/include/taler/exchange-database/do_purse_deposit.h b/src/include/taler/exchange-database/do_purse_deposit.h @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_purse_deposit.h + * @brief implementation of the do_purse_deposit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_PURSE_DEPOSIT_H +#define EXCHANGE_DATABASE_DO_PURSE_DEPOSIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to execute a transaction crediting + * a purse with @a amount from @a coin_pub. Reduces the + * value of @a coin_pub and increase the balance of + * the @a purse_pub purse. If the balance reaches the + * target amount and the purse has been merged, triggers + * the updates of the reserve/account balance. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to credit + * @param coin_pub coin to deposit (debit) + * @param amount fraction of the coin's value to deposit + * @param coin_sig signature affirming the operation + * @param amount_minus_fee amount to add to the purse + * @param[out] balance_ok set to false if the coin's + * remaining balance is below @a amount; + * in this case, the return value will be + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure + * @param[out] too_late set to true if it is too late to deposit into the purse + * @param[out] conflict set to true if the deposit failed due to a conflict (coin already spent, + * or deposited into this purse with a different amount) + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_purse_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendSignatureP *coin_sig, + const struct TALER_Amount *amount_minus_fee, + bool *balance_ok, + bool *too_late, + bool *conflict); + +#endif diff --git a/src/include/taler/exchange-database/do_purse_merge.h b/src/include/taler/exchange-database/do_purse_merge.h @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_purse_merge.h + * @brief implementation of the do_purse_merge function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_PURSE_MERGE_H +#define EXCHANGE_DATABASE_DO_PURSE_MERGE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to approve merging a purse into a + * reserve by the respective purse merge key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to merge + * @param merge_sig signature affirming the merge + * @param merge_timestamp time of the merge + * @param reserve_sig signature of the reserve affirming the merge + * @param partner_url URL of the partner exchange, can be NULL if the reserves lives with us + * @param reserve_pub public key of the reserve to credit + * @param[out] no_partner set to true if @a partner_url is unknown + * @param[out] no_balance set to true if the @a purse_pub is not paid up yet + * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_purse_merge (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergeSignatureP *merge_sig, + const struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_ReserveSignatureP *reserve_sig, + const char *partner_url, + const struct TALER_ReservePublicKeyP *reserve_pub, + bool *no_partner, + bool *no_balance, + bool *in_conflict); + +#endif diff --git a/src/include/taler/exchange-database/do_recoup.h b/src/include/taler/exchange-database/do_recoup.h @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_recoup.h + * @brief implementation of the do_recoup function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_RECOUP_H +#define EXCHANGE_DATABASE_DO_RECOUP_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 withdraw_serial_id row in the withdraw 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_recoup (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t withdraw_serial_id, + const union GNUNET_CRYPTO_BlindingSecretP *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); + +#endif diff --git a/src/include/taler/exchange-database/do_recoup_refresh.h b/src/include/taler/exchange-database/do_recoup_refresh.h @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_recoup_refresh.h + * @brief implementation of the do_recoup_refresh function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_RECOUP_REFRESH_H +#define EXCHANGE_DATABASE_DO_RECOUP_REFRESH_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_recoup_refresh (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *old_coin_pub, + uint64_t rrc_serial, + const union GNUNET_CRYPTO_BlindingSecretP *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); + +#endif diff --git a/src/include/taler/exchange-database/do_refresh.h b/src/include/taler/exchange-database/do_refresh.h @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_refresh.h + * @brief implementation of the do_refresh function for Postgres + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_DO_REFRESH_H +#define EXCHANGE_DATABASE_DO_REFRESH_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Perform refresh operation--introduced with v26 of the API--, + * checking for sufficient balance of the coin and possibly persisting the melt/refresh details. + * + * @param cls the plugin-specific state + * @param[in,out] refresh refresh operation details; the noreveal_index + * is set in case the coin was already melted before + * @param timestamp the timestamp of this melt operation, helpful for the coin history. + * @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] found set to true if there exists already an entry in the database for + * the calculated commitment hash. + * @param[out] noreveal_index if @e idempotent ist true, the existing value of the noreveal_index. + * @param[out] nonce_reuse set to true if the blinding seed for CS was re-used. + * @param[out] balance_ok set to true if the balance was sufficient + * @param[out] coin_balance if balance_ok is false, set to the remaining value of the coin + * @return query execution status, NO_RESULTS in case of an unknown coin. + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_refresh (struct EXCHANGEDB_PostgresContext *ctx, + struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh, + const struct GNUNET_TIME_Timestamp *timestamp, + bool *found, + uint32_t *noreveal_index, + bool *zombie_required, + bool *nonce_reuse, + bool *balance_ok, + struct TALER_Amount *coin_balance); + +#endif diff --git a/src/include/taler/exchange-database/do_refund.h b/src/include/taler/exchange-database/do_refund.h @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_refund.h + * @brief implementation of the do_refund function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_REFUND_H +#define EXCHANGE_DATABASE_DO_REFUND_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 reused + * @return query execution status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_refund (struct EXCHANGEDB_PostgresContext *ctx, + 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); + +#endif diff --git a/src/include/taler/exchange-database/do_reserve_open.h b/src/include/taler/exchange-database/do_reserve_open.h @@ -0,0 +1,65 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_do_reserve_open.h + * @brief implementation of the do_reserve_open function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_RESERVE_OPEN_H +#define EXCHANGE_DATABASE_DO_RESERVE_OPEN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Perform reserve open operation on database. + * + * @param cls closure + * @param reserve_pub which reserve is this about? + * @param total_paid total amount paid (coins and reserve) + * @param reserve_payment amount to be paid from the reserve + * @param min_purse_limit minimum number of purses we should be able to open + * @param reserve_sig signature by the reserve for the operation + * @param desired_expiration when should the reserve expire (earliest time) + * @param now when did we the client initiate the action + * @param open_fee annual fee to be charged for the open operation by the exchange + * @param[out] no_funds set to true if reserve balance is insufficient + * @param[out] reserve_balance set to the original reserve balance (at the start of this transaction) + * @param[out] open_cost set to the actual cost + * @param[out] final_expiration when will the reserve expire now + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_reserve_open (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *total_paid, + const struct TALER_Amount *reserve_payment, + uint32_t min_purse_limit, + const struct TALER_ReserveSignatureP *reserve_sig, + struct GNUNET_TIME_Timestamp desired_expiration, + struct GNUNET_TIME_Timestamp now, + const struct TALER_Amount *open_fee, + bool *no_funds, + struct TALER_Amount *reserve_balance, + struct TALER_Amount *open_cost, + struct GNUNET_TIME_Timestamp *final_expiration); + + +#endif diff --git a/src/include/taler/exchange-database/do_reserve_purse.h b/src/include/taler/exchange-database/do_reserve_purse.h @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_reserve_purse.h + * @brief implementation of the do_reserve_purse function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DO_RESERVE_PURSE_H +#define EXCHANGE_DATABASE_DO_RESERVE_PURSE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Function called insert request to merge a purse into a reserve by the + * respective purse merge key. The purse must not have been merged into a + * different reserve. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to merge + * @param merge_sig signature affirming the merge + * @param merge_timestamp time of the merge + * @param reserve_sig signature of the reserve affirming the merge + * @param purse_fee amount to charge the reserve for the purse creation, NULL to use the quota + * @param reserve_pub public key of the reserve to credit + * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already + * @param[out] no_reserve set to true if @a reserve_pub is not a known reserve + * @param[out] insufficient_funds set to true if @a reserve_pub has insufficient capacity to create another purse + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_reserve_purse (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergeSignatureP *merge_sig, + const struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_ReserveSignatureP *reserve_sig, + const struct TALER_Amount *purse_fee, + const struct TALER_ReservePublicKeyP *reserve_pub, + bool *in_conflict, + bool *no_reserve, + bool *insufficient_funds); + +#endif diff --git a/src/include/taler/exchange-database/do_withdraw.h b/src/include/taler/exchange-database/do_withdraw.h @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/do_withdraw.h + * @brief implementation of the do_withdraw function for Postgres + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_DO_WITHDRAW_H +#define EXCHANGE_DATABASE_DO_WITHDRAW_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Perform reserve update as part of an age-withdraw operation, checking for + * sufficient balance and fulfillment of age requirements. Finally persisting + * the withdrawal details. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param withdraw the withdraw data + * @param now the timestamp of the withdraw + * @param[out] balance_ok set to true if the balance was sufficient + * @param[out] reserve_balance set to original balance of the reserve + * @param[out] age_ok set to true if age requirements were met + * @param[out] allowed_maximum_age if @e age_ok is FALSE, this is set to the allowed maximum age + * @param[out] reserve_birthday if @e age_ok is FALSE, this is set to the reserve's birthday + * @param[out] idempotent set to true if an entry already exists for the given h_planchets and reserve_pub + * @param[out] noreveal_index if @e idempotent is true, set to the noreveal_index in the existing record + * @param[out] nonce_reuse set to true if the blinding_seed has been found in the table for a different withdraw + * @return 0 if no reserve was found, 1 if a reserve was found, else the query execution status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_do_withdraw (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_Withdraw *withdraw, + const struct GNUNET_TIME_Timestamp *now, + bool *balance_ok, + struct TALER_Amount *reserve_balance, + bool *age_ok, + uint16_t *allowed_maximum_age, + uint32_t *reserve_birthday, + bool *idempotent, + uint16_t *noreveal_index, + bool *nonce_reuse); + +#endif diff --git a/src/include/taler/exchange-database/drain_kyc_alert.h b/src/include/taler/exchange-database/drain_kyc_alert.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/drain_kyc_alert.h + * @brief implementation of the drain_kyc_alert function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DRAIN_KYC_ALERT_H +#define EXCHANGE_DATABASE_DRAIN_KYC_ALERT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_drain_kyc_alert (struct EXCHANGEDB_PostgresContext *ctx, + uint32_t trigger_type, + struct TALER_NormalizedPaytoHashP *h_payto); + +#endif diff --git a/src/include/taler/exchange-database/drop_tables.h b/src/include/taler/exchange-database/drop_tables.h @@ -0,0 +1,40 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/drop_tables.h + * @brief implementation of the drop_tables function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_DROP_TABLES_H +#define EXCHANGE_DATABASE_DROP_TABLES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Drop all Taler tables. This should only be used by testcases. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_drop_tables (struct EXCHANGEDB_PostgresContext *ctx); + +#endif diff --git a/src/include/taler/exchange-database/enable_rules.h b/src/include/taler/exchange-database/enable_rules.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/enable_rules.h + * @brief implementation of the enable_rules function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ENABLE_RULES_H +#define EXCHANGE_DATABASE_ENABLE_RULES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Enable (create/insert) customization rule schema from a deployment. + * + * @param cls closure + * @param schema name of the schema with customization rules to remove + * @return transaction status + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_enable_rules (struct EXCHANGEDB_PostgresContext *ctx, + const char *schema); + +#endif diff --git a/src/include/taler/exchange-database/ensure_coin_known.h b/src/include/taler/exchange-database/ensure_coin_known.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/ensure_coin_known.h + * @brief implementation of the ensure_coin_known function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ENSURE_COIN_KNOWN_H +#define EXCHANGE_DATABASE_ENSURE_COIN_KNOWN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @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) + * @param[out] h_age_commitment set to the conflicting age commitment hash on conflict + * @return database transaction status, non-negative on success + */ +enum TALER_EXCHANGEDB_CoinKnownStatus +EXCHANGEDB_ensure_coin_known (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo *coin, + uint64_t *known_coin_id, + struct TALER_DenominationHashP *denom_hash, + struct TALER_AgeCommitmentHashP *h_age_commitment); + +#endif diff --git a/src/include/taler/exchange-database/event_listen.h b/src/include/taler/exchange-database/event_listen.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/event_listen.h + * @brief implementation of the event_listen function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_EVENT_LISTEN_H +#define EXCHANGE_DATABASE_EVENT_LISTEN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Register callback to be invoked on events of type @a es. + * + * @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 + */ +struct GNUNET_DB_EventHandler * +EXCHANGEDB_event_listen (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Relative timeout, + const struct GNUNET_DB_EventHeaderP *es, + GNUNET_DB_EventCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/event_listen_cancel.h b/src/include/taler/exchange-database/event_listen_cancel.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/event_listen_cancel.h + * @brief implementation of the event_listen_cancel function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_EVENT_LISTEN_CANCEL_H +#define EXCHANGE_DATABASE_EVENT_LISTEN_CANCEL_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Stop notifications. + * + * @param cls the plugin's `struct PostgresClosure` + * @param eh handle to unregister. + */ +void +EXCHANGEDB_event_listen_cancel (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_DB_EventHandler *eh); + +#endif diff --git a/src/include/taler/exchange-database/event_notify.h b/src/include/taler/exchange-database/event_notify.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/event_notify.h + * @brief implementation of the event_notify function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_EVENT_NOTIFY_H +#define EXCHANGE_DATABASE_EVENT_NOTIFY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Notify all that listen on @a es of an event. + * + * @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 + */ +void +EXCHANGEDB_event_notify (struct EXCHANGEDB_PostgresContext *ctx, + const struct GNUNET_DB_EventHeaderP *es, + const void *extra, + size_t extra_size); + +#endif diff --git a/src/include/taler/exchange-database/expire_purse.h b/src/include/taler/exchange-database/expire_purse.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/expire_purse.h + * @brief implementation of the expire_purse function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_EXPIRE_PURSE_H +#define EXCHANGE_DATABASE_EXPIRE_PURSE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to clean up one expired purse. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @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). + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_expire_purse (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Absolute start_time, + struct GNUNET_TIME_Absolute end_time); + +#endif diff --git a/src/include/taler/exchange-database/find_aggregation_transient.h b/src/include/taler/exchange-database/find_aggregation_transient.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/find_aggregation_transient.h + * @brief implementation of the find_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_FIND_AGGREGATION_TRANSIENT_H +#define EXCHANGE_DATABASE_FIND_AGGREGATION_TRANSIENT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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[out] payto_uri corresponding payto URI, to be freed by caller + * @param[out] wtid wire transfer identifier of transient aggregation + * @param[out] merchant_pub public key of the merchant + * @param[out] total amount aggregated so far + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_find_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct TALER_FullPayto *payto_uri, + struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_MerchantPublicKeyP *merchant_pub, + struct TALER_Amount *total); + +#endif diff --git a/src/include/taler/exchange-database/gc.h b/src/include/taler/exchange-database/gc.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/gc.h + * @brief implementation of the gc function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GC_H +#define EXCHANGE_DATABASE_GC_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_gc (struct EXCHANGEDB_PostgresContext *ctx); + +#endif diff --git a/src/include/taler/exchange-database/get_coin_denomination.h b/src/include/taler/exchange-database/get_coin_denomination.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_coin_denomination.h + * @brief implementation of the get_coin_denomination function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_COIN_DENOMINATION_H +#define EXCHANGE_DATABASE_GET_COIN_DENOMINATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Retrieve the denomination of a known coin. + * + * @param cls the plugin closure + * @param coin_pub the public key of the coin to search for + * @param[out] known_coin_id set to the ID of the coin in the known_coins table + * @param[out] denom_hash where to store the hash of the coins denomination + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_coin_denomination (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + uint64_t *known_coin_id, + struct TALER_DenominationHashP *denom_hash); + +#endif diff --git a/src/include/taler/exchange-database/get_coin_transactions.h b/src/include/taler/exchange-database/get_coin_transactions.h @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_coin_transactions.h + * @brief implementation of the get_coin_transactions function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_COIN_TRANSACTIONS_H +#define EXCHANGE_DATABASE_GET_COIN_TRANSACTIONS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Compile a list of (historic) transactions performed with the given coin + * (melt, refund, recoup and deposit operations). Should return 0 if the @a + * coin_pub is unknown, otherwise determine @a etag_out and if it is past @a + * etag_in return the history after @a start_off. @a etag_out should be set + * to the last row ID of the given @a coin_pub in the coin history table. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param begin_transaction true to run this in its own transaction(s) + * @param coin_pub coin to investigate + * @param start_off starting offset from which on to return entries + * @param etag_in up to this offset the client already has a response, do not + * return anything unless @a etag_out will be larger + * @param[out] etag_out set to the latest history offset known for this @a coin_pub + * @param[out] balance set to current balance of the coin + * @param[out] h_denom_pub set to denomination public key of the coin + * @param[out] tlp set to list of transactions, set to NULL if coin has no + * transaction history past @a start_off or if @a etag_in is equal + * to the value written to @a etag_out. + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_coin_transactions (struct EXCHANGEDB_PostgresContext *ctx, + bool begin_transaction, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + uint64_t start_off, + uint64_t etag_in, + uint64_t *etag_out, + struct TALER_Amount *balance, + struct TALER_DenominationHashP *h_denom_pub, + struct TALER_EXCHANGEDB_TransactionList **tlp); + + +#endif diff --git a/src/include/taler/exchange-database/get_denomination_by_serial.h b/src/include/taler/exchange-database/get_denomination_by_serial.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_denomination_by_serial.h + * @brief implementation of the get_denomination_by_serial function for Postgres + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_GET_DENOMINATION_BY_SERIAL_H +#define EXCHANGE_DATABASE_GET_DENOMINATION_BY_SERIAL_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Fetch information about a denomination for a given serial. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param denom_serial row in the denomination table + * @param[out] issue set to issue information with value, fees and other info about the coin + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_denomination_by_serial (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t denom_serial, + struct TALER_EXCHANGEDB_DenominationKeyInformation *issue); + +#endif diff --git a/src/include/taler/exchange-database/get_denomination_info.h b/src/include/taler/exchange-database/get_denomination_info.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022,2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_denomination_info.h + * @brief implementation of the get_denomination_info function for Postgres + * @author Christian Grothoff + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_GET_DENOMINATION_INFO_H +#define EXCHANGE_DATABASE_GET_DENOMINATION_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Fetch information about a denomination key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param denom_pub_hash hash of the public key used for signing coins of this denomination + * @param[out] denom_serial row in the denomination table, might be NULL + * @param[out] issue set to issue information with value, fees and other info about the coin + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_denomination_info (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + uint64_t *denom_serial, + struct TALER_EXCHANGEDB_DenominationKeyInformation *issue); + +#endif diff --git a/src/include/taler/exchange-database/get_denomination_revocation.h b/src/include/taler/exchange-database/get_denomination_revocation.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_denomination_revocation.h + * @brief implementation of the get_denomination_revocation function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_DENOMINATION_REVOCATION_H +#define EXCHANGE_DATABASE_GET_DENOMINATION_REVOCATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @param[out] rowid row where the information is stored + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_denomination_revocation (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + struct TALER_MasterSignatureP *master_sig, + uint64_t *rowid); + +#endif diff --git a/src/include/taler/exchange-database/get_drain_profit.h b/src/include/taler/exchange-database/get_drain_profit.h @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_drain_profit.h + * @brief implementation of the get_drain_profit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_DRAIN_PROFIT_H +#define EXCHANGE_DATABASE_GET_DRAIN_PROFIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to get information about a profit drain event. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param wtid wire transfer ID to look up drain event for + * @param[out] serial set to serial ID of the entry + * @param[out] account_section set to account to drain + * @param[out] payto_uri set to account to wire funds to + * @param[out] request_timestamp set to time of the signature + * @param[out] amount set to amount to wire + * @param[out] master_sig set to signature affirming the operation + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_drain_profit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_WireTransferIdentifierRawP *wtid, + uint64_t *serial, + char **account_section, + struct TALER_FullPayto *payto_uri, + struct GNUNET_TIME_Timestamp *request_timestamp, + struct TALER_Amount *amount, + struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/get_expired_reserves.h b/src/include/taler/exchange-database/get_expired_reserves.h @@ -0,0 +1,73 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_expired_reserves.h + * @brief implementation of the get_expired_reserves function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_EXPIRED_RESERVES_H +#define EXCHANGE_DATABASE_GET_EXPIRED_RESERVES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about expired reserves. + * + * @param cls closure + * @param reserve_pub public key of the reserve + * @param left amount left in the reserve + * @param account_details information about the reserve's bank account, in payto://-format + * @param expiration_date when did the reserve expire + * @param close_request_row row that caused the reserve + * to be closed, 0 if it expired without request + * @return #GNUNET_OK on success, + * #GNUNET_NO to retry + * #GNUNET_SYSERR on hard failures (exit) + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_ReserveExpiredCallback)( + void *cls, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *left, + const struct TALER_FullPayto account_details, + struct GNUNET_TIME_Timestamp expiration_date, + uint64_t close_request_row); + +/** + * Obtain information about expired reserves and their + * remaining balances. + * + * @param cls closure of the plugin + * @param now timestamp based on which we decide expiration + * @param rec function to call on expired reserves + * @param rec_cls closure for @a rec + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_expired_reserves (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp now, + TALER_EXCHANGEDB_ReserveExpiredCallback rec, + void *rec_cls); + +#endif diff --git a/src/include/taler/exchange-database/get_extension_manifest.h b/src/include/taler/exchange-database/get_extension_manifest.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_extension_manifest.h + * @brief implementation of the get_extension_manifest function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_EXTENSION_MANIFEST_H +#define EXCHANGE_DATABASE_GET_EXTENSION_MANIFEST_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to get the manifest of an extension + * (age-restriction, policy_extension_...) + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param extension_name the name of the extension + * @param[out] manifest JSON object of the manifest as string + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_extension_manifest (struct EXCHANGEDB_PostgresContext *ctx, + const char *extension_name, + char **manifest); + +#endif diff --git a/src/include/taler/exchange-database/get_global_fee.h b/src/include/taler/exchange-database/get_global_fee.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_global_fee.h + * @brief implementation of the get_global_fee function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_GLOBAL_FEE_H +#define EXCHANGE_DATABASE_GET_GLOBAL_FEE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_global_fee (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp date, + struct GNUNET_TIME_Timestamp *start_date, + struct GNUNET_TIME_Timestamp *end_date, + struct TALER_GlobalFeeSet *fees, + struct GNUNET_TIME_Relative *purse_timeout, + struct GNUNET_TIME_Relative *history_expiration, + uint32_t *purse_account_limit, + struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/get_global_fees.h b/src/include/taler/exchange-database/get_global_fees.h @@ -0,0 +1,70 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_global_fees.h + * @brief implementation of the get_global_fees function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_GLOBAL_FEES_H +#define EXCHANGE_DATABASE_GET_GLOBAL_FEES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Provide information about global fees. + * + * @param cls closure + * @param fees the global fees we charge + * @param purse_timeout when do purses time out + * @param history_expiration how long are account histories preserved + * @param purse_account_limit how many purses are free per account + * @param start_date from when are these fees valid (start date) + * @param end_date until when are these fees valid (end date, exclusive) + * @param master_sig master key signature affirming that this is the correct + * fee (of purpose #TALER_SIGNATURE_MASTER_GLOBAL_FEES) + */ +typedef void +(*TALER_EXCHANGEDB_GlobalFeeCallback)( + void *cls, + const struct TALER_GlobalFeeSet *fees, + struct GNUNET_TIME_Relative purse_timeout, + struct GNUNET_TIME_Relative history_expiration, + uint32_t purse_account_limit, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + const struct TALER_MasterSignatureP *master_sig); + +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_global_fees (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_GlobalFeeCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/get_known_coin.h b/src/include/taler/exchange-database/get_known_coin.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_known_coin.h + * @brief implementation of the get_known_coin function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_KNOWN_COIN_H +#define EXCHANGE_DATABASE_GET_KNOWN_COIN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_known_coin (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct TALER_CoinPublicInfo *coin_info); + +#endif diff --git a/src/include/taler/exchange-database/get_kyc_rules.h b/src/include/taler/exchange-database/get_kyc_rules.h @@ -0,0 +1,75 @@ +/* + This file is part of TALER + Copyright (C) 2022-2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_kyc_rules.h + * @brief implementation of the get_kyc_rules function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_KYC_RULES_H +#define EXCHANGE_DATABASE_GET_KYC_RULES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Return KYC rules that apply to the given account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_payto account identifier + * @param merchant_pub merchant public key used by the client, or NULL + * if not available; if multiple @a reserve_pub values could be returned, + * we should use this one + * @param[out] no_account_pub set to true if no @a account_pub is available + * @param[out] account_pub set to account public key the rules + * apply to (because this key was used in KYC auth) + * @param[out] no_reserve_pub set to true if no @a reserve_pub is available + * @param[out] reserve_pub set to last incoming reserve public key + * of a wire transfer to the exchange from the given @a h_payto + * apply to (because this key was used in KYC auth) + * @param[out] jrules set to the active KYC rules for the + * given account, set to NULL if no custom rules are active + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_kyc_rules (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, + bool *no_account_pub, + union TALER_AccountPublicKeyP *account_pub, + bool *no_reserve_pub, + struct TALER_ReservePublicKeyP *reserve_pub, + json_t **jrules); + + +/** + * Return only the KYC rules that apply to the given account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_payto account identifier + * @param[out] jrules set to the active KYC rules for the + * given account, set to NULL if no custom rules are active + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_kyc_rules2 (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + json_t **jrules); + +#endif diff --git a/src/include/taler/exchange-database/get_old_coin_by_h_blind.h b/src/include/taler/exchange-database/get_old_coin_by_h_blind.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_old_coin_by_h_blind.h + * @brief implementation of the get_old_coin_by_h_blind function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_OLD_COIN_BY_H_BLIND_H +#define EXCHANGE_DATABASE_GET_OLD_COIN_BY_H_BLIND_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @param[out] old_coin_pub set to information about the old coin (on success only) + * @param[out] rrc_serial set to serial number of the entry in the database + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_old_coin_by_h_blind (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_BlindedCoinHashP *h_blind_ev, + struct TALER_CoinSpendPublicKeyP *old_coin_pub, + uint64_t *rrc_serial); + +#endif diff --git a/src/include/taler/exchange-database/get_pending_kyc_requirement_process.h b/src/include/taler/exchange-database/get_pending_kyc_requirement_process.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_pending_kyc_requirement_process.h + * @brief implementation of the get_pending_kyc_requirement_process function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_PENDING_KYC_REQUIREMENT_PROCESS_H +#define EXCHANGE_DATABASE_GET_PENDING_KYC_REQUIREMENT_PROCESS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Fetch information about pending KYC requirement process. + * + * @param cls closure + * @param h_payto account that must be KYC'ed + * @param provider_name provider that must be checked + * @param[out] redirect_url set to redirect URL for the process + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_pending_kyc_requirement_process (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_name, + char **redirect_url); + +#endif diff --git a/src/include/taler/exchange-database/get_policy_details.h b/src/include/taler/exchange-database/get_policy_details.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_policy_details.h + * @brief implementation of the get_policy_details function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_POLICY_DETAILS_H +#define EXCHANGE_DATABASE_GET_POLICY_DETAILS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/* 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 + * */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_policy_details (struct EXCHANGEDB_PostgresContext *ctx, + const struct GNUNET_HashCode *hc, + struct TALER_PolicyDetails *details); + +#endif diff --git a/src/include/taler/exchange-database/get_purse_deposit.h b/src/include/taler/exchange-database/get_purse_deposit.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_purse_deposit.h + * @brief implementation of the get_purse_deposit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_PURSE_DEPOSIT_H +#define EXCHANGE_DATABASE_GET_PURSE_DEPOSIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to obtain a coin deposit data from + * depositing the coin into a purse. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub purse to credit + * @param coin_pub coin to deposit (debit) + * @param[out] amount set fraction of the coin's value that was deposited (with fee) + * @param[out] h_denom_pub set to hash of denomination of the coin + * @param[out] phac set to hash of age restriction on the coin + * @param[out] coin_sig set to signature affirming the operation + * @param[out] partner_url set to the URL of the partner exchange, or NULL for ourselves, must be freed by caller + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_purse_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct TALER_Amount *amount, + struct TALER_DenominationHashP *h_denom_pub, + struct TALER_AgeCommitmentHashP *phac, + struct TALER_CoinSpendSignatureP *coin_sig, + char **partner_url); + +#endif diff --git a/src/include/taler/exchange-database/get_purse_request.h b/src/include/taler/exchange-database/get_purse_request.h @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + + +/** + * @file src/include/taler/exchange-database/get_purse_request.h + * @brief implementation of the get_purse_request function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_PURSE_REQUEST_H +#define EXCHANGE_DATABASE_GET_PURSE_REQUEST_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to return meta data about a purse by the + * purse public key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @param[out] merge_pub public key representing the merge capability + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_purse_request (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseMergePublicKeyP *merge_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); + +#endif diff --git a/src/include/taler/exchange-database/get_ready_deposit.h b/src/include/taler/exchange-database/get_ready_deposit.h @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_ready_deposit.h + * @brief implementation of the get_ready_deposit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_READY_DEPOSIT_H +#define EXCHANGE_DATABASE_GET_READY_DEPOSIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Obtain information about deposits that are ready to be executed. Such + * deposits must not be marked as "done", the execution time must be + * in the past, and the KYC status must be 'ok'. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param start_shard_row minimum shard row to select + * @param end_shard_row maximum shard row to select (inclusive) + * @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 + * @param[out] extra_wire_subject_metadata set to additional metadata to include in the wire subject, or NULL for none + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_ready_deposit (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t start_shard_row, + uint64_t end_shard_row, + struct TALER_MerchantPublicKeyP *merchant_pub, + struct TALER_FullPayto *payto_uri, + char **extra_wire_subject_metadata); + +#endif diff --git a/src/include/taler/exchange-database/get_refresh.h b/src/include/taler/exchange-database/get_refresh.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_refresh.h + * @brief implementation of the get_refresh function for Postgres + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_GET_REFRESH_H +#define EXCHANGE_DATABASE_GET_REFRESH_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup refresh refresh commitment data under the given @a rc. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param rc commitment hash to use to locate the operation + * @param[out] refresh where to store the result; note that + * refresh->session.coin.denom_sig will be set to NULL + * and is not fetched by this routine (as it is not needed by the client) + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_refresh (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_RefreshCommitmentP *rc, + struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh); + +#endif diff --git a/src/include/taler/exchange-database/get_reserve_balance.h b/src/include/taler/exchange-database/get_reserve_balance.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_reserve_balance.h + * @brief implementation of the get_reserve_balance function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_RESERVE_BALANCE_H +#define EXCHANGE_DATABASE_GET_RESERVE_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @param[out] origin_account set to URI of the origin account, NULL + * if we have no origin account (reserve created by P2P merge) +* @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_reserve_balance (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_Amount *balance, + struct TALER_FullPayto *origin_account); + +#endif diff --git a/src/include/taler/exchange-database/get_reserve_by_h_planchets.h b/src/include/taler/exchange-database/get_reserve_by_h_planchets.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_reserve_by_h_planchets.h + * @brief implementation of the get_reserve_by_h_planchets function for Postgres + * @author Christian Grothoff + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_GET_RESERVE_BY_H_PLANCHETS_H +#define EXCHANGE_DATABASE_GET_RESERVE_BY_H_PLANCHETS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Obtain information about which reserve a coin was generated + * from given the hash of the blinded coin. + * + * @param cls closure + * @param h_planchets hash that uniquely identifies the withdraw request + * @param[out] reserve_pub set to information about the reserve (on success only) + * @param[out] withdraw_serial_id set to row of the @a h_commitment in withdraw + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_reserve_by_h_planchets (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_HashBlindedPlanchetsP *h_planchets, + struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t *withdraw_serial_id); + +#endif diff --git a/src/include/taler/exchange-database/get_reserve_history.h b/src/include/taler/exchange-database/get_reserve_history.h @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_reserve_history.h + * @brief implementation of the get_reserve_history function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_RESERVE_HISTORY_H +#define EXCHANGE_DATABASE_GET_RESERVE_HISTORY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Compile a list of (historic) transactions performed with the given reserve + * (withdraw, incoming wire, open, close operations). Should return 0 if the @a + * reserve_pub is unknown, otherwise determine @a etag_out and if it is past @a + * etag_in return the history after @a start_off. @a etag_out should be set + * to the last row ID of the given @a reserve_pub in the reserve history table. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param reserve_pub public key of the reserve + * @param start_off maximum starting offset in history to exclude from returning + * @param etag_in up to this offset the client already has a response, do not + * return anything unless @a etag_out will be larger + * @param[out] etag_out set to the latest history offset known for this @a coin_pub + * @param[out] balance set to the reserve balance + * @param[out] rhp set to known transaction history (NULL if reserve is unknown) + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_reserve_history (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t start_off, + uint64_t etag_in, + uint64_t *etag_out, + struct TALER_Amount *balance, + struct TALER_EXCHANGEDB_ReserveHistory **rhp); + + +#endif diff --git a/src/include/taler/exchange-database/get_signature_for_known_coin.h b/src/include/taler/exchange-database/get_signature_for_known_coin.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_signature_for_known_coin.h + * @brief implementation of the get_signature_for_known_coin function for Postgres + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_GET_SIGNATURE_FOR_KNOWN_COIN_H +#define EXCHANGE_DATABASE_GET_SIGNATURE_FOR_KNOWN_COIN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Retrieve the denomination and the corresponding signature for a known coin. + * + * @param cls the plugin closure + * @param coin_pub the public key of the coin to search for + * @param[out] denom_pub the denomination of the public key, if coin was present + * @param[out] denom_sig the signature with the denomination key of the coin, if coin was present + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_signature_for_known_coin (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct TALER_DenominationPublicKey *denom_pub, + struct TALER_DenominationSignature *denom_sig); + +#endif diff --git a/src/include/taler/exchange-database/get_unfinished_close_requests.h b/src/include/taler/exchange-database/get_unfinished_close_requests.h @@ -0,0 +1,73 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_get_unfinished_close_requests.h + * @brief implementation of the get_unfinished_close_requests function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_UNFINISHED_CLOSE_REQUESTS_H +#define EXCHANGE_DATABASE_GET_UNFINISHED_CLOSE_REQUESTS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about expired reserves. + * + * @param cls closure + * @param reserve_pub public key of the reserve + * @param left amount left in the reserve + * @param account_details information about the reserve's bank account, in payto://-format + * @param expiration_date when did the reserve expire + * @param close_request_row row that caused the reserve + * to be closed, 0 if it expired without request + * @return #GNUNET_OK on success, + * #GNUNET_NO to retry + * #GNUNET_SYSERR on hard failures (exit) + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_ReserveExpiredCallback)( + void *cls, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *left, + const struct TALER_FullPayto account_details, + struct GNUNET_TIME_Timestamp expiration_date, + uint64_t close_request_row); + +/** + * Obtain information about force-closed reserves + * where the close was not yet done (and their remaining + * balances). Updates the returned reserve's close + * status to "done". + * + * @param cls closure of the plugin + * @param rec function to call on expired reserves + * @param rec_cls closure for @a rec + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_unfinished_close_requests (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_ReserveExpiredCallback rec, + void *rec_cls); + +#endif diff --git a/src/include/taler/exchange-database/get_wire_accounts.h b/src/include/taler/exchange-database/get_wire_accounts.h @@ -0,0 +1,75 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_wire_accounts.h + * @brief implementation of the get_wire_accounts function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_WIRE_ACCOUNTS_H +#define EXCHANGE_DATABASE_GET_WIRE_ACCOUNTS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Provide information about a wire account. + * + * @param cls closure + * @param payto_uri the exchange bank account URI + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param open_banking_gateway open banking gateway service, NULL if unavailable + * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable + * @param debit_restrictions JSON array with debit restrictions on the account + * @param credit_restrictions JSON array with credit restrictions on the account + * @param master_sig master key signature affirming that this is a bank + * account of the exchange (of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS) + * @param bank_label label the wallet should use to display the account, can be NULL + * @param priority priority for ordering bank account labels + */ +typedef void +(*TALER_EXCHANGEDB_WireAccountCallback)( + void *cls, + const struct TALER_FullPayto payto_uri, + const char *conversion_url, + const char *open_banking_gateway, + const char *wire_transfer_gateway, + const json_t *debit_restrictions, + const json_t *credit_restrictions, + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority); + +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_wire_accounts (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_WireAccountCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/get_wire_fee.h b/src/include/taler/exchange-database/get_wire_fee.h @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_wire_fee.h + * @brief implementation of the get_wire_fee function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_WIRE_FEE_H +#define EXCHANGE_DATABASE_GET_WIRE_FEE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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] rowid set to row in the database with the wire 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] master_sig signature over the above by the exchange master key + * @return status of the transaction + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_wire_fee (struct EXCHANGEDB_PostgresContext *ctx, + const char *type, + struct GNUNET_TIME_Timestamp date, + uint64_t *rowid, + struct GNUNET_TIME_Timestamp *start_date, + struct GNUNET_TIME_Timestamp *end_date, + struct TALER_WireFeeSet *fees, + struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/get_wire_fees.h b/src/include/taler/exchange-database/get_wire_fees.h @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_wire_fees.h + * @brief implementation of the get_wire_fees function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_GET_WIRE_FEES_H +#define EXCHANGE_DATABASE_GET_WIRE_FEES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Provide information about wire fees. + * + * @param cls closure + * @param fees the wire fees we charge + * @param start_date from when are these fees valid (start date) + * @param end_date until when are these fees valid (end date, exclusive) + * @param master_sig master key signature affirming that this is the correct + * fee (of purpose #TALER_SIGNATURE_MASTER_WIRE_FEES) + */ +typedef void +(*TALER_EXCHANGEDB_WireFeeCallback)( + void *cls, + const struct TALER_WireFeeSet *fees, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + const struct TALER_MasterSignatureP *master_sig); + +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_wire_fees (struct EXCHANGEDB_PostgresContext *ctx, + const char *wire_method, + TALER_EXCHANGEDB_WireFeeCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/get_wire_hash_for_contract.h b/src/include/taler/exchange-database/get_wire_hash_for_contract.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_wire_hash_for_contract.h + * @brief implementation of the get_wire_hash_for_contract function for Postgres + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_GET_WIRE_HASH_FOR_CONTRACT_H +#define EXCHANGE_DATABASE_GET_WIRE_HASH_FOR_CONTRACT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Try to get the salted hash of a merchant's bank account to a deposit + * contract. This is necessary in the event of a conflict with a given + * (merchant_pub, h_contract_terms) during deposit. + * + * @param cls closure + * @param merchant_pub merchant public key + * @param h_contract_terms hash of the proposal data + * @param[out] h_wire salted hash of a merchant's bank account + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_wire_hash_for_contract (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_PrivateContractHashP *h_contract_terms, + struct TALER_MerchantWireHashP *h_wire); + +#endif diff --git a/src/include/taler/exchange-database/get_withdraw.h b/src/include/taler/exchange-database/get_withdraw.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/get_withdraw.h + * @brief implementation of the get_withdraw function for Postgres + * @author Özgür KESIM + */ +#ifndef EXCHANGE_DATABASE_GET_WITHDRAW_H +#define EXCHANGE_DATABASE_GET_WITHDRAW_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Locate the response for a withdraw request under a hash that uniquely + * identifies the withdraw operation. Used to ensure idempotency of the + * request. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param wch hash over all hashes of blinded planchets that uniquely identifies the withdraw operation + * @param[out] wd corresponding details of the previous withdraw request if an entry was found + * @return statement execution status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_get_withdraw (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_HashBlindedPlanchetsP *wch, + struct TALER_EXCHANGEDB_Withdraw *wd); + +#endif diff --git a/src/include/taler/exchange-database/have_deposit2.h b/src/include/taler/exchange-database/have_deposit2.h @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/have_deposit2.h + * @brief implementation of the have_deposit2 function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_HAVE_DEPOSIT2_H +#define EXCHANGE_DATABASE_HAVE_DEPOSIT2_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_have_deposit2 (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant, + struct GNUNET_TIME_Timestamp refund_deadline, + struct TALER_Amount *deposit_fee, + struct GNUNET_TIME_Timestamp *exchange_timestamp); + +#endif diff --git a/src/include/taler/exchange-database/inject_auditor_triggers.h b/src/include/taler/exchange-database/inject_auditor_triggers.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/inject_auditor_triggers.h + * @brief implementation of the inject_auditor_triggers function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INJECT_AUDITOR_TRIGGERS_H +#define EXCHANGE_DATABASE_INJECT_AUDITOR_TRIGGERS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to inject auditor triggers into the + * database, triggering the real-time auditor upon + * relevant INSERTs. + * + * @param cls closure + * @return #GNUNET_OK on success, + * #GNUNET_SYSERR on DB errors + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_inject_auditor_triggers (struct EXCHANGEDB_PostgresContext *ctx); + + +#endif diff --git a/src/include/taler/exchange-database/insert_active_legitimization_measure.h b/src/include/taler/exchange-database/insert_active_legitimization_measure.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_active_legitimization_measure.h + * @brief implementation of the insert_active_legitimization_measure function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_ACTIVE_LEGITIMIZATION_MEASURE_H +#define EXCHANGE_DATABASE_INSERT_ACTIVE_LEGITIMIZATION_MEASURE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Create new active legitimization measure. + * + * + * @param cls closure + * @param access_token access token that identifies the + * account the legitimization measures apply to + * @param jmeasures new legitimization measures + * @param[out] legitimization_measure_serial_id + * set to new row in legitimization_measures table + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_active_legitimization_measure (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AccountAccessTokenP *access_token, + const json_t *jmeasures, + uint64_t *legitimization_measure_serial_id); + + +#endif diff --git a/src/include/taler/exchange-database/insert_aml_decision.h b/src/include/taler/exchange-database/insert_aml_decision.h @@ -0,0 +1,94 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_aml_decision.h + * @brief implementation of the insert_aml_decision function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_AML_DECISION_H +#define EXCHANGE_DATABASE_INSERT_AML_DECISION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert an AML decision. Inserts into AML history and insert or updates AML + * status. + * + * @param cls closure + * @param payto_uri full URI of the account, optional, + * can be NULL if the backend already knows the account + * @param h_payto account for which the attribute data is stored + * @param decision_time when was the decision made + * @param expiration_time when does the decision expire + * @param properties JSON object with properties to set for the account + * @param new_rules JSON array with new AML/KYC rules + * @param to_investigate true if AML staff should look more into this account + * @param new_measure_name name of the @a jmeasures measure that was triggered, or NULL for none + * @param jmeasures a JSON with LegitimizationMeasures to apply to the + * account, or NULL to not apply any measure right now + * @param justification human-readable text justifying the decision + * @param decider_pub public key of the staff member + * @param decider_sig signature of the staff member + * @param num_events length of the @a events array + * @param events array of events to trigger + * @param enc_attributes_size number of bytes in @a enc_attributes + * @param enc_attributes encrypted attribute data + * @param form_name name of the form from which @a enc_attributes originate, can be NULL + * @param attributes_hash hash of the unencrypted attribute data + * @param attributes_expiration_time when does the attribute data expire + * @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now + * @param[out] unknown_account set to TRUE if @a h_payto does not refer to a known account and @a jmeasures was given + * @param[out] last_date set to the previous decision time; + * the INSERT is not performed if @a last_date is not before @a decision_time + * @param[out] legitimization_measure_serial_id serial ID of the legitimization measures + * of the decision + * @param[out] is_wallet set to true if @a h_payto is for a wallet + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_aml_decision (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp decision_time, + struct GNUNET_TIME_Timestamp expiration_time, + const json_t *properties, + const json_t *new_rules, + bool to_investigate, + const char *new_measure_name, + const json_t *jmeasures, + const char *justification, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + const struct TALER_AmlOfficerSignatureP *decider_sig, + size_t num_events, + const char *events[static num_events], + const char *form_name, + size_t enc_attributes_size, + const void *enc_attributes, + struct GNUNET_HashCode *attributes_hash, + struct GNUNET_TIME_Timestamp attributes_expiration_time, + bool *invalid_officer, + bool *unknown_account, + struct GNUNET_TIME_Timestamp *last_date, + uint64_t *legitimization_measure_serial_id, + bool *is_wallet); + + +#endif diff --git a/src/include/taler/exchange-database/insert_aml_officer.h b/src/include/taler/exchange-database/insert_aml_officer.h @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_aml_officer.h + * @brief implementation of the insert_aml_officer function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_AML_OFFICER_H +#define EXCHANGE_DATABASE_INSERT_AML_OFFICER_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert AML staff record. If the time given in + * @a last_change is before the previous change in the + * database, only @e previous_change is returned and + * no actual change is committed to the database. + * + * @param cls closure + * @param decider_pub public key of the staff member + * @param master_sig offline signature affirming the AML officer + * @param decider_name full name of the staff member + * @param is_active true to enable, false to set as inactive + * @param read_only true to set read-only access + * @param last_change when was the change made effective + * @param[out] previous_change set to the time of the previous change + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_aml_officer (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + const struct TALER_MasterSignatureP *master_sig, + const char *decider_name, + bool is_active, + bool read_only, + struct GNUNET_TIME_Timestamp last_change, + struct GNUNET_TIME_Timestamp *previous_change); + +#endif diff --git a/src/include/taler/exchange-database/insert_aml_program_failure.h b/src/include/taler/exchange-database/insert_aml_program_failure.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_aml_program_failure.h + * @brief implementation of the insert_aml_program_failure function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_AML_PROGRAM_FAILURE_H +#define EXCHANGE_DATABASE_INSERT_AML_PROGRAM_FAILURE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Update AML program status to finished (and failed). + * + * @param cls closure + * @param process_row KYC process row to update + * @param h_payto account for which the attribute data is stored + * @param error_message details about what went wrong + * @param ec error code about the failure + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_aml_program_failure (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t process_row, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *error_message, + enum TALER_ErrorCode ec); + + +#endif diff --git a/src/include/taler/exchange-database/insert_auditor.h b/src/include/taler/exchange-database/insert_auditor.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_auditor.h + * @brief implementation of the insert_auditor function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_AUDITOR_H +#define EXCHANGE_DATABASE_INSERT_AUDITOR_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_auditor (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const char *auditor_url, + const char *auditor_name, + struct GNUNET_TIME_Timestamp start_date); + +#endif diff --git a/src/include/taler/exchange-database/insert_auditor_denom_sig.h b/src/include/taler/exchange-database/insert_auditor_denom_sig.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_auditor_denom_sig.h + * @brief implementation of the insert_auditor_denom_sig function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_AUDITOR_DENOM_SIG_H +#define EXCHANGE_DATABASE_INSERT_AUDITOR_DENOM_SIG_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_auditor_denom_sig (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const struct TALER_AuditorSignatureP *auditor_sig); + +#endif diff --git a/src/include/taler/exchange-database/insert_close_request.h b/src/include/taler/exchange-database/insert_close_request.h @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_close_request.h + * @brief implementation of the insert_close_request function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_CLOSE_REQUEST_H +#define EXCHANGE_DATABASE_INSERT_CLOSE_REQUEST_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to initiate closure of an account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param reserve_pub public key of the account to close + * @param payto_uri where to wire the funds + * @param reserve_sig signature affiming that the account is to be closed + * @param request_timestamp time of the close request (client-side?) + * @param balance final balance in the reserve + * @param closing_fee closing fee to charge + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_close_request (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_FullPayto payto_uri, + const struct TALER_ReserveSignatureP *reserve_sig, + struct GNUNET_TIME_Timestamp request_timestamp, + const struct TALER_Amount *balance, + const struct TALER_Amount *closing_fee); + + +#endif diff --git a/src/include/taler/exchange-database/insert_contract.h b/src/include/taler/exchange-database/insert_contract.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_contract.h + * @brief implementation of the insert_contract function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_CONTRACT_H +#define EXCHANGE_DATABASE_INSERT_CONTRACT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to persist an encrypted contract associated with a reserve. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub the purse the contract is associated with (must exist) + * @param econtract the encrypted contract + * @param[out] in_conflict set to true if @a econtract + * conflicts with an existing contract; + * in this case, the return value will be + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_contract (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_EncryptedContract *econtract, + bool *in_conflict); + +#endif diff --git a/src/include/taler/exchange-database/insert_denomination_info.h b/src/include/taler/exchange-database/insert_denomination_info.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_denomination_info.h + * @brief implementation of the insert_denomination_info function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_DENOMINATION_INFO_H +#define EXCHANGE_DATABASE_INSERT_DENOMINATION_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Insert a denomination key's public information into the database for + * reference by auditors and other consistency checks. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param denom_pub the public key used for signing coins of this denomination + * @param issue issuing information with value, fees and other info about the coin + * @return status of the query + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_denomination_info (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue); + +#endif diff --git a/src/include/taler/exchange-database/insert_denomination_revocation.h b/src/include/taler/exchange-database/insert_denomination_revocation.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_denomination_revocation.h + * @brief implementation of the insert_denomination_revocation function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_DENOMINATION_REVOCATION_H +#define EXCHANGE_DATABASE_INSERT_DENOMINATION_REVOCATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_denomination_revocation (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *denom_pub_hash, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/insert_drain_profit.h b/src/include/taler/exchange-database/insert_drain_profit.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_drain_profit.h + * @brief implementation of the insert_drain_profit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_DRAIN_PROFIT_H +#define EXCHANGE_DATABASE_INSERT_DRAIN_PROFIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to persist a request to drain profits. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param wtid wire transfer ID to use + * @param account_section account to drain + * @param payto_uri account to wire funds to + * @param request_timestamp when was the request made + * @param amount amount to wire + * @param master_sig signature affirming the operation + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_drain_profit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_WireTransferIdentifierRawP *wtid, + const char *account_section, + const struct TALER_FullPayto payto_uri, + struct GNUNET_TIME_Timestamp request_timestamp, + const struct TALER_Amount *amount, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/insert_global_fee.h b/src/include/taler/exchange-database/insert_global_fee.h @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_global_fee.h + * @brief implementation of the insert_global_fee function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_GLOBAL_FEE_H +#define EXCHANGE_DATABASE_INSERT_GLOBAL_FEE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert global fee data into database. + * + * @param cls closure + * @param start_date when does the fees go into effect + * @param end_date when does the fees end being valid + * @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 + * @param purse_account_limit how many purses are free per account + * @param master_sig signature over the above by the exchange master key + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_global_fee (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + const struct TALER_GlobalFeeSet *fees, + struct GNUNET_TIME_Relative purse_timeout, + struct GNUNET_TIME_Relative history_expiration, + uint32_t purse_account_limit, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/insert_kyc_failure.h b/src/include/taler/exchange-database/insert_kyc_failure.h @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_kyc_failure.h + * @brief implementation of the insert_kyc_failure function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_KYC_FAILURE_H +#define EXCHANGE_DATABASE_INSERT_KYC_FAILURE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Update KYC process status to finished (and failed). + * + * @param cls closure + * @param process_row KYC process row to update + * @param h_payto account for which the attribute data is stored + * @param provider_name provider that must be checked + * @param provider_account_id provider account ID + * @param provider_legitimization_id provider legitimization ID + * @param error_message details about what went wrong + * @param ec error code about the failure + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_kyc_failure (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t process_row, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_name, + const char *provider_account_id, + const char *provider_legitimization_id, + const char *error_message, + enum TALER_ErrorCode ec); + + +#endif diff --git a/src/include/taler/exchange-database/insert_kyc_requirement_process.h b/src/include/taler/exchange-database/insert_kyc_requirement_process.h @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_kyc_requirement_process.h + * @brief implementation of the insert_kyc_requirement_process function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_KYC_REQUIREMENT_PROCESS_H +#define EXCHANGE_DATABASE_INSERT_KYC_REQUIREMENT_PROCESS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Begin KYC requirement process. + * + * @param cls closure + * @param h_payto account that must be KYC'ed + * @param measure_index which of the measures in + * jmeasures does this KYC process relate to + * @param legitimization_measure_serial_id which + * legitimization measure set does this KYC process + * relate to (uniquely identifies jmeasures) + * @param provider_name provider that must be checked + * @param provider_account_id provider account ID + * @param provider_legitimization_id provider legitimization ID + * @param[out] process_row row the process is stored under + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_kyc_requirement_process (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint32_t measure_index, + uint64_t legitimization_measure_serial_id, + const char *provider_name, + const char *provider_account_id, + const char *provider_legitimization_id, + uint64_t *process_row); + +#endif diff --git a/src/include/taler/exchange-database/insert_partner.h b/src/include/taler/exchange-database/insert_partner.h @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_partner.h + * @brief implementation of the insert_partner function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_PARTNER_H +#define EXCHANGE_DATABASE_INSERT_PARTNER_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_partner (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_MasterPublicKeyP *master_pub, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + struct GNUNET_TIME_Relative wad_frequency, + const struct TALER_Amount *wad_fee, + const char *partner_base_url, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/insert_purse_request.h b/src/include/taler/exchange-database/insert_purse_request.h @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_purse_request.h + * @brief implementation of the insert_purse_request function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_PURSE_REQUEST_H +#define EXCHANGE_DATABASE_INSERT_PURSE_REQUEST_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to create a new purse with certain meta data. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the new purse + * @param merge_pub public key providing the merge capability + * @param purse_expiration time when the purse will expire + * @param h_contract_terms hash of the contract for the purse + * @param age_limit age limit to enforce for payments into the purse + * @param flags flags for the operation + * @param purse_fee fee we are allowed to charge to the reserve (depending on @a flags) + * @param amount target amount (with fees) to be put into the purse + * @param purse_sig signature with @a purse_pub's private key affirming the above + * @param[out] in_conflict set to true if the meta data + * conflicts with an existing purse; + * in this case, the return value will be + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_purse_request (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePublicKeyP *merge_pub, + struct GNUNET_TIME_Timestamp purse_expiration, + const struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t age_limit, + enum TALER_WalletAccountMergeFlags flags, + const struct TALER_Amount *purse_fee, + const struct TALER_Amount *amount, + const struct TALER_PurseContractSignatureP *purse_sig, + bool *in_conflict); + +#endif diff --git a/src/include/taler/exchange-database/insert_records_by_table.h b/src/include/taler/exchange-database/insert_records_by_table.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_records_by_table.h + * @brief implementation of the insert_records_by_table function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_RECORDS_BY_TABLE_H +#define EXCHANGE_DATABASE_INSERT_RECORDS_BY_TABLE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert record set into @a table. Used in exchange-auditor database + * replication. + * + * @param cls closure + * @param td table data to insert + * @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if + * @e table in @a tr is not supported + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_records_by_table (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_TableData *td); + + +#endif diff --git a/src/include/taler/exchange-database/insert_refund.h b/src/include/taler/exchange-database/insert_refund.h @@ -0,0 +1,40 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_refund.h + * @brief implementation of the insert_refund function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_REFUND_H +#define EXCHANGE_DATABASE_INSERT_REFUND_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @return query result status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_refund (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_Refund *refund); + +#endif diff --git a/src/include/taler/exchange-database/insert_reserve_closed.h b/src/include/taler/exchange-database/insert_reserve_closed.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_reserve_closed.h + * @brief implementation of the insert_reserve_closed function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_RESERVE_CLOSED_H +#define EXCHANGE_DATABASE_INSERT_RESERVE_CLOSED_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * 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? + * @param wtid wire transfer details + * @param amount_with_fee amount we charged to the reserve + * @param closing_fee how high is the closing fee + * @param close_request_row identifies explicit close request, 0 for none + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_reserve_closed (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct GNUNET_TIME_Timestamp execution_date, + const struct TALER_FullPayto receiver_account, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *closing_fee, + uint64_t close_request_row); + +#endif diff --git a/src/include/taler/exchange-database/insert_reserve_open_deposit.h b/src/include/taler/exchange-database/insert_reserve_open_deposit.h @@ -0,0 +1,55 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_insert_reserve_open_deposit.h + * @brief implementation of the insert_reserve_open_deposit function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_RESERVE_OPEN_DEPOSIT_H +#define EXCHANGE_DATABASE_INSERT_RESERVE_OPEN_DEPOSIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert reserve open coin deposit data into database. + * Subtracts the @a coin_total from the coin's balance. + * + * @param cls closure + * @param cpi public information about the coin + * @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT + * @param known_coin_id ID of the coin in the known_coins table + * @param coin_total amount to be spent of the coin (including deposit fee) + * @param reserve_sig signature by the reserve affirming the open operation + * @param reserve_pub public key of the reserve being opened + * @param[out] insufficient_funds set to true if the coin's balance is insufficient, otherwise to false + * @return transaction status code, 0 if operation is already in the DB + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_reserve_open_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinPublicInfo *cpi, + const struct TALER_CoinSpendSignatureP *coin_sig, + uint64_t known_coin_id, + const struct TALER_Amount *coin_total, + const struct TALER_ReserveSignatureP *reserve_sig, + const struct TALER_ReservePublicKeyP *reserve_pub, + bool *insufficient_funds); + +#endif diff --git a/src/include/taler/exchange-database/insert_sanction_list_hit.h b/src/include/taler/exchange-database/insert_sanction_list_hit.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_sanction_list_hit.h + * @brief implementation of the insert_sanction_list_hit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_SANCTION_LIST_HIT_H +#define EXCHANGE_DATABASE_INSERT_SANCTION_LIST_HIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Update sanction list hit status of the given account. + * + * @param cls closure + * @param h_payto account for which the hit is to be stored + * @param to_investigate true to flag account for investigation, + * false to **preserve** existing status + * @param new_rules new KYC rules to apply to the account, NULL to preserve + * existing rules + * @param account_properties new account properties + * @param num_events length of the @a events array + * @param events array of KYC events to trigger + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_sanction_list_hit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + bool to_investigate, + const json_t *new_rules, + const json_t *account_properties, + unsigned int num_events, + const char **events); + +#endif diff --git a/src/include/taler/exchange-database/insert_signkey_revocation.h b/src/include/taler/exchange-database/insert_signkey_revocation.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_signkey_revocation.h + * @brief implementation of the insert_signkey_revocation function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_SIGNKEY_REVOCATION_H +#define EXCHANGE_DATABASE_INSERT_SIGNKEY_REVOCATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_signkey_revocation (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/insert_successor_measure.h b/src/include/taler/exchange-database/insert_successor_measure.h @@ -0,0 +1,40 @@ +/* + This file is part of TALER + Copyright (C) 2022, 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_successor_measure.h + * @brief implementation of the insert_successor_measure function for Postgres + * @author Florian Dold + */ +#ifndef EXCHANGE_DATABASE_INSERT_SUCCESSOR_MEASURE_H +#define EXCHANGE_DATABASE_INSERT_SUCCESSOR_MEASURE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_successor_measure (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp decision_time, + const char *new_measure_name, + const json_t *jmeasures, + bool *unknown_account, + struct GNUNET_TIME_Timestamp *last_date); + + +#endif diff --git a/src/include/taler/exchange-database/insert_wire.h b/src/include/taler/exchange-database/insert_wire.h @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_wire.h + * @brief implementation of the insert_wire function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_WIRE_H +#define EXCHANGE_DATABASE_INSERT_WIRE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert information about an wire account used by this exchange. + * + * @param cls closure + * @param payto_uri wire account of the exchange + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param open_banking_gateway open banking gateway service, NULL if unavailable + * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable + * @param debit_restrictions JSON array with debit restrictions on the account + * @param credit_restrictions JSON array with credit restrictions on the account + * @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 + * @param bank_label label to show this entry under in the UI, can be NULL + * @param priority determines order in which entries are shown in the UI + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_wire (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + const char *conversion_url, + const char *open_banking_gateway, + const char *wire_transfer_gateway, + const json_t *debit_restrictions, + const json_t *credit_restrictions, + struct GNUNET_TIME_Timestamp start_date, + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority); + + +#endif diff --git a/src/include/taler/exchange-database/insert_wire_fee.h b/src/include/taler/exchange-database/insert_wire_fee.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/insert_wire_fee.h + * @brief implementation of the insert_wire_fee function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_INSERT_WIRE_FEE_H +#define EXCHANGE_DATABASE_INSERT_WIRE_FEE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @param fees how high are the wire fees + * @param master_sig signature over the above by the exchange master key + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_insert_wire_fee (struct EXCHANGEDB_PostgresContext *ctx, + const char *type, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + const struct TALER_WireFeeSet *fees, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/iterate_active_auditors.h b/src/include/taler/exchange-database/iterate_active_auditors.h @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/iterate_active_auditors.h + * @brief implementation of the iterate_active_auditors function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ITERATE_ACTIVE_AUDITORS_H +#define EXCHANGE_DATABASE_ITERATE_ACTIVE_AUDITORS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with information about the exchange's auditors. + * + * @param cls closure with a `struct TEH_KeyStateHandle *` + * @param auditor_pub the public key of the auditor + * @param auditor_url URL of the REST API of the auditor + * @param auditor_name human readable official name of the auditor + */ +typedef void +(*TALER_EXCHANGEDB_AuditorsCallback)( + void *cls, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const char *auditor_url, + const char *auditor_name); + +/** + * Function called to invoke @a cb on every active auditor. Disabled + * auditors are skipped. Runs in its own read-only transaction. + * + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_active_auditors (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_AuditorsCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/iterate_active_signkeys.h b/src/include/taler/exchange-database/iterate_active_signkeys.h @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/iterate_active_signkeys.h + * @brief implementation of the iterate_active_signkeys function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ITERATE_ACTIVE_SIGNKEYS_H +#define EXCHANGE_DATABASE_ITERATE_ACTIVE_SIGNKEYS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Signature of a function called with information about the exchange's + * online signing keys. + * + * @param cls closure with a `struct TEH_KeyStateHandle *` + * @param exchange_pub public key of the exchange + * @param meta meta data information about the signing type (expirations) + * @param master_sig master signature affirming the validity of this denomination + */ +typedef void +(*TALER_EXCHANGEDB_ActiveSignkeysCallback)( + void *cls, + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_EXCHANGEDB_SignkeyMetaData *meta, + const struct TALER_MasterSignatureP *master_sig); + +/** + * Function called to invoke @a cb on every non-revoked exchange signing key + * that has been signed by the master key. Revoked and (for signing!) + * expired keys are skipped. Runs in its own read-only transaction. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param cb function to call on each signing key + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_active_signkeys (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_ActiveSignkeysCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/iterate_auditor_denominations.h b/src/include/taler/exchange-database/iterate_auditor_denominations.h @@ -0,0 +1,65 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/iterate_auditor_denominations.h + * @brief implementation of the iterate_auditor_denominations function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ITERATE_AUDITOR_DENOMINATIONS_H +#define EXCHANGE_DATABASE_ITERATE_AUDITOR_DENOMINATIONS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with information about the denominations + * audited by the exchange's auditors. + * + * @param cls closure with a `struct TEH_KeyStateHandle *` + * @param auditor_pub the public key of an auditor + * @param h_denom_pub hash of a denomination key audited by this auditor + * @param auditor_sig signature from the auditor affirming this + */ +typedef void +(*TALER_EXCHANGEDB_AuditorDenominationsCallback)( + void *cls, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_AuditorSignatureP *auditor_sig); + +/** + * Function called to invoke @a cb on every denomination with an active + * auditor. Disabled auditors and denominations without auditor are + * skipped. Runs in its own read-only transaction. + * + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_auditor_denominations (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_AuditorDenominationsCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/iterate_denomination_info.h b/src/include/taler/exchange-database/iterate_denomination_info.h @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/iterate_denomination_info.h + * @brief implementation of the iterate_denomination_info function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ITERATE_DENOMINATION_INFO_H +#define EXCHANGE_DATABASE_ITERATE_DENOMINATION_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with information about the exchange's denomination keys. + * Note that the 'master' field in @a issue will not yet be initialized when + * this function is called! + * + * @param cls closure + * @param denom_serial table row of the denomination + * @param denom_pub public key of the denomination + * @param issue detailed information about the denomination (value, expiration times, fees); + */ +typedef void +(*TALER_EXCHANGEDB_DenominationCallback)( + void *cls, + uint64_t denom_serial, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue); + +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_denomination_info (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_DenominationCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/iterate_denominations.h b/src/include/taler/exchange-database/iterate_denominations.h @@ -0,0 +1,287 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/iterate_denominations.h + * @brief implementation of the iterate_denominations function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ITERATE_DENOMINATIONS_H +#define EXCHANGE_DATABASE_ITERATE_DENOMINATIONS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * @brief All information about a denomination key (which is used to + * sign coins into existence). + */ +struct TALER_EXCHANGEDB_DenominationKey +{ + /** + * The private key of the denomination. Will be NULL if the private + * key is not available (this is the case after the key has expired + * for signing coins, but is still valid for depositing coins). + */ + struct TALER_DenominationPrivateKey denom_priv; + + /** + * Decoded denomination public key (the hash of it is in + * @e issue, but we sometimes need the full public key as well). + */ + struct TALER_DenominationPublicKey denom_pub; + + /** + * Signed public information about a denomination key. + */ + struct TALER_EXCHANGEDB_DenominationKeyInformation issue; +}; + + +/** + * @brief Information we keep on bank transfer(s) that established a reserve. + */ +struct TALER_EXCHANGEDB_BankTransfer +{ + + /** + * Public key of the reserve that was filled. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * Amount that was transferred to the exchange. + */ + struct TALER_Amount amount; + + /** + * When did the exchange receive the incoming transaction? + * (This is the execution date of the exchange's database, + * the execution date of the bank should be in @e wire). + */ + struct GNUNET_TIME_Timestamp execution_date; + + /** + * Detailed wire information about the sending account + * in "payto://" format. + */ + struct TALER_FullPayto sender_account_details; + + /** + * Data uniquely identifying the wire transfer (wire transfer-type specific) + */ + uint64_t wire_reference; + +}; + + +/** + * @brief Information we keep on bank transfer(s) that + * closed a reserve. + */ +struct TALER_EXCHANGEDB_ClosingTransfer +{ + + /** + * Public key of the reserve that was depleted. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * Amount that was transferred from the exchange. + */ + struct TALER_Amount amount; + + /** + * Amount that was charged by the exchange. + */ + struct TALER_Amount closing_fee; + + /** + * When did the exchange execute the transaction? + */ + struct GNUNET_TIME_Timestamp execution_date; + + /** + * Detailed wire information about the receiving account + * in payto://-format. + */ + struct TALER_FullPayto receiver_account_details; + + /** + * Detailed wire transfer information that uniquely identifies the + * wire transfer. + */ + struct TALER_WireTransferIdentifierRawP wtid; + +}; + + +/** + * @brief A summary of a Reserve + */ +struct TALER_EXCHANGEDB_Reserve +{ + /** + * The reserve's public key. This uniquely identifies the reserve + */ + struct TALER_ReservePublicKeyP pub; + + /** + * The balance amount existing in the reserve + */ + struct TALER_Amount balance; + + /** + * The expiration date of this reserve; funds will be wired back + * at this time. + */ + struct GNUNET_TIME_Timestamp expiry; + + /** + * The legal expiration date of this reserve; we will forget about + * it at this time. + */ + struct GNUNET_TIME_Timestamp gc; +}; + + +/** + * Meta data about a denomination public key. + * If this is changed, you must also adjust + * taler-exchange-httpd-post-management-keys.c::denomination_meta_cmp(). + */ +struct TALER_EXCHANGEDB_DenominationKeyMetaData +{ + /** + * Serial of the denomination key as in the DB. + * Can be used calls to stored procedures in order to spare + * additional lookups. + */ + uint64_t serial; + + /** + * Start time of the validity period for this key. + */ + struct GNUNET_TIME_Timestamp start; + + /** + * The exchange will sign fresh coins between @e start and this time. + * @e expire_withdraw will be somewhat larger than @e start to + * ensure a sufficiently large anonymity set, while also allowing + * the Exchange to limit the financial damage in case of a key being + * compromised. Thus, exchanges with low volume are expected to have a + * longer withdraw period (@e expire_withdraw - @e start) than exchanges + * with high transaction volume. The period may also differ between + * types of coins. A exchange may also have a few denomination keys + * with the same value with overlapping validity periods, to address + * issues such as clock skew. + */ + struct GNUNET_TIME_Timestamp expire_withdraw; + + /** + * Coins signed with the denomination key must be spent or refreshed + * between @e start and this expiration time. After this time, the + * exchange will refuse transactions involving this key as it will + * "drop" the table with double-spending information (shortly after) + * this time. Note that wallets should refresh coins significantly + * before this time to be on the safe side. @e expire_deposit must be + * significantly larger than @e expire_withdraw (by months or even + * years). + */ + struct GNUNET_TIME_Timestamp expire_deposit; + + /** + * When do signatures with this denomination key become invalid? + * After this point, these signatures cannot be used in (legal) + * disputes anymore, as the Exchange is then allowed to destroy its side + * of the evidence. @e expire_legal is expected to be significantly + * larger than @e expire_deposit (by a year or more). + */ + struct GNUNET_TIME_Timestamp expire_legal; + + /** + * The value of the coins signed with this denomination key. + */ + struct TALER_Amount value; + + /** + * The fees the exchange charges for operations with + * coins of this denomination. + */ + struct TALER_DenomFeeSet fees; + + /** + * Age restriction for the denomination. (can be zero). If not zero, the bits + * set in the mask mark the edges at the beginning of a next age group. F.e. + * for the age groups + * 0-7, 8-9, 10-11, 12-14, 14-15, 16-17, 18-21, 21-* + * the following bits are set: + * + * 31 24 16 8 0 + * | | | | | + * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1 + * + * A value of 0 means that the denomination does not support the extension for + * age-restriction. + */ + struct TALER_AgeMask age_mask; +}; + + +/** + * Signature of a function called with information about the exchange's + * denomination keys. + * + * @param cls closure with a `struct TEH_KeyStateHandle *` + * @param denom_pub public key of the denomination + * @param h_denom_pub hash of @a denom_pub + * @param meta meta data information about the denomination type (value, expirations, fees) + * @param master_sig master signature affirming the validity of this denomination + * @param recoup_possible true if the key was revoked and clients can currently recoup + * coins of this denomination + */ +typedef void +(*TALER_EXCHANGEDB_DenominationsCallback)( + void *cls, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta, + const struct TALER_MasterSignatureP *master_sig, + bool recoup_possible); + +/** + * 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. + * + * + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_denominations (struct EXCHANGEDB_PostgresContext *ctx, + TALER_EXCHANGEDB_DenominationsCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/iterate_kyc_reference.h b/src/include/taler/exchange-database/iterate_kyc_reference.h @@ -0,0 +1,68 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_iterate_kyc_reference.h + * @brief implementation of the iterate_kyc_reference function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ITERATE_KYC_REFERENCE_H +#define EXCHANGE_DATABASE_ITERATE_KYC_REFERENCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called on all legitimization operations + * we have performed for the given account so far + * (and that have not yet expired). + * + * @param cls closure + * @param kyc_provider_name name of the provider + * of the respective KYC process + * @param provider_user_id UID at a provider (can be NULL) + * @param legi_id legitimization process ID (can be NULL) + */ +typedef void +(*TALER_EXCHANGEDB_LegitimizationProcessCallback)( + void *cls, + const char *kyc_provider_name, + const char *provider_user_id, + const char *legi_id); + +/** + * Call us on KYC legitimization processes satisfied and not expired for the + * given account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_payto account identifier + * @param lpc function to call for each satisfied KYC legitimization process + * @param lpc_cls closure for @a lpc + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_kyc_reference (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_LegitimizationProcessCallback lpc, + void *lpc_cls); + +#endif diff --git a/src/include/taler/exchange-database/iterate_reserve_close_info.h b/src/include/taler/exchange-database/iterate_reserve_close_info.h @@ -0,0 +1,141 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_iterate_reserve_close_info.h + * @brief implementation of the iterate_reserve_close_info function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ITERATE_RESERVE_CLOSE_INFO_H +#define EXCHANGE_DATABASE_ITERATE_RESERVE_CLOSE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Information per Clause-Schnorr (CS) fresh coin to + * be persisted for idempotency during refreshes-reveal. + */ +struct TALER_EXCHANGEDB_CsRevealFreshCoinData +{ + /** + * Denomination of the fresh coin. + */ + struct TALER_DenominationHashP new_denom_pub_hash; + + /** + * Blind signature of the fresh coin (possibly updated + * in case if a replay!). + */ + struct TALER_BlindedDenominationSignature bsig; + + /** + * Offset of the fresh coin in the reveal operation. + * (May not match the array offset as we may have + * a mixture of RSA and CS coins being created, and + * this request is only made for the CS subset). + */ + uint32_t coin_off; +}; + + +/** + * Generic KYC status for some operation. + */ +struct TALER_EXCHANGEDB_KycStatus +{ + + /** + * Account public key that is currently associated + * with the account. Only set if @e have_account_pub + * is true. + */ + union TALER_AccountPublicKeyP account_pub; + + /** + * Number that identifies the KYC requirement the operation + * was about. + */ + uint64_t requirement_row; + + /** + * True if @e account_pub is set. + */ + bool have_account_pub; + + /** + * True if the KYC status is "satisfied". + */ + bool ok; + +}; + + +struct TALER_EXCHANGEDB_ReserveInInfo +{ + const struct TALER_ReservePublicKeyP *reserve_pub; + const struct TALER_Amount *balance; + struct GNUNET_TIME_Timestamp execution_time; + struct TALER_FullPayto sender_account_details; + const char *exchange_account_name; + uint64_t wire_reference; +}; + + +/** + * Function called on each @a amount that was found to + * be relevant for a KYC check. + * + * @param cls closure to allow the KYC module to + * total up amounts and evaluate rules + * @param amount encountered transaction amount + * @param date when was the amount encountered + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to abort iteration + * #GNUNET_SYSERR on internal error (also abort itaration) + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_KycAmountCallback)( + void *cls, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Absolute date); + +/** + * Select information needed for KYC checks on reserve close: historic + * reserve closures going to the same account. + * + * @param cls closure + * @param h_payto which target account is this about? + * @param time_limit oldest transaction that could be relevant + * @param kac function to call for each applicable amount, in reverse chronological order (or until @a kac aborts by returning anything except #GNUNET_OK). + * @param kac_cls closure for @a kac + * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_iterate_reserve_close_info (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls); + + +#endif diff --git a/src/include/taler/exchange-database/kyc_provider_account_lookup.h b/src/include/taler/exchange-database/kyc_provider_account_lookup.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/kyc_provider_account_lookup.h + * @brief implementation of the kyc_provider_account_lookup function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_KYC_PROVIDER_ACCOUNT_LOOKUP_H +#define EXCHANGE_DATABASE_KYC_PROVIDER_ACCOUNT_LOOKUP_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup an + * @a h_payto by @a provider_legitimization_id. + * + * @param cls closure + * @param provider_name + * @param provider_legitimization_id legi to look up + * @param[out] h_payto where to write the result + * @param[out] is_wallet set to true if @a h_payto is for a wallet + * @param[out] process_row where to write the row of the entry + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_kyc_provider_account_lookup (struct EXCHANGEDB_PostgresContext *ctx, + const char *provider_name, + const char *provider_legitimization_id, + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, + uint64_t *process_row); + +#endif diff --git a/src/include/taler/exchange-database/kycauth_in_insert.h b/src/include/taler/exchange-database/kycauth_in_insert.h @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/kycauth_in_insert.h + * @brief implementation of the kycauth_in_insert function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_KYCAUTH_IN_INSERT_H +#define EXCHANGE_DATABASE_KYCAUTH_IN_INSERT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert an incoming KCYAUTH wire transfer into + * the database and update the authentication key + * for the origin account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param account_pub public key of the account + * @param credit_amount amount we were credited + * @param execution_date when was the transfer made + * @param debit_account_uri URI of the debit account + * @param section_name section of the exchange bank account that received the transfer + * @param serial_id bank-specific row identifying the transfer + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_kycauth_in_insert (struct EXCHANGEDB_PostgresContext *ctx, + const union TALER_AccountPublicKeyP *account_pub, + const struct TALER_Amount *credit_amount, + struct GNUNET_TIME_Timestamp execution_date, + const struct TALER_FullPayto debit_account_uri, + const char *section_name, + uint64_t serial_id); + + +#endif diff --git a/src/include/taler/exchange-database/lookup_active_legitimization.h b/src/include/taler/exchange-database/lookup_active_legitimization.h @@ -0,0 +1,50 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_active_legitimization.h + * @brief implementation of the lookup_active_legitimization function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_ACTIVE_LEGITIMIZATION_H +#define EXCHANGE_DATABASE_LOOKUP_ACTIVE_LEGITIMIZATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup measure data for an active legitimization process. + * + * @param cls closure + * @param legitimization_process_serial_id + * row in legitimization_processes table to access + * @param[out] measure_index set to the measure the + * process is trying to satisfy + * @param[out] jmeasures set to the legitimization + * measures that were put on the account + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_active_legitimization (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t legitimization_process_serial_id, + uint32_t *measure_index, + json_t **jmeasures); + + +#endif diff --git a/src/include/taler/exchange-database/lookup_aml_file_number.h b/src/include/taler/exchange-database/lookup_aml_file_number.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_aml_file_number.h + * @brief implementation of the lookup_aml_file_number function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_AML_FILE_NUMBER_H +#define EXCHANGE_DATABASE_LOOKUP_AML_FILE_NUMBER_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup AML file number by the payto address. + * + * @param cls closure + * @param h_payto account for which to find the row ID + * @param[out] kyc_target_row set to row in the kyc_targets table for @a h_payto + * @param[out] is_wallet set to true if this account is for a wallet + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_aml_file_number (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint64_t *kyc_target_row, + bool *is_wallet); + + +#endif diff --git a/src/include/taler/exchange-database/lookup_aml_history.h b/src/include/taler/exchange-database/lookup_aml_history.h @@ -0,0 +1,82 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_aml_history.h + * @brief implementation of the lookup_aml_history function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_AML_HISTORY_H +#define EXCHANGE_DATABASE_LOOKUP_AML_HISTORY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with historic AML events of an + * account. + * + * @param cls closure + * @param outcome_serial_id row ID of the decision + * @param decision_time when was the decision taken + * @param justification what was the given justification + * @param decider_pub which key signed the decision + * @param jproperties what are the new account properties + * @param jnew_rules what are the new account rules + * @param to_investigate should AML staff investigate + * after the decision + * @param is_active is this the active decision + */ +typedef void +(*TALER_EXCHANGEDB_AmlHistoryCallback) ( + void *cls, + uint64_t outcome_serial_id, + struct GNUNET_TIME_Timestamp decision_time, + const char *justification, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + const json_t *jproperties, + const json_t *jnew_rules, + bool to_investigate, + bool is_active); + +/** + * Lookup AML history for an account identified via + * @a h_payto. + * + * @param cls closure + * @param h_payto hash of account to lookup history for + * @param offset row ID to start returning results from + * @param limit how many results to return, negative for descending order + * @param cb function to call on results + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_aml_history (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlHistoryCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/lookup_aml_officer.h b/src/include/taler/exchange-database/lookup_aml_officer.h @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_aml_officer.h + * @brief implementation of the lookup_aml_officer function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_AML_OFFICER_H +#define EXCHANGE_DATABASE_LOOKUP_AML_OFFICER_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Fetch AML staff record. + * + * @param cls closure + * @param decider_pub public key of the staff member + * @param[out] master_sig offline signature affirming the AML officer + * @param[out] decider_name full name of the staff member + * @param[out] is_active true to enable, false to set as inactive + * @param[out] read_only true to set read-only access + * @param[out] last_change when was the change made effective + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_aml_officer (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + struct TALER_MasterSignatureP *master_sig, + char **decider_name, + bool *is_active, + bool *read_only, + struct GNUNET_TIME_Absolute *last_change); + +#endif diff --git a/src/include/taler/exchange-database/lookup_auditor_status.h b/src/include/taler/exchange-database/lookup_auditor_status.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_auditor_status.h + * @brief implementation of the lookup_auditor_status function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_AUDITOR_STATUS_H +#define EXCHANGE_DATABASE_LOOKUP_AUDITOR_STATUS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup current state of an auditor. + * + * @param cls closure + * @param auditor_pub key to look up information for + * @param[out] auditor_url set to the base URL of the auditor's REST API; memory to be + * released by the caller! + * @param[out] enabled set if the auditor is currently in use + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_auditor_status (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AuditorPublicKeyP *auditor_pub, + char **auditor_url, + bool *enabled); + +#endif diff --git a/src/include/taler/exchange-database/lookup_auditor_timestamp.h b/src/include/taler/exchange-database/lookup_auditor_timestamp.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_auditor_timestamp.h + * @brief implementation of the lookup_auditor_timestamp function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_AUDITOR_TIMESTAMP_H +#define EXCHANGE_DATABASE_LOOKUP_AUDITOR_TIMESTAMP_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_auditor_timestamp (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AuditorPublicKeyP *auditor_pub, + struct GNUNET_TIME_Timestamp *last_date); + +#endif diff --git a/src/include/taler/exchange-database/lookup_completed_legitimization.h b/src/include/taler/exchange-database/lookup_completed_legitimization.h @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_lookup_pending_legitimization.h + * @brief implementation of the lookup_pending_legitimization function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_COMPLETED_LEGITIMIZATION_H +#define EXCHANGE_DATABASE_LOOKUP_COMPLETED_LEGITIMIZATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup measure data for a legitimization process. + * + * @param cls closure + * @param legitimization_measure_serial_id + * row in legitimization_measures table to access + * @param measure_index index of the measure to return + * attribute data for + * @param[out] access_token + * set to token for access control that must match + * @param[out] h_payto set to the the hash of the + * payto URI of the account undergoing legitimization + * @param[out] is_wallet set to true if @a h_payto is for a wallet + * @param[out] jmeasures set to the legitimization + * measures that were put on the account + * @param[out] is_finished set to true if the legitimization was + * already finished + * @param[out] encrypted_attributes_len set to length of + * @a encrypted_attributes + * @param[out] encrypted_attributes set to the attributes + * obtained for the legitimization process, if it + * succeeded, otherwise set to NULL + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_completed_legitimization (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t legitimization_measure_serial_id, + uint32_t measure_index, + struct TALER_AccountAccessTokenP *access_token, + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, + json_t **jmeasures, + bool *is_finished, + size_t *encrypted_attributes_len, + void **encrypted_attributes); + +#endif diff --git a/src/include/taler/exchange-database/lookup_denomination_key.h b/src/include/taler/exchange-database/lookup_denomination_key.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_denomination_key.h + * @brief implementation of the lookup_denomination_key function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_DENOMINATION_KEY_H +#define EXCHANGE_DATABASE_LOOKUP_DENOMINATION_KEY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup information about current denomination key. + * + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_denomination_key (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *h_denom_pub, + struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta); + +#endif diff --git a/src/include/taler/exchange-database/lookup_global_fee_by_time.h b/src/include/taler/exchange-database/lookup_global_fee_by_time.h @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_global_fee_by_time.h + * @brief implementation of the lookup_global_fee_by_time function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_GLOBAL_FEE_BY_TIME_H +#define EXCHANGE_DATABASE_LOOKUP_GLOBAL_FEE_BY_TIME_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup information about known global fees. + * + * @param cls closure + * @param start_time starting time of fee + * @param end_time end time of fee + * @param[out] fees set to wire fees for that time period; if + * different global fee exists within this time + * period, an 'invalid' amount is returned. + * @param[out] purse_timeout set to when unmerged purses expire + * @param[out] history_expiration set to when we expire reserve histories + * @param[out] purse_account_limit set to number of free purses + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_global_fee_by_time (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp start_time, + struct GNUNET_TIME_Timestamp end_time, + struct TALER_GlobalFeeSet *fees, + struct GNUNET_TIME_Relative *purse_timeout, + struct GNUNET_TIME_Relative *history_expiration, + uint32_t *purse_account_limit); + +#endif diff --git a/src/include/taler/exchange-database/lookup_h_payto_by_access_token.h b/src/include/taler/exchange-database/lookup_h_payto_by_access_token.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_h_payto_by_access_token.h + * @brief implementation of the lookup_h_payto_by_access_token function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_H_PAYTO_BY_ACCESS_TOKEN_H +#define EXCHANGE_DATABASE_LOOKUP_H_PAYTO_BY_ACCESS_TOKEN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup @a h_payto based on an @a access_token. + * + * @param cls closure + * @param access_token + * set to token for access control + * @param[out] h_payto set to the the hash of the + * payto URI of the account (if found) + * @param[out] is_wallet set to true if @a h_payto + * is for a wallet + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_h_payto_by_access_token (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AccountAccessTokenP *access_token, + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet); + +#endif diff --git a/src/include/taler/exchange-database/lookup_kyc_history.h b/src/include/taler/exchange-database/lookup_kyc_history.h @@ -0,0 +1,83 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_kyc_history.h + * @brief implementation of the lookup_kyc_history function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_KYC_HISTORY_H +#define EXCHANGE_DATABASE_LOOKUP_KYC_HISTORY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with historic KYC events of an + * account. + * + * @param cls closure + * @param provider_name name of the KYC provider + * @param finished did the KYC process finish + * @param error_code error code from the KYC process + * @param error_message error message from the KYC process, + * or NULL for none + * @param provider_user_id user ID at the provider + * or NULL for none + * @param provider_legitimization_id legitimization process ID at the provider + * or NULL for none + * @param collection_time when was the data collected + * @param expiration_time when does the collected data expire + * @param encrypted_attributes_len number of bytes in @a encrypted_attributes + * @param encrypted_attributes encrypted KYC attributes + */ +typedef void +(*TALER_EXCHANGEDB_KycHistoryCallback) ( + void *cls, + const char *provider_name, + bool finished, + enum TALER_ErrorCode error_code, + const char *error_message, + const char *provider_user_id, + const char *provider_legitimization_id, + struct GNUNET_TIME_Timestamp collection_time, + struct GNUNET_TIME_Absolute expiration_time, + size_t encrypted_attributes_len, + const void *encrypted_attributes); + +/** + * Lookup KYC history for an account identified via + * @a h_payto. + * + * @param cls closure + * @param h_payto hash of account to lookup history for + * @param cb function to call on results + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_kyc_history (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_KycHistoryCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/lookup_kyc_process_by_account.h b/src/include/taler/exchange-database/lookup_kyc_process_by_account.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_kyc_process_by_account.h + * @brief implementation of the lookup_kyc_process_by_account function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_KYC_PROCESS_BY_ACCOUNT_H +#define EXCHANGE_DATABASE_LOOKUP_KYC_PROCESS_BY_ACCOUNT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup KYC provider meta data. + * + * @param cls closure + * @param provider_name provider that must be checked + * @param h_payto account that must be KYC'ed + * @param[out] process_row row with the legitimization data + * @param[out] expiration how long is this KYC check set to be valid (in the past if invalid) + * @param[out] provider_account_id provider account ID + * @param[out] provider_legitimization_id provider legitimization ID + * @param[out] is_wallet set to true if @a h_payto is for a wallet + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_kyc_process_by_account (struct EXCHANGEDB_PostgresContext *ctx, + const char *provider_name, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint64_t *process_row, + struct GNUNET_TIME_Absolute *expiration, + char **provider_account_id, + char **provider_legitimization_id, + bool *is_wallet); + +#endif diff --git a/src/include/taler/exchange-database/lookup_kyc_requirement_by_row.h b/src/include/taler/exchange-database/lookup_kyc_requirement_by_row.h @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_kyc_requirement_by_row.h + * @brief implementation of the lookup_kyc_requirement_by_row function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_KYC_REQUIREMENT_BY_ROW_H +#define EXCHANGE_DATABASE_LOOKUP_KYC_REQUIREMENT_BY_ROW_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup KYC requirement. + * + * @param cls closure + * @param h_payto identifies account to look up requirement for + * @param account_pub set to public key of the account + * needed to authorize access + * @param[out] is_wallet set to #GNUNET_YES if the account is + * that of a wallet (#GNUNET_SYSERR is used if unknown) + * @param[out] access_token set to the access token to begin + * work on KYC processes for this account + * @param[out] rule_gen row ID of the last decision this + * response is based on (for long-polling by clients) + * @param[out] jrules set to active ``LegitimizationRuleSet`` + * of the account impacted by the requirement + * @param[out] aml_review set to true if the account is under + * active review by AML staff + * @param[out] kyc_required set to true if the user must pass + * some KYC check before some previous operation may continue + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_kyc_requirement_by_row (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + const union TALER_AccountPublicKeyP *account_pub, + enum GNUNET_GenericReturnValue *is_wallet, + struct TALER_AccountAccessTokenP *access_token, + uint64_t *rule_gen, + json_t **jrules, + bool *aml_review, + bool *kyc_required); + + +#endif diff --git a/src/include/taler/exchange-database/lookup_kyc_status_by_token.h b/src/include/taler/exchange-database/lookup_kyc_status_by_token.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_kyc_status_by_token.h + * @brief implementation of the lookup_kyc_status_by_token function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_KYC_STATUS_BY_TOKEN_H +#define EXCHANGE_DATABASE_LOOKUP_KYC_STATUS_BY_TOKEN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup KYC status by account access token. + * + * @param cls closure + * @param access_token key to look under + * @param[out] row set to requirement row that matches + * @param[out] jmeasures set to the LegitimizationMeasures for the @a access_token; must be freed by caller! + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_kyc_status_by_token (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AccountAccessTokenP *access_token, + uint64_t *row, + json_t **jmeasures); + + +#endif diff --git a/src/include/taler/exchange-database/lookup_pending_legitimization.h b/src/include/taler/exchange-database/lookup_pending_legitimization.h @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_pending_legitimization.h + * @brief implementation of the lookup_pending_legitimization function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_PENDING_LEGITIMIZATION_H +#define EXCHANGE_DATABASE_LOOKUP_PENDING_LEGITIMIZATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup measure data for a legitimization process. + * + * @param cls closure + * @param legitimization_measure_serial_id + * row in legitimization_measures table to access + * @param[out] access_token + * set to token for access control that must match + * @param[out] h_payto set to the the hash of the + * payto URI of the account undergoing legitimization + * @param[out] jmeasures set to the legitimization + * measures that were put on the account + * @param[out] is_finished set to true if the legitimization was + * already finished + * @param[out] is_wallet set to true if @a h_payto is for a wallet + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_pending_legitimization (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t legitimization_measure_serial_id, + struct TALER_AccountAccessTokenP *access_token, + struct TALER_NormalizedPaytoHashP *h_payto, + json_t **jmeasures, + bool *is_finished, + bool *is_wallet); + +#endif diff --git a/src/include/taler/exchange-database/lookup_records_by_table.h b/src/include/taler/exchange-database/lookup_records_by_table.h @@ -0,0 +1,904 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_lookup_records_by_table.h + * @brief implementation of the lookup_records_by_table function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_RECORDS_BY_TABLE_H +#define EXCHANGE_DATABASE_LOOKUP_RECORDS_BY_TABLE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +/* Callback typedefs */ +/** + * @file include/taler/taler_exchangedb_plugin.h + * @brief Low-level (statement-level) database access for the exchange + * @author Florian Dold + * @author Christian Grothoff + * @author Özgür Kesim + */ +#ifndef TALER_EXCHANGEDB_PLUGIN_H +#define TALER_EXCHANGEDB_PLUGIN_H +#include <jansson.h> +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_db_lib.h> +#include <taler/taler_util.h> +#include <taler/taler_signatures.h> +#include <taler/taler_extensions_policy.h> + + +struct EXCHANGEDB_PostgresContext; +/** + * The conflict that can occur for the age restriction + */ +enum TALER_EXCHANGEDB_AgeCommitmentHash_Conflict +{ + /** + * Value OK, no conflict + */ + TALER_AgeCommitmentHashP_NoConflict = 0, + + /** + * Given hash had a value, but NULL (or zero) was expected + */ + TALER_AgeCommitmentHashP_NullExpected = 1, + + /** + * Given hash was NULL, but value was expected + */ + TALER_AgeCommitmentHashP_ValueExpected = 2, + + /** + * Given hash differs from value in the known coin + */ + TALER_AgeCommitmentHashP_ValueDiffers = 3, +}; + +/** + * Per-coin information returned when doing a batch insert. + */ +struct TALER_EXCHANGEDB_CoinInfo +{ + /** + * Row of the coin in the known_coins table. + */ + uint64_t known_coin_id; + + /** + * Hash of the denomination, relevant on @e denom_conflict. + */ + struct TALER_DenominationHashP denom_hash; + + /** + * Hash of the age commitment, relevant on @e age_conflict. + */ + struct TALER_AgeCommitmentHashP h_age_commitment; + + /** + * True if the coin was known previously. + */ + bool existed; + + /** + * True if the known coin has a different denomination; + * application will find denomination of the already + * known coin in @e denom_hash. + */ + bool denom_conflict; + + /** + * Indicates if and what kind of conflict with the age + * restriction of the known coin was present; + * application will find age commitment of the already + * known coin in @e h_age_commitment. + */ + enum TALER_EXCHANGEDB_AgeCommitmentHash_Conflict age_conflict; +}; + + +/** + * Information about a denomination key. + */ +struct TALER_EXCHANGEDB_DenominationKeyInformation +{ + + /** + * Signature over this struct to affirm the validity of the key. + */ + struct TALER_MasterSignatureP signature; + + /** + * Start time of the validity period for this key. + */ + struct GNUNET_TIME_Timestamp start; + + /** + * The exchange will sign fresh coins between @e start and this time. + * @e expire_withdraw will be somewhat larger than @e start to + * ensure a sufficiently large anonymity set, while also allowing + * the Exchange to limit the financial damage in case of a key being + * compromised. Thus, exchanges with low volume are expected to have a + * longer withdraw period (@e expire_withdraw - @e start) than exchanges + * with high transaction volume. The period may also differ between + * types of coins. A exchange may also have a few denomination keys + * with the same value with overlapping validity periods, to address + * issues such as clock skew. + */ + struct GNUNET_TIME_Timestamp expire_withdraw; + + /** + * Coins signed with the denomination key must be spent or refreshed + * between @e start and this expiration time. After this time, the + * exchange will refuse transactions involving this key as it will + * "drop" the table with double-spending information (shortly after) + * this time. Note that wallets should refresh coins significantly + * before this time to be on the safe side. @e expire_deposit must be + * significantly larger than @e expire_withdraw (by months or even + * years). + */ + struct GNUNET_TIME_Timestamp expire_deposit; + + /** + * When do signatures with this denomination key become invalid? + * After this point, these signatures cannot be used in (legal) + * disputes anymore, as the Exchange is then allowed to destroy its side + * of the evidence. @e expire_legal is expected to be significantly + * larger than @e expire_deposit (by a year or more). + */ + struct GNUNET_TIME_Timestamp expire_legal; + + /** + * The value of the coins signed with this denomination key. + */ + struct TALER_Amount value; + + /** + * Fees for the coin. + */ + struct TALER_DenomFeeSet fees; + + /** + * Hash code of the denomination public key. (Used to avoid having + * the variable-size RSA key in this struct.) + */ + struct TALER_DenominationHashP denom_hash; + + /** + * If denomination was setup for age restriction, non-zero age mask. + * Note that the mask is not part of the signature. + */ + struct TALER_AgeMask age_mask; +}; + + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Events signalling that a coin deposit status + * changed. + */ +struct TALER_CoinDepositEventP +{ + /** + * Of type #TALER_DBEVENT_EXCHANGE_DEPOSIT_STATUS_CHANGED. + */ + struct GNUNET_DB_EventHeaderP header; + + /** + * Public key of the merchant. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + +}; + +/** + * Events signalling a reserve got funding. + */ +struct TALER_ReserveEventP +{ + /** + * Of type #TALER_DBEVENT_EXCHANGE_RESERVE_INCOMING. + */ + struct GNUNET_DB_EventHeaderP header; + + /** + * Public key of the reserve the event is about. + */ + struct TALER_ReservePublicKeyP reserve_pub; +}; + + +/** + * Signature of events signalling a purse changed its status. + */ +struct TALER_PurseEventP +{ + /** + * Of type #TALER_DBEVENT_EXCHANGE_PURSE_MERGED or + * #TALER_DBEVENT_EXCHANGE_PURSE_DEPOSITED. + */ + struct GNUNET_DB_EventHeaderP header; + + /** + * Public key of the purse the event is about. + */ + struct TALER_PurseContractPublicKeyP purse_pub; +}; + + +/** + * Signature of events signalling a KYC process was completed. + */ +struct TALER_KycCompletedEventP +{ + /** + * Of type #TALER_DBEVENT_EXCHANGE_KYC_COMPLETED. + */ + struct GNUNET_DB_EventHeaderP header; + + /** + * Hash of payto://-URI for which the KYC state changed. + */ + struct TALER_NormalizedPaytoHashP h_payto; +}; + + +GNUNET_NETWORK_STRUCT_END + +/** + * Meta data about an exchange online signing key. + */ +struct TALER_EXCHANGEDB_SignkeyMetaData +{ + /** + * Start time of the validity period for this key. + */ + struct GNUNET_TIME_Timestamp start; + + /** + * The exchange will sign messages with this key between @e start and this time. + */ + struct GNUNET_TIME_Timestamp expire_sign; + + /** + * When do signatures with this sign key become invalid? + * After this point, these signatures cannot be used in (legal) + * disputes anymore, as the Exchange is then allowed to destroy its side + * of the evidence. @e expire_legal is expected to be significantly + * larger than @e expire_sign (by a year or more). + */ + struct GNUNET_TIME_Timestamp expire_legal; + +}; + + +/** + * Enumeration of all of the tables replicated by exchange-auditor + * database replication. + * + * Note: wire_accounts is not replicated. So far not needed by the auditor. + */ +enum TALER_EXCHANGEDB_ReplicatedTable +{ + TALER_EXCHANGEDB_RT_DENOMINATIONS, + TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS, + TALER_EXCHANGEDB_RT_KYC_TARGETS, + TALER_EXCHANGEDB_RT_WIRE_TARGETS, + TALER_EXCHANGEDB_RT_RESERVES, + TALER_EXCHANGEDB_RT_RESERVES_IN, + TALER_EXCHANGEDB_RT_RESERVES_CLOSE, + TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS, + TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS, + TALER_EXCHANGEDB_RT_AUDITORS, + TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS, + TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS, + TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS, + TALER_EXCHANGEDB_RT_KNOWN_COINS, + TALER_EXCHANGEDB_RT_REFRESH, + TALER_EXCHANGEDB_RT_BATCH_DEPOSITS, + TALER_EXCHANGEDB_RT_COIN_DEPOSITS, + TALER_EXCHANGEDB_RT_REFUNDS, + TALER_EXCHANGEDB_RT_WIRE_OUT, + TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING, + TALER_EXCHANGEDB_RT_WIRE_FEE, + TALER_EXCHANGEDB_RT_GLOBAL_FEE, + TALER_EXCHANGEDB_RT_RECOUP, + TALER_EXCHANGEDB_RT_RECOUP_REFRESH, + TALER_EXCHANGEDB_RT_EXTENSIONS, + TALER_EXCHANGEDB_RT_POLICY_DETAILS, + TALER_EXCHANGEDB_RT_POLICY_FULFILLMENTS, + TALER_EXCHANGEDB_RT_PURSE_REQUESTS, + TALER_EXCHANGEDB_RT_PURSE_DECISION, + TALER_EXCHANGEDB_RT_PURSE_MERGES, + TALER_EXCHANGEDB_RT_PURSE_DEPOSITS, + TALER_EXCHANGEDB_RT_ACCOUNT_MERGES, + TALER_EXCHANGEDB_RT_HISTORY_REQUESTS, + TALER_EXCHANGEDB_RT_CLOSE_REQUESTS, + TALER_EXCHANGEDB_RT_WADS_OUT, + TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES, + TALER_EXCHANGEDB_RT_WADS_IN, + TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES, + TALER_EXCHANGEDB_RT_PROFIT_DRAINS, + TALER_EXCHANGEDB_RT_AML_STAFF, + TALER_EXCHANGEDB_RT_PURSE_DELETION, + TALER_EXCHANGEDB_RT_WITHDRAW, + TALER_EXCHANGEDB_RT_LEGITIMIZATION_MEASURES, + TALER_EXCHANGEDB_RT_LEGITIMIZATION_OUTCOMES, + TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES, + TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES, + TALER_EXCHANGEDB_RT_AML_HISTORY, + TALER_EXCHANGEDB_RT_KYC_EVENTS, + TALER_EXCHANGEDB_RT_KYCAUTHS_IN +}; + + +/** + * Record of a single entry in a replicated table. + */ +struct TALER_EXCHANGEDB_TableData +{ + /** + * Data of which table is returned here? + */ + enum TALER_EXCHANGEDB_ReplicatedTable table; + + /** + * Serial number of the record. + */ + uint64_t serial; + + /** + * Table-specific details. + */ + union + { + + /** + * Details from the 'denominations' table. + */ + struct + { + uint32_t denom_type; + uint32_t age_mask; + struct TALER_DenominationPublicKey denom_pub; + struct TALER_MasterSignatureP master_sig; + struct GNUNET_TIME_Timestamp valid_from; + struct GNUNET_TIME_Timestamp expire_withdraw; + struct GNUNET_TIME_Timestamp expire_deposit; + struct GNUNET_TIME_Timestamp expire_legal; + struct TALER_Amount coin; + struct TALER_DenomFeeSet fees; + } denominations; + + struct + { + struct TALER_MasterSignatureP master_sig; + uint64_t denominations_serial; + } denomination_revocations; + + struct + { + struct TALER_FullPayto full_payto_uri; + } wire_targets; + + struct + { + struct TALER_NormalizedPaytoHashP h_normalized_payto; + struct TALER_AccountAccessTokenP access_token; + union TALER_AccountPublicKeyP target_pub; + bool no_account; + bool is_wallet; + } kyc_targets; + + struct + { + struct TALER_AccountAccessTokenP target_token; + struct GNUNET_TIME_Timestamp start_time; + json_t *measures; + uint32_t display_priority; + } legitimization_measures; + + struct + { + struct TALER_NormalizedPaytoHashP h_payto; + struct GNUNET_TIME_Timestamp decision_time; + struct GNUNET_TIME_Timestamp expiration_time; + json_t *properties; + bool to_investigate; + json_t *new_rules; + } legitimization_outcomes; + + struct + { + struct TALER_NormalizedPaytoHashP h_payto; + struct GNUNET_TIME_Timestamp start_time; + struct GNUNET_TIME_Timestamp expiration_time; + uint64_t legitimization_measure_serial_id; + uint32_t measure_index; + char *provider_name; + char *provider_user_id; + char *provider_legitimization_id; + char *redirect_url; + } legitimization_processes; + + struct + { + struct TALER_NormalizedPaytoHashP h_payto; + uint64_t legitimization_serial; + struct GNUNET_TIME_Timestamp collection_time; + struct GNUNET_TIME_Timestamp expiration_time; + uint64_t trigger_outcome_serial; + void *encrypted_attributes; + size_t encrypted_attributes_size; + } kyc_attributes; + + struct + { + struct TALER_NormalizedPaytoHashP h_payto; + uint64_t outcome_serial_id; + char *justification; + struct TALER_AmlOfficerPublicKeyP decider_pub; + struct TALER_AmlOfficerSignatureP decider_sig; + } aml_history; + + struct + { + struct GNUNET_TIME_Timestamp event_timestamp; + char *event_type; + } kyc_events; + + struct + { + struct TALER_AmlOfficerPublicKeyP decider_pub; + struct TALER_MasterSignatureP master_sig; + char *decider_name; + bool is_active; + bool read_only; + struct GNUNET_TIME_Timestamp last_change; + } aml_staff; + + struct + { + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_TIME_Timestamp expiration_date; + struct GNUNET_TIME_Timestamp gc_date; + } reserves; + + struct + { + uint64_t wire_reference; + struct TALER_Amount credit; + struct TALER_FullPaytoHashP sender_account_h_payto; + char *exchange_account_section; + struct GNUNET_TIME_Timestamp execution_date; + struct TALER_ReservePublicKeyP reserve_pub; + } reserves_in; + + struct + { + uint64_t wire_reference; + struct TALER_Amount credit; + struct TALER_FullPaytoHashP sender_account_h_payto; + char *exchange_account_section; + struct GNUNET_TIME_Timestamp execution_date; + union TALER_AccountPublicKeyP account_pub; + } kycauth_in; + + struct + { + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_TIME_Timestamp request_timestamp; + struct GNUNET_TIME_Timestamp expiration_date; + struct TALER_ReserveSignatureP reserve_sig; + struct TALER_Amount reserve_payment; + uint32_t requested_purse_limit; + } reserves_open_requests; + + struct + { + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinSpendSignatureP coin_sig; + struct TALER_ReserveSignatureP reserve_sig; + struct TALER_Amount contribution; + } reserves_open_deposits; + + struct + { + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_TIME_Timestamp execution_date; + struct TALER_WireTransferIdentifierRawP wtid; + struct TALER_FullPaytoHashP sender_account_h_payto; + struct TALER_Amount amount; + struct TALER_Amount closing_fee; + } reserves_close; + + struct + { + struct TALER_AuditorPublicKeyP auditor_pub; + char *auditor_url; + char *auditor_name; + bool is_active; + struct GNUNET_TIME_Timestamp last_change; + } auditors; + + struct + { + uint64_t auditor_uuid; + uint64_t denominations_serial; + struct TALER_AuditorSignatureP auditor_sig; + } auditor_denom_sigs; + + struct + { + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_MasterSignatureP master_sig; + struct TALER_EXCHANGEDB_SignkeyMetaData meta; + } exchange_sign_keys; + + struct + { + uint64_t esk_serial; + struct TALER_MasterSignatureP master_sig; + } signkey_revocations; + + struct + { + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_AgeCommitmentHashP age_hash; + uint64_t denominations_serial; + struct TALER_DenominationSignature denom_sig; + } known_coins; + + struct + { + struct TALER_RefreshCommitmentP rc; + struct GNUNET_TIME_Timestamp execution_date; + struct TALER_Amount amount_with_fee; + struct TALER_CoinSpendPublicKeyP old_coin_pub; + struct TALER_CoinSpendSignatureP old_coin_sig; + struct TALER_PublicRefreshMasterSeedP refresh_seed; + uint32_t noreveal_index; + struct TALER_HashBlindedPlanchetsP planchets_h; + struct TALER_HashBlindedPlanchetsP selected_h; + bool no_blinding_seed; + struct TALER_BlindingMasterSeedP blinding_seed; + size_t num_cs_r_values; + struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values; + uint64_t cs_r_choices; + size_t num_coins; + uint64_t *denom_serials; + struct TALER_BlindedDenominationSignature *denom_sigs; + } refresh; + + struct + { + uint64_t shard; + struct TALER_MerchantPublicKeyP merchant_pub; + struct GNUNET_TIME_Timestamp wallet_timestamp; + struct GNUNET_TIME_Timestamp exchange_timestamp; + struct GNUNET_TIME_Timestamp refund_deadline; + struct GNUNET_TIME_Timestamp wire_deadline; + struct TALER_PrivateContractHashP h_contract_terms; + bool no_wallet_data_hash; + struct GNUNET_HashCode wallet_data_hash; + struct TALER_WireSaltP wire_salt; + struct TALER_FullPaytoHashP wire_target_h_payto; + bool no_policy_details; + uint64_t policy_details_serial_id; + bool policy_blocked; + struct TALER_Amount total_amount; + struct TALER_Amount total_without_fee; + struct TALER_MerchantSignatureP merchant_sig; + bool done; + } batch_deposits; + + struct + { + uint64_t batch_deposit_serial_id; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinSpendSignatureP coin_sig; + struct TALER_Amount amount_with_fee; + } coin_deposits; + + struct + { + struct TALER_CoinSpendPublicKeyP coin_pub; + uint64_t batch_deposit_serial_id; + struct TALER_MerchantSignatureP merchant_sig; + uint64_t rtransaction_id; + struct TALER_Amount amount_with_fee; + } refunds; + + struct + { + struct GNUNET_TIME_Timestamp execution_date; + struct TALER_WireTransferIdentifierRawP wtid_raw; + struct TALER_FullPaytoHashP wire_target_h_payto; + char *exchange_account_section; + struct TALER_Amount amount; + } wire_out; + + struct + { + uint64_t batch_deposit_serial_id; + struct TALER_WireTransferIdentifierRawP wtid_raw; + } aggregation_tracking; + + struct + { + char *wire_method; + struct GNUNET_TIME_Timestamp start_date; + struct GNUNET_TIME_Timestamp end_date; + struct TALER_WireFeeSet fees; + struct TALER_MasterSignatureP master_sig; + } wire_fee; + + struct + { + 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; + } global_fee; + + struct + { + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinSpendSignatureP coin_sig; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; + struct TALER_Amount amount; + struct GNUNET_TIME_Timestamp timestamp; + uint64_t withdraw_serial_id; + } recoup; + + struct + { + uint64_t known_coin_id; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinSpendSignatureP coin_sig; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; + struct TALER_Amount amount; + struct GNUNET_TIME_Timestamp timestamp; + uint64_t rrc_serial; + } recoup_refresh; + + struct + { + char *name; + char *manifest; + } extensions; + + struct + { + struct GNUNET_HashCode hash_code; + json_t *policy_json; + bool no_policy_json; + struct GNUNET_TIME_Timestamp deadline; + struct TALER_Amount commitment; + struct TALER_Amount accumulated_total; + struct TALER_Amount fee; + struct TALER_Amount transferable; + uint16_t fulfillment_state; /* will also be recomputed */ + uint64_t fulfillment_id; + bool no_fulfillment_id; + } policy_details; + + struct + { + struct GNUNET_TIME_Timestamp fulfillment_timestamp; + char *fulfillment_proof; + struct GNUNET_HashCode h_fulfillment_proof; + struct GNUNET_HashCode *policy_hash_codes; + size_t policy_hash_codes_count; + } policy_fulfillments; + + struct + { + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_PurseMergePublicKeyP merge_pub; + struct GNUNET_TIME_Timestamp purse_creation; + struct GNUNET_TIME_Timestamp purse_expiration; + struct TALER_PrivateContractHashP h_contract_terms; + uint32_t age_limit; + uint32_t flags; + struct TALER_Amount amount_with_fee; + struct TALER_Amount purse_fee; + struct TALER_PurseContractSignatureP purse_sig; + } purse_requests; + + struct + { + struct TALER_PurseContractPublicKeyP purse_pub; + struct GNUNET_TIME_Timestamp action_timestamp; + bool refunded; + } purse_decision; + + struct + { + uint64_t partner_serial_id; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_PurseMergeSignatureP merge_sig; + struct GNUNET_TIME_Timestamp merge_timestamp; + } purse_merges; + + struct + { + uint64_t partner_serial_id; + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_Amount amount_with_fee; + struct TALER_CoinSpendSignatureP coin_sig; + } purse_deposits; + + struct + { + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_ReserveSignatureP reserve_sig; + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_NormalizedPaytoHashP wallet_h_payto; + } account_merges; + + struct + { + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_ReserveSignatureP reserve_sig; + struct GNUNET_TIME_Timestamp request_timestamp; + struct TALER_Amount history_fee; + } history_requests; + + struct + { + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_TIME_Timestamp close_timestamp; + struct TALER_ReserveSignatureP reserve_sig; + struct TALER_Amount close; + struct TALER_Amount close_fee; + struct TALER_FullPayto payto_uri; + } close_requests; + + struct + { + struct TALER_WadIdentifierP wad_id; + uint64_t partner_serial_id; + struct TALER_Amount amount; + struct GNUNET_TIME_Timestamp execution_time; + } wads_out; + + struct + { + uint64_t wad_out_serial_id; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_PrivateContractHashP h_contract; + struct GNUNET_TIME_Timestamp purse_expiration; + struct GNUNET_TIME_Timestamp merge_timestamp; + struct TALER_Amount amount_with_fee; + struct TALER_Amount wad_fee; + struct TALER_Amount deposit_fees; + struct TALER_ReserveSignatureP reserve_sig; + struct TALER_PurseContractSignatureP purse_sig; + } wads_out_entries; + + struct + { + struct TALER_WadIdentifierP wad_id; + char *origin_exchange_url; + struct TALER_Amount amount; + struct GNUNET_TIME_Timestamp arrival_time; + } wads_in; + + struct + { + uint64_t wad_in_serial_id; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_PrivateContractHashP h_contract; + struct GNUNET_TIME_Timestamp purse_expiration; + struct GNUNET_TIME_Timestamp merge_timestamp; + struct TALER_Amount amount_with_fee; + struct TALER_Amount wad_fee; + struct TALER_Amount deposit_fees; + struct TALER_ReserveSignatureP reserve_sig; + struct TALER_PurseContractSignatureP purse_sig; + } wads_in_entries; + + struct + { + struct TALER_WireTransferIdentifierRawP wtid; + char *account_section; + struct TALER_FullPayto payto_uri; + struct GNUNET_TIME_Timestamp trigger_date; + struct TALER_Amount amount; + struct TALER_MasterSignatureP master_sig; + } profit_drains; + + struct + { + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_PurseContractSignatureP purse_sig; + } purse_deletion; + + struct + { + struct TALER_HashBlindedPlanchetsP planchets_h; + struct GNUNET_TIME_Timestamp execution_date; + struct TALER_Amount amount_with_fee; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_ReserveSignatureP reserve_sig; + bool age_proof_required; + uint16_t max_age; + uint16_t noreveal_index; + struct TALER_HashBlindedPlanchetsP selected_h; + bool no_blinding_seed; + struct TALER_BlindingMasterSeedP blinding_seed; + size_t num_cs_r_values; + struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values; + uint64_t cs_r_choices; + size_t num_coins; + uint64_t *denom_serials; + struct TALER_BlindedDenominationSignature *denom_sigs; + } withdraw; + + } details; + +}; + + +/** + * Function called on data to replicate in the auditor's database. + * + * @param cls closure + * @param td record from an exchange table + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_SYSERR to fail with an error + */ +typedef int +(*TALER_EXCHANGEDB_ReplicationCallback)( + void *cls, + const struct TALER_EXCHANGEDB_TableData *td); + +/** + * Lookup records above @a serial number in @a table. Used in + * exchange-auditor database replication. + * + * @param cls closure + * @param table table for which we should return the serial + * @param serial largest serial number to exclude + * @param cb function to call on the records + * @param cb_cls closure for @a cb + * @return transaction status code, GNUNET_DB_STATUS_HARD_ERROR if + * @a table does not have a serial number + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_records_by_table (struct EXCHANGEDB_PostgresContext *ctx, + enum TALER_EXCHANGEDB_ReplicatedTable table, + uint64_t serial, + TALER_EXCHANGEDB_ReplicationCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/lookup_rules_by_access_token.h b/src/include/taler/exchange-database/lookup_rules_by_access_token.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_rules_by_access_token.h + * @brief implementation of the lookup_rules_by_access_token function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_RULES_BY_ACCESS_TOKEN_H +#define EXCHANGE_DATABASE_LOOKUP_RULES_BY_ACCESS_TOKEN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup KYC rules by account access token. + * + * @param cls closure + * @param h_payto account hash to look under + * @param[out] jnew_rules set to active LegitimizationRuleSet + * @param[out] rowid set to outcome_serial_id of the row + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_rules_by_access_token (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + json_t **jnew_rules, + uint64_t *rowid); + +#endif diff --git a/src/include/taler/exchange-database/lookup_serial_by_table.h b/src/include/taler/exchange-database/lookup_serial_by_table.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_lookup_serial_by_table.h + * @brief implementation of the lookup_serial_by_table function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_SERIAL_BY_TABLE_H +#define EXCHANGE_DATABASE_LOOKUP_SERIAL_BY_TABLE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup the latest serial number of @a table. Used in + * exchange-auditor database replication. + * + * @param cls closure + * @param table table for which we should return the serial + * @param[out] serial latest serial number in use + * @return transaction status code, GNUNET_DB_STATUS_HARD_ERROR if + * @a table does not have a serial number + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_serial_by_table (struct EXCHANGEDB_PostgresContext *ctx, + enum TALER_EXCHANGEDB_ReplicatedTable table, + uint64_t *serial); + + +#endif diff --git a/src/include/taler/exchange-database/lookup_signing_key.h b/src/include/taler/exchange-database/lookup_signing_key.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_signing_key.h + * @brief implementation of the lookup_signing_key function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_SIGNING_KEY_H +#define EXCHANGE_DATABASE_LOOKUP_SIGNING_KEY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_signing_key (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct TALER_EXCHANGEDB_SignkeyMetaData *meta); + +#endif diff --git a/src/include/taler/exchange-database/lookup_signkey_revocation.h b/src/include/taler/exchange-database/lookup_signkey_revocation.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_signkey_revocation.h + * @brief implementation of the lookup_signkey_revocation function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_SIGNKEY_REVOCATION_H +#define EXCHANGE_DATABASE_LOOKUP_SIGNKEY_REVOCATION_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_signkey_revocation (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/lookup_transfer_by_deposit.h b/src/include/taler/exchange-database/lookup_transfer_by_deposit.h @@ -0,0 +1,64 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_transfer_by_deposit.h + * @brief implementation of the lookup_transfer_by_deposit function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_TRANSFER_BY_DEPOSIT_H +#define EXCHANGE_DATABASE_LOOKUP_TRANSFER_BY_DEPOSIT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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. + * + * @param cls closure + * @param h_contract_terms hash of the proposal data + * @param h_wire hash of merchant wire details + * @param coin_pub public key of deposited coin + * @param merchant_pub merchant public key + * @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 + * @param[out] exec_time when was the transaction done, or + * when we expect it to be done (if @a pending is false) + * @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 + * @param[out] kyc set to the kyc status of the receiver (if @a pending) + * @param[out] account_pub set to public key that is authorized to start the KYC process; unchanged if no such key is known + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_transfer_by_deposit (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant_pub, + bool *pending, + struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Timestamp *exec_time, + struct TALER_Amount *amount_with_fee, + struct TALER_Amount *deposit_fee, + struct TALER_EXCHANGEDB_KycStatus *kyc, + union TALER_AccountPublicKeyP *account_pub); + +#endif diff --git a/src/include/taler/exchange-database/lookup_wire_fee_by_time.h b/src/include/taler/exchange-database/lookup_wire_fee_by_time.h @@ -0,0 +1,77 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_wire_fee_by_time.h + * @brief implementation of the lookup_wire_fee_by_time function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_WIRE_FEE_BY_TIME_H +#define EXCHANGE_DATABASE_LOOKUP_WIRE_FEE_BY_TIME_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Lookup information about known wire fees. Finds all applicable + * fees in the given range. If they are identical, returns the + * respective @a fees. If any of the fees + * differ between @a start_time and @a end_time, the transaction + * succeeds BUT returns an invalid amount for both fees. + * + * @param cls closure + * @param wire_method the wire method to lookup fees for + * @param start_time starting time of fee + * @param end_time end time of fee + * @param[out] fees wire fees for that time period; if + * different fees exists within this time + * period, an 'invalid' amount is returned. + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_wire_fee_by_time (struct EXCHANGEDB_PostgresContext *ctx, + const char *wire_method, + struct GNUNET_TIME_Timestamp start_time, + struct GNUNET_TIME_Timestamp end_time, + struct TALER_WireFeeSet *fees); + +/** + * Lookup information about known wire fees. Finds all applicable + * fees in the given range. If they are identical, returns the + * respective @a fees. If any of the fees + * differ between @a start_time and @a end_time, the transaction + * succeeds BUT returns an invalid amount for both fees. + * + * @param cls closure + * @param wire_method the wire method to lookup fees for + * @param start_time starting time of fee + * @param end_time end time of fee + * @param[out] fees wire fees for that time period; if + * different fees exists within this time + * period, an 'invalid' amount is returned. + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_wire_fee_by_time (struct EXCHANGEDB_PostgresContext *ctx, + const char *wire_method, + struct GNUNET_TIME_Timestamp start_time, + struct GNUNET_TIME_Timestamp end_time, + struct TALER_WireFeeSet *fees); + +#endif diff --git a/src/include/taler/exchange-database/lookup_wire_timestamp.h b/src/include/taler/exchange-database/lookup_wire_timestamp.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_wire_timestamp.h + * @brief implementation of the lookup_wire_timestamp function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_WIRE_TIMESTAMP_H +#define EXCHANGE_DATABASE_LOOKUP_WIRE_TIMESTAMP_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_wire_timestamp (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + struct GNUNET_TIME_Timestamp *last_date); + +#endif diff --git a/src/include/taler/exchange-database/lookup_wire_transfer.h b/src/include/taler/exchange-database/lookup_wire_transfer.h @@ -0,0 +1,79 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/lookup_wire_transfer.h + * @brief implementation of the lookup_wire_transfer function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_LOOKUP_WIRE_TRANSFER_H +#define EXCHANGE_DATABASE_LOOKUP_WIRE_TRANSFER_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with the results of the lookup of the + * transaction data associated with a wire transfer identifier. + * + * @param cls closure + * @param rowid which row in the table is the information from (for diagnostics) + * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls) + * @param account_payto_uri which account did the transfer go to? + * @param h_payto hash over @a account_payto_uri as it is in the DB + * @param exec_time execution time of the wire transfer (should be same for all callbacks with the same @e cls) + * @param h_contract_terms which proposal was this payment about + * @param denom_pub denomination of @a coin_pub + * @param coin_pub which public key was this payment about + * @param coin_value amount contributed by this coin in total (with fee) + * @param coin_fee applicable fee for this coin + */ +typedef void +(*TALER_EXCHANGEDB_AggregationDataCallback)( + void *cls, + uint64_t rowid, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_FullPayto account_payto_uri, + const struct TALER_FullPaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp exec_time, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *coin_value, + const struct TALER_Amount *coin_fee); + +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_lookup_wire_transfer (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_WireTransferIdentifierRawP *wtid, + TALER_EXCHANGEDB_AggregationDataCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/mark_refresh_reveal_success.h b/src/include/taler/exchange-database/mark_refresh_reveal_success.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/mark_refresh_reveal_success.h + * @brief Mark the successful reveal of a refresh in the database + * @author Özgür Kesim + */ +#ifndef EXCHANGE_DATABASE_MARK_REFRESH_REVEAL_SUCCESS_H +#define EXCHANGE_DATABASE_MARK_REFRESH_REVEAL_SUCCESS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Mark a refresh, given by the commitment, as successfully revealed. + * + * @param cls closure + * @param rc commitment for the refresh + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_mark_refresh_reveal_success (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_RefreshCommitmentP *rc); + +#endif diff --git a/src/include/taler/exchange-database/persist_kyc_attributes.h b/src/include/taler/exchange-database/persist_kyc_attributes.h @@ -0,0 +1,61 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/persist_kyc_attributes.h + * @brief implementation of the persist_kyc_attributes function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_PERSIST_KYC_ATTRIBUTES_H +#define EXCHANGE_DATABASE_PERSIST_KYC_ATTRIBUTES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Store KYC attribute data. + * + * @param cls closure + * @param process_row KYC process row to update + * @param h_payto account for which the attribute data is stored + * @param provider_name name of the provider that provided the attributes + * @param provider_account_id provider account ID + * @param provider_legitimization_id provider legitimization ID + * @param birthday birthdate of user, in days after 1990, or 0 if unknown or definitively adult + * @param expiration_time when does the data expire + * @param form_name name of the form from which the @a enc_attributes originate, can be NULL + * @param enc_attributes_size number of bytes in @a enc_attributes + * @param enc_attributes encrypted attribute data + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_persist_kyc_attributes (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t process_row, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_name, + const char *provider_account_id, + const char *provider_legitimization_id, + uint32_t birthday, + struct GNUNET_TIME_Absolute expiration_time, + const char *form_name, + size_t enc_attributes_size, + const void *enc_attributes); + + +#endif diff --git a/src/include/taler/exchange-database/persist_policy_details.h b/src/include/taler/exchange-database/persist_policy_details.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/persist_policy_details.h + * @brief implementation of the persist_policy_details function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_PERSIST_POLICY_DETAILS_H +#define EXCHANGE_DATABASE_PERSIST_POLICY_DETAILS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/* 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_persist_policy_details (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PolicyDetails *details, + uint64_t *policy_details_serial_id, + struct TALER_Amount *accumulated_total, + enum TALER_PolicyFulfillmentState *fulfillment_state); + +#endif diff --git a/src/include/taler/exchange-database/preflight.h b/src/include/taler/exchange-database/preflight.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/preflight.h + * @brief implementation of the preflight function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_PREFLIGHT_H +#define EXCHANGE_DATABASE_PREFLIGHT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Do a pre-flight check that we are not in an uncommitted transaction. + * If we are, try to commit the previous transaction and output a warning. + * Does not return anything, as we will continue regardless of the outcome. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @return #GNUNET_OK if everything is fine + * #GNUNET_NO if a transaction was rolled back + * #GNUNET_SYSERR on hard errors + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_preflight (struct EXCHANGEDB_PostgresContext *ctx); + +#endif diff --git a/src/include/taler/exchange-database/profit_drains_get_pending.h b/src/include/taler/exchange-database/profit_drains_get_pending.h @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/profit_drains_get_pending.h + * @brief implementation of the profit_drains_get_pending function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_PROFIT_DRAINS_GET_PENDING_H +#define EXCHANGE_DATABASE_PROFIT_DRAINS_GET_PENDING_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Get profit drain operation ready to execute. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param[out] serial set to serial ID of the entry + * @param[out] wtid set set to wire transfer ID to use + * @param[out] account_section set to account to drain + * @param[out] payto_uri set to account to wire funds to + * @param[out] request_timestamp set to time of the signature + * @param[out] amount set to amount to wire + * @param[out] master_sig set to signature affirming the operation + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_profit_drains_get_pending (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t *serial, + struct TALER_WireTransferIdentifierRawP *wtid, + char **account_section, + struct TALER_FullPayto *payto_uri, + struct GNUNET_TIME_Timestamp *request_timestamp, + struct TALER_Amount *amount, + struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/include/taler/exchange-database/profit_drains_set_finished.h b/src/include/taler/exchange-database/profit_drains_set_finished.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/profit_drains_set_finished.h + * @brief implementation of the profit_drains_set_finished function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_PROFIT_DRAINS_SET_FINISHED_H +#define EXCHANGE_DATABASE_PROFIT_DRAINS_SET_FINISHED_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Set profit drain operation to finished. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param serial serial ID of the entry to mark finished + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_profit_drains_set_finished (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial); + +#endif diff --git a/src/include/taler/exchange-database/release_revolving_shard.h b/src/include/taler/exchange-database/release_revolving_shard.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/release_revolving_shard.h + * @brief implementation of the release_revolving_shard function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_RELEASE_REVOLVING_SHARD_H +#define EXCHANGE_DATABASE_RELEASE_REVOLVING_SHARD_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to release a revolving shard + * back into the work pool. Clears the + * "completed" flag. + * + * @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 +EXCHANGEDB_release_revolving_shard (struct EXCHANGEDB_PostgresContext *ctx, + const char *job_name, + uint32_t start_row, + uint32_t end_row); + +#endif diff --git a/src/include/taler/exchange-database/reserves_get.h b/src/include/taler/exchange-database/reserves_get.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/reserves_get.h + * @brief implementation of the reserves_get function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_RESERVES_GET_H +#define EXCHANGE_DATABASE_RESERVES_GET_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Get the summary of a reserve. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @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 + * and expiration are then filled accordingly. + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_reserves_get (struct EXCHANGEDB_PostgresContext *ctx, + struct TALER_EXCHANGEDB_Reserve *reserve); + +#endif diff --git a/src/include/taler/exchange-database/reserves_get_origin.h b/src/include/taler/exchange-database/reserves_get_origin.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/reserves_get_origin.h + * @brief implementation of the reserves_get_origin function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_RESERVES_GET_ORIGIN_H +#define EXCHANGE_DATABASE_RESERVES_GET_ORIGIN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @param[out] payto_uri set to the wire source payto://-URI + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_reserves_get_origin (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_FullPaytoHashP *h_payto, + struct TALER_FullPayto *payto_uri); + +#endif diff --git a/src/include/taler/exchange-database/reserves_in_insert.h b/src/include/taler/exchange-database/reserves_in_insert.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/reserves_in_insert.h + * @brief implementation of the reserves_in_insert function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_RESERVES_IN_INSERT_H +#define EXCHANGE_DATABASE_RESERVES_IN_INSERT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert an incoming transaction into reserves. New reserves are also + * created through this function. Runs its own transaction(s). + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param reserves array of reserves to insert + * @param reserves_length length of the @a reserves array + * @param[out] results set to query status per reserve, must be of length @a reserves_length + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_reserves_in_insert (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_ReserveInInfo *reserves, + unsigned int reserves_length, + enum GNUNET_DB_QueryStatus *results); + + +#endif diff --git a/src/include/taler/exchange-database/reserves_update.h b/src/include/taler/exchange-database/reserves_update.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/reserves_update.h + * @brief implementation of the reserves_update function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_RESERVES_UPDATE_H +#define EXCHANGE_DATABASE_RESERVES_UPDATE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Updates a reserve with the data from the given reserve structure. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param reserve the reserve structure whose data will be used to update the + * corresponding record in the database. + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_reserves_update (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_EXCHANGEDB_Reserve *reserve); + +#endif diff --git a/src/include/taler/exchange-database/rollback.h b/src/include/taler/exchange-database/rollback.h @@ -0,0 +1,38 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/rollback.h + * @brief implementation of the rollback function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_ROLLBACK_H +#define EXCHANGE_DATABASE_ROLLBACK_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Roll back the current transaction of a database connection. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + */ +void +EXCHANGEDB_rollback (struct EXCHANGEDB_PostgresContext *ctx); + +#endif diff --git a/src/include/taler/exchange-database/select_account_merges_above_serial_id.h b/src/include/taler/exchange-database/select_account_merges_above_serial_id.h @@ -0,0 +1,84 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_account_merges_above_serial_id.h + * @brief implementation of the select_account_merges_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_ACCOUNT_MERGES_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_ACCOUNT_MERGES_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about + * account merge requests that have been made, with + * the goal of auditing the account merge execution. + * + * @param cls closure + * @param rowid unique serial ID for the deposit in our DB + * @param reserve_pub reserve affected by the merge + * @param purse_pub purse being merged + * @param h_contract_terms hash over contract of the purse + * @param purse_expiration when would the purse expire + * @param amount total amount in the purse + * @param min_age minimum age of all coins deposited into the purse + * @param flags how was the purse created + * @param purse_fee if a purse fee was paid, how high is it + * @param merge_timestamp when was the merge approved + * @param reserve_sig signature by reserve approving the merge + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_AccountMergeCallback)( + void *cls, + uint64_t rowid, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PrivateContractHashP *h_contract_terms, + struct GNUNET_TIME_Timestamp purse_expiration, + const struct TALER_Amount *amount, + uint32_t min_age, + enum TALER_WalletAccountMergeFlags flags, + const struct TALER_Amount *purse_fee, + struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_ReserveSignatureP *reserve_sig); + +/** + * Select account merges above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_account_merges_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_AccountMergeCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_aggregation_amounts_for_kyc_check.h b/src/include/taler/exchange-database/select_aggregation_amounts_for_kyc_check.h @@ -0,0 +1,140 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_aggregation_amounts_for_kyc_check.h + * @brief implementation of the select_aggregation_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_AGGREGATION_AMOUNTS_FOR_KYC_CHECK_H +#define EXCHANGE_DATABASE_SELECT_AGGREGATION_AMOUNTS_FOR_KYC_CHECK_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Information per Clause-Schnorr (CS) fresh coin to + * be persisted for idempotency during refreshes-reveal. + */ +struct TALER_EXCHANGEDB_CsRevealFreshCoinData +{ + /** + * Denomination of the fresh coin. + */ + struct TALER_DenominationHashP new_denom_pub_hash; + + /** + * Blind signature of the fresh coin (possibly updated + * in case if a replay!). + */ + struct TALER_BlindedDenominationSignature bsig; + + /** + * Offset of the fresh coin in the reveal operation. + * (May not match the array offset as we may have + * a mixture of RSA and CS coins being created, and + * this request is only made for the CS subset). + */ + uint32_t coin_off; +}; + + +/** + * Generic KYC status for some operation. + */ +struct TALER_EXCHANGEDB_KycStatus +{ + + /** + * Account public key that is currently associated + * with the account. Only set if @e have_account_pub + * is true. + */ + union TALER_AccountPublicKeyP account_pub; + + /** + * Number that identifies the KYC requirement the operation + * was about. + */ + uint64_t requirement_row; + + /** + * True if @e account_pub is set. + */ + bool have_account_pub; + + /** + * True if the KYC status is "satisfied". + */ + bool ok; + +}; + + +struct TALER_EXCHANGEDB_ReserveInInfo +{ + const struct TALER_ReservePublicKeyP *reserve_pub; + const struct TALER_Amount *balance; + struct GNUNET_TIME_Timestamp execution_time; + struct TALER_FullPayto sender_account_details; + const char *exchange_account_name; + uint64_t wire_reference; +}; + + +/** + * Function called on each @a amount that was found to + * be relevant for a KYC check. + * + * @param cls closure to allow the KYC module to + * total up amounts and evaluate rules + * @param amount encountered transaction amount + * @param date when was the amount encountered + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to abort iteration + * #GNUNET_SYSERR on internal error (also abort itaration) + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_KycAmountCallback)( + void *cls, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Absolute date); + +/** + * Call @a kac on deposited amounts after @a time_limit which are relevant for a + * KYC trigger for a the (credited) account identified by @a h_payto. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_payto account identifier + * @param time_limit oldest transaction that could be relevant + * @param kac function to call for each applicable amount, in reverse chronological order (or until @a kac aborts by returning anything except #GNUNET_OK). + * @param kac_cls closure for @a kac + * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aggregation_amounts_for_kyc_check (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_aggregation_transient.h b/src/include/taler/exchange-database/select_aggregation_transient.h @@ -0,0 +1,50 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_aggregation_transient.h + * @brief implementation of the select_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_AGGREGATION_TRANSIENT_H +#define EXCHANGE_DATABASE_SELECT_AGGREGATION_TRANSIENT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 merchant_pub public key of the merchant receiving the transfer + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const char *exchange_account_section, + struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_Amount *total); + + +#endif diff --git a/src/include/taler/exchange-database/select_aggregations_above_serial.h b/src/include/taler/exchange-database/select_aggregations_above_serial.h @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_aggregations_above_serial.h + * @brief implementation of the select_aggregations_above_serial function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_AGGREGATIONS_ABOVE_SERIAL_H +#define EXCHANGE_DATABASE_SELECT_AGGREGATIONS_ABOVE_SERIAL_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called on aggregations that were done for + * a (batch) deposit. + * + * @param cls closure + * @param amount affected amount + * @param tracking_serial_id where in the table are we + * @param batch_deposit_serial_id which batch deposit was aggregated + */ +typedef void +(*TALER_EXCHANGEDB_AggregationCallback)( + void *cls, + const struct TALER_Amount *amount, + uint64_t tracking_serial_id, + uint64_t batch_deposit_serial_id); + +/** + * Select all aggregation tracking IDs in the database + * above a given @a min_tracking_serial_id. + * + * @param cls closure + * @param min_tracking_serial_id only return entries strictly above this row (and in order) + * @param cb function to call on all such aggregations + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aggregations_above_serial (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t min_tracking_serial_id, + TALER_EXCHANGEDB_AggregationCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_all_kyc_attributes.h b/src/include/taler/exchange-database/select_all_kyc_attributes.h @@ -0,0 +1,75 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_all_kyc_attributes.h + * @brief implementation of the select_all_kyc_attributes function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_ALL_KYC_ATTRIBUTES_H +#define EXCHANGE_DATABASE_SELECT_ALL_KYC_ATTRIBUTES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Return KYC attribute information. + * + * @param cls closure + * @param row_id current row in kyc_attributes table + * @param h_payto account the attributes are about + * @param provider_name name of the provider that collected the attributes + * @param collection_time when were the attributes collected + * @param expiration_time when does the data expire + * @param properties properties that were set for @a h_payto + * @param enc_attributes_size size of @a enc_attributes + * @param enc_attributes the encrypted collected attributes + * @return true to continue to iterate + */ +typedef bool +(*TALER_EXCHANGEDB_AllAttributesCallback)( + void *cls, + uint64_t row_id, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_name, + struct GNUNET_TIME_Timestamp collection_time, + struct GNUNET_TIME_Timestamp expiration_time, + const json_t *properties, + size_t enc_attributes_size, + const void *enc_attributes); + +/** + * Lookup all KYC attributes above @a min_row_id. + * + * @param cls closure + * @param min_row_id minimum row ID to return (exclusive) + * @param cb callback to invoke on each match + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_all_kyc_attributes (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t min_row_id, + TALER_EXCHANGEDB_AllAttributesCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_all_purse_decisions_above_serial_id.h b/src/include/taler/exchange-database/select_all_purse_decisions_above_serial_id.h @@ -0,0 +1,68 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_all_purse_decisions_above_serial_id.h + * @brief implementation of the select_all_purse_decisions_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_ALL_PURSE_DECISIONS_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_ALL_PURSE_DECISIONS_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about purse decisions that have been made, with + * the goal of auditing the purse's execution. + * + * @param cls closure + * @param rowid unique serial ID for the deposit in our DB + * @param purse_pub public key of the purse + * @param refunded true if decision was to refund + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_AllPurseDecisionCallback)( + void *cls, + uint64_t rowid, + const struct TALER_PurseContractPublicKeyP *purse_pub, + bool refunded); + +/** + * Select purse decisions above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_all_purse_decisions_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_AllPurseDecisionCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_all_purse_deletions_above_serial_id.h b/src/include/taler/exchange-database/select_all_purse_deletions_above_serial_id.h @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_all_purse_deletions_above_serial_id.h + * @brief implementation of the select_all_purse_deletions_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_ALL_PURSE_DELETIONS_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_ALL_PURSE_DELETIONS_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about purse deletions that have been made, with + * the goal of auditing the purse's execution. + * + * @param cls closure + * @param rowid unique serial ID for the deposit in our DB + * @param purse_pub public key of the purse + * @param purse_sig signature affirming deletion of the purse + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_AllPurseDeletionsCallback)( + void *cls, + uint64_t rowid, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig); + +/** + * Select all purse deletions above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_all_purse_deletions_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_AllPurseDeletionsCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_aml_attributes.h b/src/include/taler/exchange-database/select_aml_attributes.h @@ -0,0 +1,76 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_aml_attributes.h + * @brief implementation of the select_aml_attributes function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_AML_ATTRIBUTES_H +#define EXCHANGE_DATABASE_SELECT_AML_ATTRIBUTES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Return AML attribute information. + * + * @param cls closure + * @param row_id current row in kyc_attributes table + * @param collection_time when were the attributes collected + * @param by_aml_officer true if the data was filed by an AML officer + * @param officer_name name of the officer, NULL if not @a by_aml_officer + * @param enc_attributes_size size of @a enc_attributes + * @param enc_attributes the encrypted collected attributes + */ +typedef void +(*TALER_EXCHANGEDB_AmlAttributeCallback)( + void *cls, + uint64_t row_id, + struct GNUNET_TIME_Timestamp collection_time, + bool by_aml_officer, + const char *officer_name, + size_t enc_attributes_size, + const void *enc_attributes); + +/** + * Lookup AML attributes of a particular account. + * + * @param cls closure + * @param h_payto which account should we return attributes for + * @param offset row to start from + * @param limit how many records to return (negative + * to go back in time, positive to go forward) + * @param cb callback to invoke on each match + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aml_attributes (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlAttributeCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_aml_decisions.h b/src/include/taler/exchange-database/select_aml_decisions.h @@ -0,0 +1,90 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_aml_decisions.h + * @brief implementation of the select_aml_decisions function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_AML_DECISIONS_H +#define EXCHANGE_DATABASE_SELECT_AML_DECISIONS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Return AML decision information. + * + * @param cls closure + * @param row_id current row in legitimization outcomes table + * @param justification human-readable reason for the decision, NULL if none is available + * @param h_payto account for which the attribute data is stored + * @param decision_time when was the decision taken + * @param expiration_time when will the rules expire + * @param jproperties properties set for the account, + * NULL if no properties were set + * @param to_investigate true if AML staff should look at the account + * @param is_active true if this is the currently active decision about the account + * @param is_wallet true if the @a h_payto is for a Taler wallet + * @param payto payto URI of the account the decision is about + * @param account_rules current active rules for the account + */ +typedef void +(*TALER_EXCHANGEDB_AmlDecisionCallback)( + void *cls, + uint64_t row_id, + const char *justification, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp decision_time, + struct GNUNET_TIME_Absolute expiration_time, + const json_t *jproperties, + bool to_investigate, + bool is_active, + bool is_wallet, + struct TALER_FullPayto payto, + const json_t *account_rules); + +/** + * Lookup AML decisions that have a particular state. + * + * @param cls closure + * @param h_payto which account should we return the AML decision history for, NULL to return all accounts + * @param investigation_only filter by investigation state + * @param active_only filter for only active states + * @param offset row to start from + * @param limit how many records to return (negative + * to go back in time, positive to go forward) + * @param cb callback to invoke on each match + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aml_decisions (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + enum TALER_EXCHANGE_YesNoAll investigation_only, + enum TALER_EXCHANGE_YesNoAll active_only, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlDecisionCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_aml_measures.h b/src/include/taler/exchange-database/select_aml_measures.h @@ -0,0 +1,76 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_aml_measures.h + * @brief implementation of the select_aml_measures function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_AML_MEASURES_H +#define EXCHANGE_DATABASE_SELECT_AML_MEASURES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with legitimization measures. + * + * @param cls closure + * @param h_payto hash of account the measure applies to + * @param start_time when was the process started + * @param jmeasures object of type ``LegitimizationMeasures`` + * @param is_finished true if the measure was finished + * @param measure_serial_id row ID of the measure in the exchange table + */ +typedef void +(*TALER_EXCHANGEDB_LegitimizationMeasureCallback) ( + void *cls, + struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute start_time, + const json_t *jmeasures, + bool is_finished, + uint64_t measure_serial_id); + +/** + * Lookup legitimization measures. + * + * @param cls closure + * @param h_payto account for which the attribute data is stored, + * NULL to select for all accounts + * @param active_only select only measures that are active + * @param offset row offset to select from + * @param limit number of results to return, negative to + * return in descending order from @a offset + * @param cb callback to invoke on each match + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aml_measures (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + enum TALER_EXCHANGE_YesNoAll active_only, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_LegitimizationMeasureCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_aml_statistics.h b/src/include/taler/exchange-database/select_aml_statistics.h @@ -0,0 +1,68 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_aml_statistics.h + * @brief implementation of the select_aml_statistics function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_AML_STATISTICS_H +#define EXCHANGE_DATABASE_SELECT_AML_STATISTICS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with AML statistics (counters). + * + * @param cls closure + * @param name name of the counter + * @param cnt number of events for @a name in the query range + */ +typedef void +(*TALER_EXCHANGEDB_AmlStatisticsCallback)( + void *cls, + const char *name, + uint64_t cnt); + +/** + * Obtain the AML statistics for a given set of @a names and + * timeframe. + * + * @param cls closure + * @param num_names length of the @e names array + * @param names array of names of the statistics to fetch + * @param start_date start of time range + * @param end_date end of time range + * @param cb function to call on each statistic + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_aml_statistics (struct EXCHANGEDB_PostgresContext *ctx, + size_t num_names, + const char *names[static num_names], + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + TALER_EXCHANGEDB_AmlStatisticsCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_auditor_denom_sig.h b/src/include/taler/exchange-database/select_auditor_denom_sig.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_auditor_denom_sig.h + * @brief implementation of the select_auditor_denom_sig function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_AUDITOR_DENOM_SIG_H +#define EXCHANGE_DATABASE_SELECT_AUDITOR_DENOM_SIG_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_auditor_denom_sig (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_AuditorPublicKeyP *auditor_pub, + struct TALER_AuditorSignatureP *auditor_sig); + +#endif diff --git a/src/include/taler/exchange-database/select_batch_deposits_missing_wire.h b/src/include/taler/exchange-database/select_batch_deposits_missing_wire.h @@ -0,0 +1,66 @@ +/* + This file is part of TALER + Copyright (C) 2022-2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_batch_deposits_missing_wire.h + * @brief implementation of the select_batch_deposits_missing_wire function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_BATCH_DEPOSITS_MISSING_WIRE_H +#define EXCHANGE_DATABASE_SELECT_BATCH_DEPOSITS_MISSING_WIRE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called on (batch) deposits will need a wire + * transfer. + * + * @param cls closure + * @param batch_deposit_serial_id where in the table are we + * @param total_amount value of all missing deposits, including fees + * @param wire_target_h_payto hash of the recipient account's payto URI + * @param deadline what was the earliest requested wire transfer deadline + */ +typedef void +(*TALER_EXCHANGEDB_WireMissingCallback)( + void *cls, + uint64_t batch_deposit_serial_id, + const struct TALER_Amount *total_amount, + const struct TALER_FullPaytoHashP *wire_target_h_payto, + struct GNUNET_TIME_Timestamp deadline); + +/** + * Select all of those batch deposits in the database + * above the given serial ID. + * + * @param cls closure + * @param min_batch_deposit_serial_id select all batch deposits above this ID + * @param cb function to call on all such deposits + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_batch_deposits_missing_wire (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t min_batch_deposit_serial_id, + TALER_EXCHANGEDB_WireMissingCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_coin_deposits_above_serial_id.h b/src/include/taler/exchange-database/select_coin_deposits_above_serial_id.h @@ -0,0 +1,69 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_coin_deposits_above_serial_id.h + * @brief implementation of the select_coin_deposits_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_COIN_DEPOSITS_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_COIN_DEPOSITS_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about deposits that have been made, + * with the goal of auditing the deposit's execution. + * + * @param cls closure + * @param rowid unique serial ID for the deposit in our DB + * @param exchange_timestamp when did the deposit happen + * @param deposit deposit details + * @param denom_pub denomination public key of @a coin_pub + * @param done flag set if the deposit was already executed (or not) + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_DepositCallback)( + void *cls, + uint64_t rowid, + struct GNUNET_TIME_Timestamp exchange_timestamp, + const struct TALER_EXCHANGEDB_Deposit *deposit, + const struct TALER_DenominationPublicKey *denom_pub, + bool done); + +/** + * Select deposits above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_coin_deposits_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_DepositCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_contract.h b/src/include/taler/exchange-database/select_contract.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_contract.h + * @brief implementation of the select_contract function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_CONTRACT_H +#define EXCHANGE_DATABASE_SELECT_CONTRACT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to retrieve an encrypted contract. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub key to lookup the contract by + * @param[out] pub_ckey set to the ephemeral DH used to encrypt the contract + * @param[out] econtract_sig set to the signature over the encrypted contract + * @param[out] econtract_size set to the number of bytes in @a econtract + * @param[out] econtract set to the encrypted contract on success, to be freed by the caller + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_contract (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ContractDiffiePublicP *pub_ckey, + struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseContractSignatureP *econtract_sig, + size_t *econtract_size, + void **econtract); + +#endif diff --git a/src/include/taler/exchange-database/select_contract_by_purse.h b/src/include/taler/exchange-database/select_contract_by_purse.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_contract_by_purse.h + * @brief implementation of the select_contract_by_purse function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_CONTRACT_BY_PURSE_H +#define EXCHANGE_DATABASE_SELECT_CONTRACT_BY_PURSE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to retrieve an encrypted contract. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub key to lookup the contract by + * @param[out] econtract set to the encrypted contract on success, to be freed by the caller + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_contract_by_purse (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_EncryptedContract *econtract); + +#endif diff --git a/src/include/taler/exchange-database/select_deposit_amounts_for_kyc_check.h b/src/include/taler/exchange-database/select_deposit_amounts_for_kyc_check.h @@ -0,0 +1,143 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_deposit_amounts_for_kyc_check.h + * @brief implementation of the select_deposit_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_DEPOSIT_AMOUNTS_FOR_KYC_CHECK_H +#define EXCHANGE_DATABASE_SELECT_DEPOSIT_AMOUNTS_FOR_KYC_CHECK_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Information per Clause-Schnorr (CS) fresh coin to + * be persisted for idempotency during refreshes-reveal. + */ +struct TALER_EXCHANGEDB_CsRevealFreshCoinData +{ + /** + * Denomination of the fresh coin. + */ + struct TALER_DenominationHashP new_denom_pub_hash; + + /** + * Blind signature of the fresh coin (possibly updated + * in case if a replay!). + */ + struct TALER_BlindedDenominationSignature bsig; + + /** + * Offset of the fresh coin in the reveal operation. + * (May not match the array offset as we may have + * a mixture of RSA and CS coins being created, and + * this request is only made for the CS subset). + */ + uint32_t coin_off; +}; + + +/** + * Generic KYC status for some operation. + */ +struct TALER_EXCHANGEDB_KycStatus +{ + + /** + * Account public key that is currently associated + * with the account. Only set if @e have_account_pub + * is true. + */ + union TALER_AccountPublicKeyP account_pub; + + /** + * Number that identifies the KYC requirement the operation + * was about. + */ + uint64_t requirement_row; + + /** + * True if @e account_pub is set. + */ + bool have_account_pub; + + /** + * True if the KYC status is "satisfied". + */ + bool ok; + +}; + + +struct TALER_EXCHANGEDB_ReserveInInfo +{ + const struct TALER_ReservePublicKeyP *reserve_pub; + const struct TALER_Amount *balance; + struct GNUNET_TIME_Timestamp execution_time; + struct TALER_FullPayto sender_account_details; + const char *exchange_account_name; + uint64_t wire_reference; +}; + + +/** + * Function called on each @a amount that was found to + * be relevant for a KYC check. + * + * @param cls closure to allow the KYC module to + * total up amounts and evaluate rules + * @param amount encountered transaction amount + * @param date when was the amount encountered + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to abort iteration + * #GNUNET_SYSERR on internal error (also abort itaration) + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_KycAmountCallback)( + void *cls, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Absolute date); + +/** + * Call @a kac on deposited amounts after @a time_limit which are relevant for a + * KYC trigger for a merchant identified by @a h_payto. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_payto account identifier + * @param time_limit oldest transaction that could be relevant + * @param kac function to call for each applicable amount, + * in reverse chronological order (or until @a kac aborts + * by returning anything except #GNUNET_OK). + * @param kac_cls closure for @a kac + * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_deposit_amounts_for_kyc_check (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_exchange_credit_transfers.h b/src/include/taler/exchange-database/select_exchange_credit_transfers.h @@ -0,0 +1,72 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_exchange_credit_transfers.h + * @brief implementation of the select_exchange_credit_transfers function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_EXCHANGE_CREDIT_TRANSFERS_H +#define EXCHANGE_DATABASE_SELECT_EXCHANGE_CREDIT_TRANSFERS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Callback that is given AML-relevant transfer data. + * + * @param cls closure + * @param row_id current row in AML status table + * @param payto_uri account involved with the wire transfer + * @param execution_time when was the transfer made + * @param amount wire amount of the transfer + */ +typedef void +(*TALER_EXCHANGEDB_AmlTransferCallback)( + void *cls, + uint64_t row_id, + const char *payto_uri, + struct GNUNET_TIME_Absolute execution_time, + const struct TALER_Amount *amount); + +/** + * Return AML-relevant wire transfer credit data. + * + * @param cls closure + * @param threshold minimum wire amount to return data for + * @param offset offset in table to filter by + * @param limit maximum number of entries to return, negative for descending + * @param h_payto account to filter transfer data by + * @param cb function to call on each result + * @param cb_cls closure to pass to @a cb + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_exchange_credit_transfers (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_exchange_debit_transfers.h b/src/include/taler/exchange-database/select_exchange_debit_transfers.h @@ -0,0 +1,72 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_exchange_debit_transfers.h + * @brief implementation of the select_exchange_debit_transfers function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_EXCHANGE_DEBIT_TRANSFERS_H +#define EXCHANGE_DATABASE_SELECT_EXCHANGE_DEBIT_TRANSFERS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Callback that is given AML-relevant transfer data. + * + * @param cls closure + * @param row_id current row in AML status table + * @param payto_uri account involved with the wire transfer + * @param execution_time when was the transfer made + * @param amount wire amount of the transfer + */ +typedef void +(*TALER_EXCHANGEDB_AmlTransferCallback)( + void *cls, + uint64_t row_id, + const char *payto_uri, + struct GNUNET_TIME_Absolute execution_time, + const struct TALER_Amount *amount); + +/** + * Return AML-relevant wire transfer debit data. + * + * @param cls closure + * @param threshold minimum wire amount to return data for + * @param offset offset in table to filter by + * @param limit maximum number of entries to return, negative for descending + * @param h_payto account to filter transfer data by + * @param cb function to call on each result + * @param cb_cls closure to pass to @a cb + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_exchange_debit_transfers (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_exchange_kycauth_transfers.h b/src/include/taler/exchange-database/select_exchange_kycauth_transfers.h @@ -0,0 +1,72 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_exchange_kycauth_transfers.h + * @brief implementation of the select_exchange_kycauth_transfers function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_EXCHANGE_KYCAUTH_TRANSFERS_H +#define EXCHANGE_DATABASE_SELECT_EXCHANGE_KYCAUTH_TRANSFERS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Callback that is given AML-relevant transfer data. + * + * @param cls closure + * @param row_id current row in AML status table + * @param payto_uri account involved with the wire transfer + * @param execution_time when was the transfer made + * @param amount wire amount of the transfer + */ +typedef void +(*TALER_EXCHANGEDB_AmlTransferCallback)( + void *cls, + uint64_t row_id, + const char *payto_uri, + struct GNUNET_TIME_Absolute execution_time, + const struct TALER_Amount *amount); + +/** + * Return wire transfer kycauth data. + * + * @param cls closure + * @param threshold minimum wire amount to return data for + * @param offset offset in table to filter by + * @param limit maximum number of entries to return, negative for descending + * @param h_payto account to filter transfer data by + * @param cb function to call on each result + * @param cb_cls closure to pass to @a cb + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_exchange_kycauth_transfers (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_Amount *threshold, + uint64_t offset, + int64_t limit, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_AmlTransferCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_kyc_accounts.h b/src/include/taler/exchange-database/select_kyc_accounts.h @@ -0,0 +1,86 @@ +/* + This file is part of TALER + Copyright (C) 2025 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_kyc_accounts.h + * @brief implementation of the select_kyc_accounts function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_KYC_ACCOUNTS_H +#define EXCHANGE_DATABASE_SELECT_KYC_ACCOUNTS_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Return account summary information. + * + * @param cls closure + * @param row_id current row in AML status table + * @param h_payto account for which the attribute data is stored + * @param open_time when was the account opened formally, + * GNUNET_TIME_UNIT_FOREVER_TS if it was never opened + * @param close_time when was the account formally closed, + * GNUNET_TIME_UNIT_ZERO_TS if it was never closed + * @param comments comments on the account + * @param high_risk is this a high-risk business relationship + * @param to_investigate TRUE if this account should be investigated + * @param payto the payto URI of the account + */ +typedef void +(*TALER_EXCHANGEDB_AmlAccountListCallback)( + void *cls, + uint64_t row_id, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp open_time, + struct GNUNET_TIME_Timestamp close_time, + const char *comments, + bool high_risk, + bool to_investigate, + struct TALER_FullPayto payto); + +/** + * List accounts managed by the exchange (for AML/KYC). + * + * @param cls closure + * @param investigation_only filter by investigation state + * @param open_only filter for only open accounts + * @param high_risk_only filter for only high-risk accounts + * @param offset row to start from + * @param limit how many records to return (negative + * to go back in time, positive to go forward) + * @param cb callback to invoke on each match + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_kyc_accounts (struct EXCHANGEDB_PostgresContext *ctx, + enum TALER_EXCHANGE_YesNoAll investigation_only, + enum TALER_EXCHANGE_YesNoAll open_only, + enum TALER_EXCHANGE_YesNoAll high_risk_only, + uint64_t offset, + int64_t limit, + TALER_EXCHANGEDB_AmlAccountListCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_kyc_attributes.h b/src/include/taler/exchange-database/select_kyc_attributes.h @@ -0,0 +1,70 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_kyc_attributes.h + * @brief implementation of the select_kyc_attributes function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_KYC_ATTRIBUTES_H +#define EXCHANGE_DATABASE_SELECT_KYC_ATTRIBUTES_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Callback with KYC attributes about a particular user. + * + * @param cls closure + * @param h_payto account for which the attribute data is stored + * @param provider_name provider that must be checked + * @param collection_time when was the data collected + * @param expiration_time when does the data expire + * @param enc_attributes_size number of bytes in @a enc_attributes + * @param enc_attributes encrypted attribute data + */ +typedef void +(*TALER_EXCHANGEDB_AttributeCallback)( + void *cls, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_name, + struct GNUNET_TIME_Timestamp collection_time, + struct GNUNET_TIME_Timestamp expiration_time, + size_t enc_attributes_size, + const void *enc_attributes); + +/** + * Lookup KYC attribute data for a specific account. + * + * @param cls closure + * @param h_payto account for which the attribute data is stored + * @param cb callback to invoke on each match + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_kyc_attributes (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + TALER_EXCHANGEDB_AttributeCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_merge_amounts_for_kyc_check.h b/src/include/taler/exchange-database/select_merge_amounts_for_kyc_check.h @@ -0,0 +1,139 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_merge_amounts_for_kyc_check.h + * @brief implementation of the select_merge_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_MERGE_AMOUNTS_FOR_KYC_CHECK_H +#define EXCHANGE_DATABASE_SELECT_MERGE_AMOUNTS_FOR_KYC_CHECK_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Information per Clause-Schnorr (CS) fresh coin to + * be persisted for idempotency during refreshes-reveal. + */ +struct TALER_EXCHANGEDB_CsRevealFreshCoinData +{ + /** + * Denomination of the fresh coin. + */ + struct TALER_DenominationHashP new_denom_pub_hash; + + /** + * Blind signature of the fresh coin (possibly updated + * in case if a replay!). + */ + struct TALER_BlindedDenominationSignature bsig; + + /** + * Offset of the fresh coin in the reveal operation. + * (May not match the array offset as we may have + * a mixture of RSA and CS coins being created, and + * this request is only made for the CS subset). + */ + uint32_t coin_off; +}; + + +/** + * Generic KYC status for some operation. + */ +struct TALER_EXCHANGEDB_KycStatus +{ + + /** + * Account public key that is currently associated + * with the account. Only set if @e have_account_pub + * is true. + */ + union TALER_AccountPublicKeyP account_pub; + + /** + * Number that identifies the KYC requirement the operation + * was about. + */ + uint64_t requirement_row; + + /** + * True if @e account_pub is set. + */ + bool have_account_pub; + + /** + * True if the KYC status is "satisfied". + */ + bool ok; + +}; + + +struct TALER_EXCHANGEDB_ReserveInInfo +{ + const struct TALER_ReservePublicKeyP *reserve_pub; + const struct TALER_Amount *balance; + struct GNUNET_TIME_Timestamp execution_time; + struct TALER_FullPayto sender_account_details; + const char *exchange_account_name; + uint64_t wire_reference; +}; + + +/** + * Function called on each @a amount that was found to + * be relevant for a KYC check. + * + * @param cls closure to allow the KYC module to + * total up amounts and evaluate rules + * @param amount encountered transaction amount + * @param date when was the amount encountered + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to abort iteration + * #GNUNET_SYSERR on internal error (also abort itaration) + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_KycAmountCallback)( + void *cls, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Absolute date); + +/** + * Call @a kac on merged reserve amounts after @a time_limit which are relevant for a + * KYC trigger for a the wallet identified by @a h_payto. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_payto account identifier + * @param time_limit oldest transaction that could be relevant + * @param kac function to call for each applicable amount, in reverse chronological order (or until @a kac aborts by returning anything except #GNUNET_OK). + * @param kac_cls closure for @a kac + * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_merge_amounts_for_kyc_check (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_purse.h b/src/include/taler/exchange-database/select_purse.h @@ -0,0 +1,58 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_purse.h + * @brief implementation of the select_purse function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_PURSE_H +#define EXCHANGE_DATABASE_SELECT_PURSE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to obtain information about a purse. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the new purse + * @param[out] purse_creation set to time when the purse was created + * @param[out] purse_expiration set to time when the purse will expire + * @param[out] amount set to target amount (with fees) to be put into the purse + * @param[out] deposited set to actual amount put into the purse so far + * @param[out] h_contract_terms set to hash of the contract for the purse + * @param[out] merge_timestamp set to time when the purse was merged, or NEVER if not + * @param[out] purse_deleted set to true if purse was deleted + * @param[out] purse_refunded set to true if purse was refunded + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp *purse_creation, + struct GNUNET_TIME_Timestamp *purse_expiration, + struct TALER_Amount *amount, + struct TALER_Amount *deposited, + struct TALER_PrivateContractHashP *h_contract_terms, + struct GNUNET_TIME_Timestamp *merge_timestamp, + bool *purse_deleted, + bool *purse_refunded); + +#endif diff --git a/src/include/taler/exchange-database/select_purse_by_merge_pub.h b/src/include/taler/exchange-database/select_purse_by_merge_pub.h @@ -0,0 +1,56 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_purse_by_merge_pub.h + * @brief implementation of the select_purse_by_merge_pub function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_PURSE_BY_MERGE_PUB_H +#define EXCHANGE_DATABASE_SELECT_PURSE_BY_MERGE_PUB_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to return meta data about a purse by the + * merge capability key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_by_merge_pub (struct EXCHANGEDB_PostgresContext *ctx, + 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); + +#endif diff --git a/src/include/taler/exchange-database/select_purse_decisions_above_serial_id.h b/src/include/taler/exchange-database/select_purse_decisions_above_serial_id.h @@ -0,0 +1,70 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_purse_decisions_above_serial_id.h + * @brief implementation of the select_purse_decisions_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_PURSE_DECISIONS_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_PURSE_DECISIONS_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about purse decisions that have been made, with + * the goal of auditing the purse's execution. + * + * @param cls closure + * @param rowid unique serial ID for the deposit in our DB + * @param purse_pub public key of the purse + * @param reserve_pub public key of the target reserve, NULL if not known / refunded + * @param purse_value what is the (target) value of the purse + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_PurseDecisionCallback)( + void *cls, + uint64_t rowid, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *purse_value); + +/** + * Select purse decisions above @a serial_id in monotonically increasing + * order. + * + * @param cls closure + * @param serial_id highest serial ID to exclude (select strictly larger) + * @param refunded which refund status to select for + * @param cb function to call on each result + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_decisions_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + bool refunded, + TALER_EXCHANGEDB_PurseDecisionCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_purse_deposits_above_serial_id.h b/src/include/taler/exchange-database/select_purse_deposits_above_serial_id.h @@ -0,0 +1,77 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_purse_deposits_above_serial_id.h + * @brief implementation of the select_purse_deposits_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_PURSE_DEPOSITS_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_PURSE_DEPOSITS_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about purse deposits that have been made, with + * the goal of auditing the deposit's execution. + * + * @param cls closure + * @param rowid unique serial ID for the deposit in our DB + * @param deposit deposit details + * @param reserve_pub which reserve is the purse merged into, NULL if unknown + * @param flags purse flags + * @param auditor_balance purse balance (according to the + * auditor during auditing) + * @param purse_total target amount the purse should reach + * @param denom_pub denomination public key of @a coin_pub + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_PurseDepositCallback)( + void *cls, + uint64_t rowid, + const struct TALER_EXCHANGEDB_PurseDeposit *deposit, + const struct TALER_ReservePublicKeyP *reserve_pub, + enum TALER_WalletAccountMergeFlags flags, + const struct TALER_Amount *auditor_balance, + const struct TALER_Amount *purse_total, + const struct TALER_DenominationPublicKey *denom_pub); + +/** + * Select deposits above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_deposits_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_PurseDepositCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_purse_deposits_by_purse.h b/src/include/taler/exchange-database/select_purse_deposits_by_purse.h @@ -0,0 +1,67 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_purse_deposits_by_purse.h + * @brief implementation of the select_purse_deposits_by_purse function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_PURSE_DEPOSITS_BY_PURSE_H +#define EXCHANGE_DATABASE_SELECT_PURSE_DEPOSITS_BY_PURSE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about purse refunds that have been made, with + * the goal of auditing the purse refund's execution. + * + * @param cls closure + * @param rowid row of the refund event + * @param amount_with_fee amount of the deposit into the purse + * @param coin_pub coin that is to be refunded the @a given amount_with_fee + * @param denom_pub denomination of @a coin_pub + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_PurseRefundCoinCallback)( + void *cls, + uint64_t rowid, + const struct TALER_Amount *amount_with_fee, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_DenominationPublicKey *denom_pub); + +/** + * Select coin affected by purse refund. + * + * @param cls closure + * @param purse_pub purse that was refunded + * @param cb function to call on each result + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_deposits_by_purse (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + TALER_EXCHANGEDB_PurseRefundCoinCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_purse_merge.h b/src/include/taler/exchange-database/select_purse_merge.h @@ -0,0 +1,52 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_purse_merge.h + * @brief implementation of the select_purse_merge function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_PURSE_MERGE_H +#define EXCHANGE_DATABASE_SELECT_PURSE_MERGE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to approve merging of a purse with + * an account, made by the receiving account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param purse_pub public key of the purse + * @param[out] merge_sig set to the signature confirming the merge + * @param[out] merge_timestamp set to the time of the merge + * @param[out] partner_url set to the URL of the target exchange, or NULL if the target exchange is us. To be freed by the caller. + * @param[out] reserve_pub set to the public key of the reserve/account being credited + * @param[out] refunded set to true if purse was refunded + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_merge (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseMergeSignatureP *merge_sig, + struct GNUNET_TIME_Timestamp *merge_timestamp, + char **partner_url, + struct TALER_ReservePublicKeyP *reserve_pub, + bool *refunded); + +#endif diff --git a/src/include/taler/exchange-database/select_purse_merges_above_serial_id.h b/src/include/taler/exchange-database/select_purse_merges_above_serial_id.h @@ -0,0 +1,82 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_purse_merges_above_serial_id.h + * @brief implementation of the select_purse_merges_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_PURSE_MERGES_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_PURSE_MERGES_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about purse + * merges that have been made, with + * the goal of auditing the purse merge execution. + * + * @param cls closure + * @param rowid unique serial ID for the deposit in our DB + * @param partner_base_url where is the reserve, NULL for this exchange + * @param amount total amount expected in the purse + * @param balance current balance in the purse (according to the auditor) + * @param flags purse flags + * @param merge_pub merge capability key + * @param reserve_pub reserve the merge affects + * @param merge_sig signature affirming the merge + * @param purse_pub purse key + * @param merge_timestamp when did the merge happen + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_PurseMergeCallback)( + void *cls, + uint64_t rowid, + const char *partner_base_url, + const struct TALER_Amount *amount, + const struct TALER_Amount *balance, + enum TALER_WalletAccountMergeFlags flags, + const struct TALER_PurseMergePublicKeyP *merge_pub, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_PurseMergeSignatureP *merge_sig, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp merge_timestamp); + +/** + * Select purse merges deposits above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_merges_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_PurseMergeCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_purse_requests_above_serial_id.h b/src/include/taler/exchange-database/select_purse_requests_above_serial_id.h @@ -0,0 +1,79 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_purse_requests_above_serial_id.h + * @brief implementation of the select_purse_requests_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_PURSE_REQUESTS_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_PURSE_REQUESTS_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called on purse requests. + * + * @param cls closure + * @param rowid purse request table row of the purse + * @param purse_pub public key of the purse + * @param merge_pub public key representing the merge capability + * @param purse_creation when was the purse created? + * @param purse_expiration when would an unmerged purse expire + * @param h_contract_terms contract associated with the purse + * @param age_limit the age limit for deposits into the purse + * @param target_amount amount to be put into the purse + * @param purse_sig signature of the purse over the initialization data + * @return #GNUNET_OK to continue to iterate + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_PurseRequestCallback)( + void *cls, + uint64_t rowid, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePublicKeyP *merge_pub, + struct GNUNET_TIME_Timestamp purse_creation, + struct GNUNET_TIME_Timestamp purse_expiration, + const struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t age_limit, + const struct TALER_Amount *target_amount, + const struct TALER_PurseContractSignatureP *purse_sig); + +/** + * Select purse requestss deposits above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_purse_requests_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_PurseRequestCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_recoup_above_serial_id.h b/src/include/taler/exchange-database/select_recoup_above_serial_id.h @@ -0,0 +1,74 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_recoup_above_serial_id.h + * @brief implementation of the select_recoup_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_RECOUP_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_RECOUP_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called about recoups the exchange has to perform. + * + * @param cls closure + * @param rowid row identifier used to uniquely identify the recoup operation + * @param timestamp when did we receive the recoup request + * @param amount how much should be added back to the reserve + * @param reserve_pub public key of the reserve + * @param coin public information about the coin + * @param denom_pub denomination key of @a coin + * @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP + * @param coin_blind blinding factor used to blind the coin + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_RecoupCallback)( + void *cls, + uint64_t rowid, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *amount, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_CoinPublicInfo *coin, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_CoinSpendSignatureP *coin_sig, + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind); + +/** + * Function called to select recoup requests the exchange + * received, 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_recoup_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_RecoupCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_recoup_refresh_above_serial_id.h b/src/include/taler/exchange-database/select_recoup_refresh_above_serial_id.h @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_recoup_refresh_above_serial_id.h + * @brief implementation of the select_recoup_refresh_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_RECOUP_REFRESH_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_RECOUP_REFRESH_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called about recoups on refreshed coins the exchange has to + * perform. + * + * @param cls closure + * @param rowid row identifier used to uniquely identify the recoup operation + * @param timestamp when did we receive the recoup request + * @param amount how much should be added back to the old coin + * @param old_coin_pub original coin that was refreshed to create @a coin + * @param old_denom_pub_hash hash of public key of @a old_coin_pub + * @param coin public information about the fresh coin + * @param denom_pub denomination key of @a coin + * @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP + * @param coin_blind blinding factor used to blind the coin + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_RecoupRefreshCallback)( + void *cls, + uint64_t rowid, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendPublicKeyP *old_coin_pub, + const struct TALER_DenominationHashP *old_denom_pub_hash, + const struct TALER_CoinPublicInfo *coin, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_CoinSpendSignatureP *coin_sig, + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind); + +/** + * Function called to select recoup requests the exchange received for + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_recoup_refresh_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_RecoupRefreshCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_refreshes_above_serial_id.h b/src/include/taler/exchange-database/select_refreshes_above_serial_id.h @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_refreshes_above_serial_id.h + * @brief implementation of the select_refreshes_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_REFRESHES_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_REFRESHES_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about coins that were melted, + * with the goal of auditing the refresh's execution. + * + * @param cls closure + * @param rowid unique serial ID for the refresh session in our DB + * @param old_denom_pub denomination public key of @a coin_pub + * @param coin_pub public key of the coin + * @param coin_sig signature from the coin + * @param h_age_commitment hash of the age commitment for the coin + * @param amount_with_fee amount that was deposited including fee + * @param num_nds length of the @a new_denom_serials array + * @param new_denom_serials array of denomination serials of fresh coins + * @param rc what the refresh commitment + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_RefreshesCallback)( + void *cls, + uint64_t rowid, + const struct TALER_DenominationPublicKey *old_denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendSignatureP *coin_sig, + const struct TALER_AgeCommitmentHashP *h_age_commitment, + const struct TALER_Amount *amount_with_fee, + size_t num_nds, + uint64_t new_denom_serials[static num_nds], + const struct TALER_RefreshCommitmentP *rc); + +/** + * Select refresh sessions above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_refreshes_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_RefreshesCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_refunds_above_serial_id.h b/src/include/taler/exchange-database/select_refunds_above_serial_id.h @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_refunds_above_serial_id.h + * @brief implementation of the select_refunds_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_REFUNDS_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_REFUNDS_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about coins that were refunding, + * with the goal of auditing the refund's execution. + * + * @param cls closure + * @param rowid unique serial ID for the refund in our DB + * @param denom_pub denomination public key of @a coin_pub + * @param coin_pub public key of the coin + * @param merchant_pub public key of the merchant + * @param merchant_sig signature of the merchant + * @param h_contract_terms hash of the proposal data known to merchant and customer + * @param rtransaction_id refund transaction ID chosen by the merchant + * @param full_refund true if the refunds total up to the entire value of the deposit + * @param amount_with_fee amount that was deposited including fee + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_RefundCallback)( + void *cls, + uint64_t rowid, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_MerchantSignatureP *merchant_sig, + const struct TALER_PrivateContractHashP *h_contract_terms, + uint64_t rtransaction_id, + bool full_refund, + const struct TALER_Amount *amount_with_fee); + +/** + * Select refunds above @a serial_id 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_refunds_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_RefundCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_refunds_by_coin.h b/src/include/taler/exchange-database/select_refunds_by_coin.h @@ -0,0 +1,65 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_refunds_by_coin.h + * @brief implementation of the select_refunds_by_coin function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_REFUNDS_BY_COIN_H +#define EXCHANGE_DATABASE_SELECT_REFUNDS_BY_COIN_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Callback invoked with information about refunds applicable + * to a particular coin and contract. + * + * @param cls closure + * @param amount_with_fee amount being refunded + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_RefundCoinCallback)( + void *cls, + const struct TALER_Amount *amount_with_fee); + +/** + * Select refunds by @a coin_pub, @a merchant_pub and @a h_contract. + * + * @param cls closure of plugin + * @param coin_pub coin to get refunds for + * @param merchant_pub merchant to get refunds for + * @param h_contract contract (hash) to get refunds for + * @param cb function to call for each refund found + * @param cb_cls closure for @a cb + * @return query result status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_refunds_by_coin (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_PrivateContractHashP *h_contract, + TALER_EXCHANGEDB_RefundCoinCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_reserve_close_info.h b/src/include/taler/exchange-database/select_reserve_close_info.h @@ -0,0 +1,50 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_reserve_close_info.h + * @brief implementation of the select_reserve_close_info function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_RESERVE_CLOSE_INFO_H +#define EXCHANGE_DATABASE_SELECT_RESERVE_CLOSE_INFO_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Select information needed to see if we can close + * a reserve. + * + * @param cls closure + * @param reserve_pub which reserve is this about? + * @param[out] balance current reserve balance + * @param[out] payto_uri set to URL of account that + * originally funded the reserve; + * could be set to NULL if not known + * @return transaction status code, 0 if reserve unknown + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserve_close_info (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_Amount *balance, + struct TALER_FullPayto *payto_uri); + + +#endif diff --git a/src/include/taler/exchange-database/select_reserve_closed_above_serial_id.h b/src/include/taler/exchange-database/select_reserve_closed_above_serial_id.h @@ -0,0 +1,79 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_reserve_closed_above_serial_id.h + * @brief implementation of the select_reserve_closed_above_serial_id function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_RESERVE_CLOSED_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_RESERVE_CLOSED_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called about reserve closing operations + * the aggregator triggered. + * + * @param cls closure + * @param rowid row identifier used to uniquely identify the reserve closing operation + * @param execution_date when did we execute the close operation + * @param amount_with_fee how much did we debit the reserve + * @param closing_fee how much did we charge for closing the reserve + * @param reserve_pub public key of the reserve + * @param receiver_account where did we send the funds, in payto://-format + * @param wtid identifier used for the wire transfer + * @param close_request_row row with the responsible close + * request, 0 if regular expiration triggered close + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_ReserveClosedCallback)( + void *cls, + uint64_t rowid, + struct GNUNET_TIME_Timestamp execution_date, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *closing_fee, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_FullPayto receiver_account, + const struct TALER_WireTransferIdentifierRawP *wtid, + uint64_t close_request_row); + +/** + * Function called to select reserve close operations the aggregator + * triggered, 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserve_closed_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_ReserveClosedCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_reserve_open_above_serial_id.h b/src/include/taler/exchange-database/select_reserve_open_above_serial_id.h @@ -0,0 +1,77 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file pg_select_reserve_open_above_serial_id.h + * @brief implementation of the select_reserve_open_above_serial_id function + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_RESERVE_OPEN_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_RESERVE_OPEN_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called about reserve opening operations. + * + * @param cls closure + * @param rowid row identifier used to uniquely identify the reserve closing operation + * @param reserve_payment how much to pay from the + * reserve's own balance for opening the reserve + * @param request_timestamp when was the request created + * @param reserve_expiration desired expiration time for the reserve + * @param purse_limit minimum number of purses the client + * wants to have concurrently open for this reserve + * @param reserve_pub public key of the reserve + * @param reserve_sig signature affirming the operation + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_ReserveOpenCallback)( + void *cls, + uint64_t rowid, + const struct TALER_Amount *reserve_payment, + struct GNUNET_TIME_Timestamp request_timestamp, + struct GNUNET_TIME_Timestamp reserve_expiration, + uint32_t purse_limit, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig); + +/** + * Function called to select reserve open operations, 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserve_open_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_ReserveOpenCallback cb, + void *cb_cls); + + +#endif diff --git a/src/include/taler/exchange-database/select_reserves_in_above_serial_id.h b/src/include/taler/exchange-database/select_reserves_in_above_serial_id.h @@ -0,0 +1,70 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_reserves_in_above_serial_id.h + * @brief implementation of the select_reserves_in_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_RESERVES_IN_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_RESERVES_IN_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about incoming wire transfers. + * + * @param cls closure + * @param rowid unique serial ID for the refresh session in our DB + * @param reserve_pub public key of the reserve (also the wire subject) + * @param credit amount that was received + * @param sender_account_details information about the sender's bank account, in payto://-format + * @param wire_reference unique identifier for the wire transfer + * @param execution_date when did we receive the funds + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_ReserveInCallback)( + void *cls, + uint64_t rowid, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *credit, + const struct TALER_FullPayto sender_account_details, + uint64_t wire_reference, + struct GNUNET_TIME_Timestamp execution_date); + +/** + * Select inbound wire transfers into reserves_in above @a serial_id + * 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserves_in_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_ReserveInCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_reserves_in_above_serial_id_by_account.h b/src/include/taler/exchange-database/select_reserves_in_above_serial_id_by_account.h @@ -0,0 +1,72 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_reserves_in_above_serial_id_by_account.h + * @brief implementation of the select_reserves_in_above_serial_id_by_account function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_RESERVES_IN_ABOVE_SERIAL_ID_BY_ACCOUNT_H +#define EXCHANGE_DATABASE_SELECT_RESERVES_IN_ABOVE_SERIAL_ID_BY_ACCOUNT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about incoming wire transfers. + * + * @param cls closure + * @param rowid unique serial ID for the refresh session in our DB + * @param reserve_pub public key of the reserve (also the wire subject) + * @param credit amount that was received + * @param sender_account_details information about the sender's bank account, in payto://-format + * @param wire_reference unique identifier for the wire transfer + * @param execution_date when did we receive the funds + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_ReserveInCallback)( + void *cls, + uint64_t rowid, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *credit, + const struct TALER_FullPayto sender_account_details, + uint64_t wire_reference, + struct GNUNET_TIME_Timestamp execution_date); + +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_reserves_in_above_serial_id_by_account (struct EXCHANGEDB_PostgresContext *ctx, + const char *account_name, + uint64_t serial_id, + TALER_EXCHANGEDB_ReserveInCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_wire_out_above_serial_id.h b/src/include/taler/exchange-database/select_wire_out_above_serial_id.h @@ -0,0 +1,70 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_wire_out_above_serial_id.h + * @brief implementation of the select_wire_out_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_WIRE_OUT_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_WIRE_OUT_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with the results of the lookup of the + * wire transfer data of the exchange. + * + * @param cls closure + * @param rowid identifier of the respective row in the database + * @param date timestamp of the wire transfer (roughly) + * @param wtid wire transfer subject + * @param payto_uri details of the receiver, URI in payto://-format + * @param amount amount that was wired + * @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_WireTransferOutCallback)( + void *cls, + uint64_t rowid, + struct GNUNET_TIME_Timestamp date, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_FullPayto payto_uri, + const struct TALER_Amount *amount); + +/** + * Function called to select all wire transfers the exchange + * executed. + * + * @param cls closure + * @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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_wire_out_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_WireTransferOutCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_wire_out_above_serial_id_by_account.h b/src/include/taler/exchange-database/select_wire_out_above_serial_id_by_account.h @@ -0,0 +1,72 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_wire_out_above_serial_id_by_account.h + * @brief implementation of the select_wire_out_above_serial_id_by_account function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_WIRE_OUT_ABOVE_SERIAL_ID_BY_ACCOUNT_H +#define EXCHANGE_DATABASE_SELECT_WIRE_OUT_ABOVE_SERIAL_ID_BY_ACCOUNT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with the results of the lookup of the + * wire transfer data of the exchange. + * + * @param cls closure + * @param rowid identifier of the respective row in the database + * @param date timestamp of the wire transfer (roughly) + * @param wtid wire transfer subject + * @param payto_uri details of the receiver, URI in payto://-format + * @param amount amount that was wired + * @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_WireTransferOutCallback)( + void *cls, + uint64_t rowid, + struct GNUNET_TIME_Timestamp date, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_FullPayto payto_uri, + const struct TALER_Amount *amount); + +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_wire_out_above_serial_id_by_account (struct EXCHANGEDB_PostgresContext *ctx, + const char *account_name, + uint64_t serial_id, + TALER_EXCHANGEDB_WireTransferOutCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_withdraw_amounts_for_kyc_check.h b/src/include/taler/exchange-database/select_withdraw_amounts_for_kyc_check.h @@ -0,0 +1,140 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_withdraw_amounts_for_kyc_check.h + * @brief implementation of the select_withdraw_amounts_for_kyc_check function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_WITHDRAW_AMOUNTS_FOR_KYC_CHECK_H +#define EXCHANGE_DATABASE_SELECT_WITHDRAW_AMOUNTS_FOR_KYC_CHECK_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Information per Clause-Schnorr (CS) fresh coin to + * be persisted for idempotency during refreshes-reveal. + */ +struct TALER_EXCHANGEDB_CsRevealFreshCoinData +{ + /** + * Denomination of the fresh coin. + */ + struct TALER_DenominationHashP new_denom_pub_hash; + + /** + * Blind signature of the fresh coin (possibly updated + * in case if a replay!). + */ + struct TALER_BlindedDenominationSignature bsig; + + /** + * Offset of the fresh coin in the reveal operation. + * (May not match the array offset as we may have + * a mixture of RSA and CS coins being created, and + * this request is only made for the CS subset). + */ + uint32_t coin_off; +}; + + +/** + * Generic KYC status for some operation. + */ +struct TALER_EXCHANGEDB_KycStatus +{ + + /** + * Account public key that is currently associated + * with the account. Only set if @e have_account_pub + * is true. + */ + union TALER_AccountPublicKeyP account_pub; + + /** + * Number that identifies the KYC requirement the operation + * was about. + */ + uint64_t requirement_row; + + /** + * True if @e account_pub is set. + */ + bool have_account_pub; + + /** + * True if the KYC status is "satisfied". + */ + bool ok; + +}; + + +struct TALER_EXCHANGEDB_ReserveInInfo +{ + const struct TALER_ReservePublicKeyP *reserve_pub; + const struct TALER_Amount *balance; + struct GNUNET_TIME_Timestamp execution_time; + struct TALER_FullPayto sender_account_details; + const char *exchange_account_name; + uint64_t wire_reference; +}; + + +/** + * Function called on each @a amount that was found to + * be relevant for a KYC check. + * + * @param cls closure to allow the KYC module to + * total up amounts and evaluate rules + * @param amount encountered transaction amount + * @param date when was the amount encountered + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to abort iteration + * #GNUNET_SYSERR on internal error (also abort itaration) + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_KycAmountCallback)( + void *cls, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Absolute date); + +/** + * Call @a kac on withdrawn amounts after @a time_limit which are relevant + * for a KYC trigger for a the (debited) account identified by @a h_payto. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_payto account identifier + * @param time_limit oldest transaction that could be relevant + * @param kac function to call for each applicable amount, in reverse chronological order (or until @a kac aborts by returning anything except #GNUNET_OK). + * @param kac_cls closure for @a kac + * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_withdraw_amounts_for_kyc_check (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Absolute time_limit, + TALER_EXCHANGEDB_KycAmountCallback kac, + void *kac_cls); + +#endif diff --git a/src/include/taler/exchange-database/select_withdrawals_above_serial_id.h b/src/include/taler/exchange-database/select_withdrawals_above_serial_id.h @@ -0,0 +1,85 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/select_withdrawals_above_serial_id.h + * @brief implementation of the select_withdrawals_above_serial_id function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SELECT_WITHDRAWALS_ABOVE_SERIAL_ID_H +#define EXCHANGE_DATABASE_SELECT_WITHDRAWALS_ABOVE_SERIAL_ID_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * Function called with details about withdraw operations. + * + * @param cls closure + * @param rowid unique serial ID for the refresh session in our DB + * @param num_denom_serials number of elements in @e denom_serials array + * @param denom_serials array with length @e num_denom_serials of serial ID's of denominations in our DB + * @param selected_h hash over the gamma-selected planchets + * @param h_planchets running hash over all hashes of blinded planchets in the original withdraw request + * @param blinding_seed the blinding seed for CS denominations that was provided during withdraw; might be NULL + * @param age_proof_required true if the withdraw request required an age proof. + * @param max_age if @e age_proof_required is true, the maximum age that was set on the coins. + * @param noreveal_index if @e age_proof_required is true, the index that was returned by the exchange for the reveal phase. + * @param reserve_pub public key of the reserve + * @param reserve_sig signature over the withdraw operation + * @param execution_date when did the wallet withdraw the coin + * @param amount_with_fee amount that was withdrawn + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +typedef enum GNUNET_GenericReturnValue +(*TALER_EXCHANGEDB_WithdrawCallback)( + void *cls, + uint64_t rowid, + size_t num_denom_serials, + const uint64_t *denom_serials, + const struct TALER_HashBlindedPlanchetsP *selected_h, + const struct TALER_HashBlindedPlanchetsP *h_planchets, + const struct TALER_BlindingMasterSeedP *blinding_seed, + bool age_proof_required, + uint8_t max_age, + uint8_t noreveal_index, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig, + struct GNUNET_TIME_Timestamp execution_date, + const struct TALER_Amount *amount_with_fee); + +/** + * Select withdraw operations from reserves_out above @a serial_id + * 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 + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_select_withdrawals_above_serial_id (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t serial_id, + TALER_EXCHANGEDB_WithdrawCallback cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/set_aml_lock.h b/src/include/taler/exchange-database/set_aml_lock.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/set_aml_lock.h + * @brief implementation of the set_aml_lock function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SET_AML_LOCK_H +#define EXCHANGE_DATABASE_SET_AML_LOCK_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Set a lock for @a lock_duration on running AML programs for the @a h_payto + * account. If a lock already exists, returns the timeout of the + * @a existing_lock. Returns 0 if @a h_payto is not known. + * + * @param cls closure + * @param h_payto account to lock + * @param lock_duration how long to lock the account + * @param[out] existing_lock set to timeout of existing lock, or + * to zero if there is no existing lock + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_set_aml_lock (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Relative lock_duration, + struct GNUNET_TIME_Absolute *existing_lock); + + +#endif diff --git a/src/include/taler/exchange-database/set_extension_manifest.h b/src/include/taler/exchange-database/set_extension_manifest.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/set_extension_manifest.h + * @brief implementation of the set_extension_manifest function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SET_EXTENSION_MANIFEST_H +#define EXCHANGE_DATABASE_SET_EXTENSION_MANIFEST_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to save the manifest of an extension + * (age-restriction, policy_extension_...) After successful storage of the + * 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 + * @param manifest JSON object of the configuration as string + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_set_extension_manifest (struct EXCHANGEDB_PostgresContext *ctx, + const char *extension_name, + const char *manifest); + +#endif diff --git a/src/include/taler/exchange-database/set_purse_balance.h b/src/include/taler/exchange-database/set_purse_balance.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/set_purse_balance.h + * @brief implementation of the set_purse_balance function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_SET_PURSE_BALANCE_H +#define EXCHANGE_DATABASE_SET_PURSE_BALANCE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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. + * + * @param cls closure + * @param purse_pub public key of a purse + * @param balance new balance to store under the purse + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_set_purse_balance (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_Amount *balance); + +#endif diff --git a/src/include/taler/exchange-database/start.h b/src/include/taler/exchange-database/start.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/start.h + * @brief implementation of the start function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_START_H +#define EXCHANGE_DATABASE_START_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Start a transaction. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param name unique name identifying the transaction (for debugging) + * must point to a constant + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_start (struct EXCHANGEDB_PostgresContext *ctx, + const char *name); + +#endif diff --git a/src/include/taler/exchange-database/start_deferred_wire_out.h b/src/include/taler/exchange-database/start_deferred_wire_out.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/start_deferred_wire_out.h + * @brief implementation of the start_deferred_wire_out function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_START_DEFERRED_WIRE_OUT_H +#define EXCHANGE_DATABASE_START_DEFERRED_WIRE_OUT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Starts a READ COMMITTED transaction where we transiently violate the foreign + * 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 + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_start_deferred_wire_out (struct EXCHANGEDB_PostgresContext *ctx); + +#endif diff --git a/src/include/taler/exchange-database/start_read_committed.h b/src/include/taler/exchange-database/start_read_committed.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/start_read_committed.h + * @brief implementation of the start_read_committed function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_START_READ_COMMITTED_H +#define EXCHANGE_DATABASE_START_READ_COMMITTED_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Start a READ COMMITTED transaction. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param name unique name identifying the transaction (for debugging) + * must point to a constant + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_start_read_committed (struct EXCHANGEDB_PostgresContext *ctx, + const char *name); + +#endif diff --git a/src/include/taler/exchange-database/start_read_only.h b/src/include/taler/exchange-database/start_read_only.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/start_read_only.h + * @brief implementation of the start_read_only function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_START_READ_ONLY_H +#define EXCHANGE_DATABASE_START_READ_ONLY_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Start a READ ONLY serializable transaction. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param name unique name identifying the transaction (for debugging) + * must point to a constant + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +EXCHANGEDB_start_read_only (struct EXCHANGEDB_PostgresContext *ctx, + const char *name); + +#endif diff --git a/src/include/taler/exchange-database/store_wire_transfer_out.h b/src/include/taler/exchange-database/store_wire_transfer_out.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/store_wire_transfer_out.h + * @brief implementation of the store_wire_transfer_out function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_STORE_WIRE_TRANSFER_OUT_H +#define EXCHANGE_DATABASE_STORE_WIRE_TRANSFER_OUT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @param h_payto identifies the receiver account of the wire transfer + * @param exchange_account_section configuration section of the exchange specifying the + * exchange's bank account being used + * @param amount amount that was transmitted + * @param extra_wire_subject_metadata additional meta data for the wire transfer subject, can be NULL + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_store_wire_transfer_out (struct EXCHANGEDB_PostgresContext *ctx, + struct GNUNET_TIME_Timestamp date, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_FullPaytoHashP *h_payto, + const char *exchange_account_section, + const struct TALER_Amount *amount, + const char *extra_wire_subject_metadata); + +#endif diff --git a/src/include/taler/exchange-database/test_aml_officer.h b/src/include/taler/exchange-database/test_aml_officer.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/test_aml_officer.h + * @brief implementation of the test_aml_officer function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_TEST_AML_OFFICER_H +#define EXCHANGE_DATABASE_TEST_AML_OFFICER_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Test if the given AML staff member is active + * (at least read-only). + * + * @param cls closure + * @param decider_pub public key of the staff member + * @param[out] read_only set to true if the member is read-only + * @return database transaction status, if member is unknown or not active, 1 if member is active + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_test_aml_officer (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AmlOfficerPublicKeyP *decider_pub, + bool *read_only); + + +#endif diff --git a/src/include/taler/exchange-database/trigger_kyc_rule_for_account.h b/src/include/taler/exchange-database/trigger_kyc_rule_for_account.h @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/trigger_kyc_rule_for_account.h + * @brief implementation of the trigger_kyc_rule_for_account function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_TRIGGER_KYC_RULE_FOR_ACCOUNT_H +#define EXCHANGE_DATABASE_TRIGGER_KYC_RULE_FOR_ACCOUNT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert KYC requirement for @a h_payto account into table. + * + * @param cls closure + * @param payto_uri account that must be KYC'ed, + * can be NULL if @a h_payto is already + * guaranteed to be in wire_targets + * @param h_payto hash of @a payto_uri + * @param set_account_pub public key to enable for the + * KYC authorization, NULL if not known + * @param check_merchant_pub public key that must already + * be enabled for a KYC authorzation for it to be + * valid, NULL if not known + * @param jmeasures serialized MeasureSet to put in place + * @param display_priority priority of the rule + * @param[out] requirement_row set to legitimization requirement row for this check + * @param[out] bad_kyc_auth set if @a check_account_pub + * did not match the existing KYC auth + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_trigger_kyc_rule_for_account (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + const struct TALER_NormalizedPaytoHashP *h_payto, + const union TALER_AccountPublicKeyP *set_account_pub, + const struct TALER_MerchantPublicKeyP *check_merchant_pub, + const json_t *jmeasures, + uint32_t display_priority, + uint64_t *requirement_row, + bool *bad_kyc_auth); + +#endif diff --git a/src/include/taler/exchange-database/update_aggregation_transient.h b/src/include/taler/exchange-database/update_aggregation_transient.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/update_aggregation_transient.h + * @brief implementation of the update_aggregation_transient function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_UPDATE_AGGREGATION_TRANSIENT_H +#define EXCHANGE_DATABASE_UPDATE_AGGREGATION_TRANSIENT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + * @param kyc_requirement_row row in legitimization_requirements that need to be satisfied to continue, or 0 for none + * @param total new total amount to be wired in the future + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_update_aggregation_transient (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPaytoHashP *h_payto, + const struct TALER_WireTransferIdentifierRawP *wtid, + uint64_t kyc_requirement_row, + const struct TALER_Amount *total); + +#endif diff --git a/src/include/taler/exchange-database/update_auditor.h b/src/include/taler/exchange-database/update_auditor.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/update_auditor.h + * @brief implementation of the update_auditor function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_UPDATE_AUDITOR_H +#define EXCHANGE_DATABASE_UPDATE_AUDITOR_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + +struct EXCHANGEDB_PostgresContext; +/** + * Update information about an auditor that will audit this exchange. + * + * @param cls closure + * @param auditor_pub key of the auditor (primary key for the existing record) + * @param auditor_url base URL of the auditor's REST service, to be updated + * @param auditor_name name of the auditor (for humans) + * @param change_date date when the auditor status was last changed + * (only to be used for replay detection) + * @param enabled true to enable, false to disable + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_update_auditor (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const char *auditor_url, + const char *auditor_name, + struct GNUNET_TIME_Timestamp change_date, + bool enabled); + +#endif diff --git a/src/include/taler/exchange-database/update_kyc_process_by_row.h b/src/include/taler/exchange-database/update_kyc_process_by_row.h @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/update_kyc_process_by_row.h + * @brief implementation of the update_kyc_process_by_row function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_UPDATE_KYC_PROCESS_BY_ROW_H +#define EXCHANGE_DATABASE_UPDATE_KYC_PROCESS_BY_ROW_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Update KYC requirement check with provider-linkage and/or + * expiration data. + * + * @param cls closure + * @param process_row row to select by + * @param provider_name provider that must be checked (technically redundant) + * @param h_payto account that must be KYC'ed (helps access by shard, otherwise also redundant) + * @param provider_account_id provider account ID + * @param provider_legitimization_id provider legitimization ID + * @param redirect_url where the user should be redirected to start the KYC process + * @param expiration how long is this KYC check set to be valid (in the past if invalid) + * @param ec error code, #TALER_EC_NONE on success + * @param error_message_hint human-readable error message details (in addition to @a ec, NULL on success) + * @param finished true to mark the process as done + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_update_kyc_process_by_row (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t process_row, + const char *provider_name, + const struct TALER_NormalizedPaytoHashP *h_payto, + const char *provider_account_id, + const char *provider_legitimization_id, + const char *redirect_url, + struct GNUNET_TIME_Absolute expiration, + enum TALER_ErrorCode ec, + const char *error_message_hint, + bool finished); + +#endif diff --git a/src/include/taler/exchange-database/update_wire.h b/src/include/taler/exchange-database/update_wire.h @@ -0,0 +1,63 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/update_wire.h + * @brief implementation of the update_wire function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_UPDATE_WIRE_H +#define EXCHANGE_DATABASE_UPDATE_WIRE_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Update information about a wire account of the exchange. + * + * @param cls closure + * @param payto_uri account the update is about + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param open_banking_gateway open banking gateway service, NULL if unavailable + * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable + * @param debit_restrictions JSON array with debit restrictions on the account; NULL allowed if not @a enabled + * @param credit_restrictions JSON array with credit restrictions on the account; NULL allowed if not @a enabled + * @param change_date date when the account status was last changed + * (only to be used for replay detection) + * @param master_sig master signature to store, can be NULL (if @a enabled is false) + * @param bank_label label to show this entry under in the UI, can be NULL + * @param priority determines order in which entries are shown in the UI + * @param enabled true to enable, false to disable (the actual change) + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_update_wire (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_FullPayto payto_uri, + const char *conversion_url, + const char *open_banking_gateway, + const char *wire_transfer_gateway, + const json_t *debit_restrictions, + const json_t *credit_restrictions, + struct GNUNET_TIME_Timestamp change_date, + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority, + bool enabled); + +#endif diff --git a/src/include/taler/exchange-database/wad_in_insert.h b/src/include/taler/exchange-database/wad_in_insert.h @@ -0,0 +1,54 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/wad_in_insert.h + * @brief implementation of the wad_in_insert function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_WAD_IN_INSERT_H +#define EXCHANGE_DATABASE_WAD_IN_INSERT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + +struct EXCHANGEDB_PostgresContext; +/** + * Insert an incoming WAD wire transfer into the database. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param wad_id WAD identifier + * @param origin_exchange_url exchange base URL originating the transfer + * @param amount the amount that was transferred + * @param execution_date when was the transfer made + * @param debit_account_uri URI of the debit account + * @param section_name section of the exchange bank account that received the transfer + * @param serial_id bank-specific row identifying the transfer + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wad_in_insert (struct EXCHANGEDB_PostgresContext *ctx, + const struct TALER_WadIdentifierP *wad_id, + const char *origin_exchange_url, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Timestamp execution_date, + const struct TALER_FullPayto debit_account_uri, + const char *section_name, + uint64_t serial_id); + + +#endif diff --git a/src/include/taler/exchange-database/wire_prepare_data_get.h b/src/include/taler/exchange-database/wire_prepare_data_get.h @@ -0,0 +1,1753 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/wire_prepare_data_get.h + * @brief implementation of the wire_prepare_data_get function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_WIRE_PREPARE_DATA_GET_H +#define EXCHANGE_DATABASE_WIRE_PREPARE_DATA_GET_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + + + +struct EXCHANGEDB_PostgresContext; +/* Callback typedefs */ +/** + * @brief Information we keep for a withdrawn coin to reproduce + * the /batch-withdraw operation if needed, and to have proof + * that a reserve was drained by this amount. + * + * @note This structure will be removed at some point after v24 of the protocol + * FIXME: to be deleted. + */ +struct TALER_EXCHANGEDB_CollectableBlindcoin +{ + + /** + * Our (blinded) signature over the (blinded) coin. + */ + struct TALER_BlindedDenominationSignature sig; + + /** + * Hash of the denomination key (which coin was generated). + */ + struct TALER_DenominationHashP denom_pub_hash; + + /** + * Value of the coin being exchangeed (matching the denomination key) + * plus the transaction fee. We include this in what is being + * signed so that we can verify a reserve's remaining total balance + * without needing to access the respective denomination key + * information each time. + */ + struct TALER_Amount amount_with_fee; + + /** + * Withdrawal fee charged by the exchange. This must match the Exchange's + * denomination key's withdrawal fee. If the client puts in an + * invalid withdrawal fee (too high or too low) that does not match + * the Exchange's denomination key, the withdraw operation is invalid + * and will be rejected by the exchange. The @e amount_with_fee minus + * the @e withdraw_fee is must match the value of the generated + * coin. We include this in what is being signed so that we can + * verify a exchange's accounting without needing to access the + * respective denomination key information each time. + */ + struct TALER_Amount withdraw_fee; + + /** + * Public key of the reserve that was drained. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * Hash over the blinded message, needed to verify + * the @e reserve_sig. + */ + struct TALER_BlindedCoinHashP h_coin_envelope; + + /** + * Signature confirming the withdrawal, matching @e reserve_pub, + * @e denom_pub and @e h_coin_envelope. + */ + struct TALER_ReserveSignatureP reserve_sig; +}; + +/** + * @brief Information we keep for a withdraw request + * to reproduce the /withdraw operation if needed, and to have proof + * that a reserve was drained by this amount. + */ +struct TALER_EXCHANGEDB_Withdraw +{ + /** + * Total amount (with fee) committed to withdraw + */ + struct TALER_Amount amount_with_fee; + + /** + * true, if a proof of age was required following this withdraw, + * in a subsequent call to /reveal-withdraw. + * In this case, @e max_age, @e h_commitment and + * @e noreveal_index are to be taken into account + */ + bool age_proof_required; + + /** + * Maximum age (in years) that the coins are restricted to, + * if ``age_proof_required`` is true. + */ + uint16_t max_age; + + /** + * If ``age_proof_required`` is true, index (smaller #TALER_CNC_KAPPA) + * which the exchange has chosen to keep unrevealed + * during the next cut and choose (aka /reveal-age) step. + * This value applies to all n coins in the commitment. + */ + uint16_t noreveal_index; + + /** + * If @e age_proof_required is true, the running hash over all blinded coin + * envelope's TALER_BlindedCoinHashP values. + * It runs over ``kappa*num_coins``, starting with the hashes for the coins + * for kappa index=0, then index=1 etc., + * i.e. h[0][0]...h[0][n-1]h[1][0]...h[1][n-1]...h[κ-1][0]...h[κ-1][n-1] + */ + struct TALER_HashBlindedPlanchetsP planchets_h; + + /** + * Public key of the reserve that was drained. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * Signature confirming the withdrawal commitment + */ + struct TALER_ReserveSignatureP reserve_sig; + + /** + * Number of coins to be withdrawn. + */ + size_t num_coins; + + /** + * The hash of the blinded coin envelopes which are signed by the exchange. + * In case of @e age_proof_required = true, this is the hash over the chosen coins' + * envelopes (according to @e noreveal_index) from the request, which contained + * kappa*num_coins blinded coins envelopes. + */ + struct TALER_HashBlindedPlanchetsP selected_h; + + /** + * Array of @a num_coins denomination signatures of the blinded coins @a + * h_coin_evs. + */ + struct TALER_BlindedDenominationSignature *denom_sigs; + + /** + * Array of @a num_coins serial id's of the denominations, corresponding to + * the coins in @a h_coin_evs. + * If @e age_proof_required is true, the denominations MUST support age restriction. + */ + uint64_t *denom_serials; + + /** + * If true, no @e blinding_seed is set and @e num_cs_r_values is 0. + */ + bool no_blinding_seed; + + /** + * If @e no_blinding_seed is false, the blinding seed for the nonces needed for + * blind CS signatures. + */ + struct TALER_BlindingMasterSeedP blinding_seed; + + /** + * Number of elements in @e cs_r_values. + * Only non-zero IF @e age_proof_required is true AND any of the denomination + * has a cipher of type CS. + */ + size_t num_cs_r_values; + + /** + * Array @e num_r_pubs of public R-value pairs for CS that were generated from the + * @e blinding_seed, a coin's index and the denomination's private key during the + * the /withdraw request, to ensure idempotency in case of expiration of a denomination. + * NULL if @e num_r_pub is 0 (or @e age_proof_required is false). + */ + struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values; + + /** + * The bitvector encoding the choices per coin, made by the exchange, + * for the R-values in @e cs_r_values. The value is encoded in NBO + * and the lowest bit corresponds to the pair at index 0 in @e cs_r_values. + */ + uint64_t cs_r_choices; + + /** + * [out]-Array of @a num_coins hashes of the public keys of the denominations + * identified by @e denom_serials. This field is only set when calling + * get_reserve_history(). + */ + struct TALER_DenominationHashP *denom_pub_hashes; +}; + + +/** + * Information the exchange records about a recoup request + * in a reserve history. + */ +struct TALER_EXCHANGEDB_Recoup +{ + + /** + * Information about the coin that was paid back. + */ + struct TALER_CoinPublicInfo coin; + + /** + * Blinding factor supplied to prove to the exchange that + * the coin came from this reserve. + */ + union GNUNET_CRYPTO_BlindingSecretP coin_blind; + + /** + * Signature of the coin of type + * #TALER_SIGNATURE_WALLET_COIN_RECOUP. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** + * Public key of the reserve the coin was paid back into. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * How much was the coin still worth at this time? + */ + struct TALER_Amount value; + + /** + * When did the recoup operation happen? + */ + struct GNUNET_TIME_Timestamp timestamp; + +}; + + +/** + * Public key to which a nonce is locked. + */ +union TALER_EXCHANGEDB_NonceLockTargetP +{ + /** + * Nonce is locked to this coin key. + */ + struct TALER_CoinSpendPublicKeyP coin; + + /** + * Nonce is locked to this reserve key. + */ + struct TALER_ReservePublicKeyP reserve; +}; + + +/** + * Information the exchange records about a recoup request + * in a coin history. + */ +struct TALER_EXCHANGEDB_RecoupListEntry +{ + + /** + * Blinding factor supplied to prove to the exchange that + * the coin came from this reserve. + */ + union GNUNET_CRYPTO_BlindingSecretP coin_blind; + + /** + * Signature of the coin of type + * #TALER_SIGNATURE_WALLET_COIN_RECOUP. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** + * Hash of the public denomination key used to sign the coin. + */ + struct TALER_DenominationHashP h_denom_pub; + + /** + * Public key of the reserve the coin was paid back into. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * How much was the coin still worth at this time? + */ + struct TALER_Amount value; + + /** + * When did the /recoup operation happen? + */ + struct GNUNET_TIME_Timestamp timestamp; + +}; + + +/** + * Information the exchange records about a recoup-refresh request in + * a coin transaction history. + */ +struct TALER_EXCHANGEDB_RecoupRefreshListEntry +{ + + /** + * Information about the coin that was paid back + * (NOT the coin we are considering the history of!) + */ + struct TALER_CoinPublicInfo coin; + + /** + * Blinding factor supplied to prove to the exchange that + * the coin came from this @e old_coin_pub. + */ + union GNUNET_CRYPTO_BlindingSecretP coin_blind; + + /** + * Signature of the coin of type + * #TALER_SIGNATURE_WALLET_COIN_RECOUP. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** + * Public key of the old coin that the refreshed coin was paid back to. + */ + struct TALER_CoinSpendPublicKeyP old_coin_pub; + + /** + * How much was the coin still worth at this time? + */ + struct TALER_Amount value; + + /** + * When did the recoup operation happen? + */ + struct GNUNET_TIME_Timestamp timestamp; + +}; + + +/** + * Details about a purse merge operation. + */ +struct TALER_EXCHANGEDB_PurseMerge +{ + + /** + * Public key of the reserve the coin was merged into. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * Amount in the purse, with fees. + */ + struct TALER_Amount amount_with_fee; + + /** + * Fee paid for the purse. + */ + struct TALER_Amount purse_fee; + + /** + * Hash over the contract. + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Merge capability key. + */ + struct TALER_PurseMergePublicKeyP merge_pub; + + /** + * Purse public key. + */ + struct TALER_PurseContractPublicKeyP purse_pub; + + /** + * Signature by the reserve approving the merge. + */ + struct TALER_ReserveSignatureP reserve_sig; + + /** + * When was the merge made. + */ + struct GNUNET_TIME_Timestamp merge_timestamp; + + /** + * When was the purse set to expire. + */ + struct GNUNET_TIME_Timestamp purse_expiration; + + /** + * Minimum age required for depositing into the purse. + */ + uint32_t min_age; + + /** + * Flags of the purse. + */ + enum TALER_WalletAccountMergeFlags flags; + + /** + * true if the purse was actually successfully merged, + * false if the @e purse_fee was charged but the + * @e amount was not credited to the reserve. + */ + bool merged; +}; + + +/** + * Details about a (paid for) reserve history request. + */ +struct TALER_EXCHANGEDB_HistoryRequest +{ + /** + * Public key of the reserve the history request was for. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * Fee paid for the request. + */ + struct TALER_Amount history_fee; + + /** + * When was the request made. + */ + struct GNUNET_TIME_Timestamp request_timestamp; + + /** + * Signature by the reserve approving the history request. + */ + struct TALER_ReserveSignatureP reserve_sig; +}; + + +/** + * Details about a (paid for) reserve open request. + */ +struct TALER_EXCHANGEDB_OpenRequest +{ + /** + * Public key of the reserve the open request was for. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * Fee paid for the request from the reserve. + */ + struct TALER_Amount open_fee; + + /** + * When was the request made. + */ + struct GNUNET_TIME_Timestamp request_timestamp; + + /** + * How long was the reserve supposed to be open. + */ + struct GNUNET_TIME_Timestamp reserve_expiration; + + /** + * Signature by the reserve approving the open request, + * with purpose #TALER_SIGNATURE_WALLET_RESERVE_OPEN. + */ + struct TALER_ReserveSignatureP reserve_sig; + + /** + * How many open purses should be included with the + * open reserve? + */ + uint32_t purse_limit; + +}; + + +/** + * Details about an (explicit) reserve close request. + */ +struct TALER_EXCHANGEDB_CloseRequest +{ + /** + * Public key of the reserve the history request was for. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * When was the request made. + */ + struct GNUNET_TIME_Timestamp request_timestamp; + + /** + * Hash of the payto://-URI of the target account + * for the closure, or all zeros for the reserve + * origin account. + */ + struct TALER_FullPaytoHashP target_account_h_payto; + + /** + * Signature by the reserve approving the history request. + */ + struct TALER_ReserveSignatureP reserve_sig; + +}; + + +/** + * @brief Types of operations on a reserve. + */ +enum TALER_EXCHANGEDB_ReserveOperation +{ + /** + * Money was deposited into the reserve via a bank transfer. + * This is how customers establish a reserve at the exchange. + */ + TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE = 0, + + /** + * A batch of coins was withdrawn from the reserve using /withdraw. + */ + TALER_EXCHANGEDB_RO_WITHDRAW_COINS = 1, + + /** + * A coin was returned to the reserve using /recoup. + */ + TALER_EXCHANGEDB_RO_RECOUP_COIN = 2, + + /** + * The exchange send inactive funds back from the reserve to the + * customer's bank account. This happens when the exchange + * closes a reserve with a non-zero amount left in it. + */ + TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK = 3, + + /** + * Event where a purse was merged into a reserve. + */ + TALER_EXCHANGEDB_RO_PURSE_MERGE = 4, + + /** + * Event where a wallet paid for a full reserve history. + */ + TALER_EXCHANGEDB_RO_HISTORY_REQUEST = 5, + + /** + * Event where a wallet paid to open a reserve for longer. + */ + TALER_EXCHANGEDB_RO_OPEN_REQUEST = 6, + + /** + * Event where a wallet requested a reserve to be closed. + */ + TALER_EXCHANGEDB_RO_CLOSE_REQUEST = 7, + +}; + + +/** + * @brief Reserve history as a linked list. Lists all of the transactions + * associated with this reserve (such as the bank transfers that + * established the reserve and all /withdraw operations we have done + * since). + */ +struct TALER_EXCHANGEDB_ReserveHistory +{ + + /** + * Next entry in the reserve history. + */ + struct TALER_EXCHANGEDB_ReserveHistory *next; + + /** + * Offset of this entry in the reserve history. + * Corresponds to the reserve_history_serial_id in the database. + */ + uint64_t history_offset; + + /** + * Type of the event, determines @e details. + */ + enum TALER_EXCHANGEDB_ReserveOperation type; + + /** + * Details of the operation, depending on @e type. + */ + union + { + + /** + * Details about a bank transfer to the exchange (reserve + * was established). + */ + struct TALER_EXCHANGEDB_BankTransfer *bank; + + /** + * Details about a /withdraw operation. + */ + struct TALER_EXCHANGEDB_Withdraw *withdraw; + + /** + * Details about a /recoup operation. + */ + struct TALER_EXCHANGEDB_Recoup *recoup; + + /** + * Details about a bank transfer from the exchange (reserve + * was closed). + */ + struct TALER_EXCHANGEDB_ClosingTransfer *closing; + + /** + * Details about a purse merge operation. + */ + struct TALER_EXCHANGEDB_PurseMerge *merge; + + /** + * Details about a (paid for) reserve history request. + */ + struct TALER_EXCHANGEDB_HistoryRequest *history; + + /** + * Details about a (paid for) open reserve request. + */ + struct TALER_EXCHANGEDB_OpenRequest *open_request; + + /** + * Details about an (explicit) reserve close request. + */ + struct TALER_EXCHANGEDB_CloseRequest *close_request; + + } details; + +}; + + +/** + * @brief Data about a coin for a deposit operation. + */ +struct TALER_EXCHANGEDB_CoinDepositInformation +{ + /** + * Information about the coin that is being deposited. + */ + struct TALER_CoinPublicInfo coin; + + /** + * ECDSA signature affirming that the customer intends + * this coin to be deposited at the merchant identified + * by @e h_wire in relation to the proposal data identified + * by @e h_contract_terms. + */ + struct TALER_CoinSpendSignatureP csig; + + /** + * Fraction of the coin's remaining value to be deposited, including + * depositing fee (if any). The coin is identified by @e coin_pub. + */ + struct TALER_Amount amount_with_fee; + +}; + + +/** + * @brief Data from a batch deposit operation. + */ +struct TALER_EXCHANGEDB_BatchDeposit +{ + + /** + * Public key of the merchant. Enables later identification + * of the merchant in case of a need to rollback transactions. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Signature of the merchant over the contract, of purpose + * #TALER_SIGNATURE_MERCHANT_CONTRACT. + */ + struct TALER_MerchantSignatureP merchant_sig; + + /** + * Hash over the proposal data between merchant and customer + * (remains unknown to the Exchange). + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Hash over additional inputs by the wallet. + */ + struct GNUNET_HashCode wallet_data_hash; + + /** + * Unsalted hash over @e receiver_wire_account. + */ + struct TALER_FullPaytoHashP wire_target_h_payto; + + /** + * Salt used by the merchant to compute "h_wire". + */ + struct TALER_WireSaltP wire_salt; + + /** + * Time when this request was generated. Used, for example, to + * assess when (roughly) the income was achieved for tax purposes. + * Note that the Exchange will only check that the timestamp is not "too + * far" into the future (i.e. several days). The fact that the + * timestamp falls within the validity period of the coin's + * denomination key is irrelevant for the validity of the deposit + * request, as obviously the customer and merchant could conspire to + * set any timestamp. Also, the Exchange must accept very old deposit + * requests, as the merchant might have been unable to transmit the + * deposit request in a timely fashion (so back-dating is not + * prevented). + */ + struct GNUNET_TIME_Timestamp wallet_timestamp; + + /** + * How much time does the merchant have to issue a refund request? + * Zero if refunds are not allowed. After this time, the coin + * cannot be refunded. + */ + struct GNUNET_TIME_Timestamp refund_deadline; + + /** + * How much time does the merchant have to execute the wire transfer? + * This time is advisory for aggregating transactions, not a hard + * constraint (as the merchant can theoretically pick any time, + * including one in the past). + */ + struct GNUNET_TIME_Timestamp wire_deadline; + + /** + * Row ID of the policy details; 0 if no policy applies. + */ + uint64_t policy_details_serial_id; + + /** + * Information about the receiver for executing the transaction. URI in + * payto://-format. + */ + struct TALER_FullPayto receiver_wire_account; + + /** + * Optional extra information to include in the wire transfer + * subject. + */ + const char *extra_wire_subject_metadata; + + /** + * Array about the coins that are being deposited. + */ + const struct TALER_EXCHANGEDB_CoinDepositInformation *cdis; + + /** + * Length of the @e cdis array. + */ + unsigned int num_cdis; + + /** + * False if @e wallet_data_hash was provided + */ + bool no_wallet_data_hash; + + /** + * True if further processing is blocked by policy. + */ + bool policy_blocked; + +}; + + +/** + * @brief Data from a deposit operation. The combination of + * the coin's public key, the merchant's public key and the + * transaction ID must be unique. While a coin can (theoretically) be + * deposited at the same merchant twice (with partial spending), the + * merchant must either use a different public key or a different + * transaction ID for the two transactions. The same coin must not + * be used twice at the same merchant for the same transaction + * (as determined by transaction ID). + */ +struct TALER_EXCHANGEDB_Deposit +{ + /** + * Information about the coin that is being deposited. + */ + struct TALER_CoinPublicInfo coin; + + /** + * ECDSA signature affirming that the customer intends + * this coin to be deposited at the merchant identified + * by @e h_wire in relation to the proposal data identified + * by @e h_contract_terms. + */ + struct TALER_CoinSpendSignatureP csig; + + /** + * Public key of the merchant. Enables later identification + * of the merchant in case of a need to rollback transactions. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Hash over the proposal data between merchant and customer + * (remains unknown to the Exchange). + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Salt used by the merchant to compute "h_wire". + */ + struct TALER_WireSaltP wire_salt; + + /** + * Hash over inputs from the wallet to customize the contract. + */ + struct GNUNET_HashCode wallet_data_hash; + + /** + * Hash over the policy data for this deposit (remains unknown to the + * Exchange). Needed for the verification of the deposit's signature + */ + struct TALER_ExtensionPolicyHashP h_policy; + + /** + * Time when this request was generated. Used, for example, to + * assess when (roughly) the income was achieved for tax purposes. + * Note that the Exchange will only check that the timestamp is not "too + * far" into the future (i.e. several days). The fact that the + * timestamp falls within the validity period of the coin's + * denomination key is irrelevant for the validity of the deposit + * request, as obviously the customer and merchant could conspire to + * set any timestamp. Also, the Exchange must accept very old deposit + * requests, as the merchant might have been unable to transmit the + * deposit request in a timely fashion (so back-dating is not + * prevented). + */ + struct GNUNET_TIME_Timestamp timestamp; + + /** + * How much time does the merchant have to issue a refund request? + * Zero if refunds are not allowed. After this time, the coin + * cannot be refunded. + */ + struct GNUNET_TIME_Timestamp refund_deadline; + + /** + * How much time does the merchant have to execute the wire transfer? + * This time is advisory for aggregating transactions, not a hard + * constraint (as the merchant can theoretically pick any time, + * including one in the past). + */ + struct GNUNET_TIME_Timestamp wire_deadline; + + /** + * Fraction of the coin's remaining value to be deposited, including + * depositing fee (if any). The coin is identified by @e coin_pub. + */ + struct TALER_Amount amount_with_fee; + + /** + * Depositing fee. + */ + struct TALER_Amount deposit_fee; + + /** + * Information about the receiver for executing the transaction. URI in + * payto://-format. + */ + struct TALER_FullPayto receiver_wire_account; + + /** + * True if @e policy_json was provided + */ + bool has_policy; + + /** + * True if @e wallet_data_hash is not in use. + */ + bool no_wallet_data_hash; + +}; + + +/** + * @brief Specification for a deposit operation in the + * `struct TALER_EXCHANGEDB_TransactionList`. + */ +struct TALER_EXCHANGEDB_DepositListEntry +{ + + /** + * ECDSA signature affirming that the customer intends + * this coin to be deposited at the merchant identified + * by @e h_wire in relation to the proposal data identified + * by @e h_contract_terms. + */ + struct TALER_CoinSpendSignatureP csig; + + /** + * Public key of the merchant. Enables later identification + * of the merchant in case of a need to rollback transactions. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Hash over the proposa data between merchant and customer + * (remains unknown to the Exchange). + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Hash over inputs from the wallet to customize the contract. + */ + struct GNUNET_HashCode wallet_data_hash; + + /** + * Hash of the public denomination key used to sign the coin. + */ + struct TALER_DenominationHashP h_denom_pub; + + /** + * Age commitment hash, if applicable to the denomination. Should be all + * zeroes if age commitment is not applicable to the denonimation. + */ + struct TALER_AgeCommitmentHashP h_age_commitment; + + /** + * Salt used to compute h_wire from the @e receiver_wire_account. + */ + struct TALER_WireSaltP wire_salt; + + /** + * Hash over the policy data for this deposit (remains unknown to the + * Exchange). Needed for the verification of the deposit's signature + */ + struct TALER_ExtensionPolicyHashP h_policy; + + /** + * Fraction of the coin's remaining value to be deposited, including + * depositing fee (if any). The coin is identified by @e coin_pub. + */ + struct TALER_Amount amount_with_fee; + + /** + * Depositing fee. + */ + struct TALER_Amount deposit_fee; + + /** + * Time when this request was generated. Used, for example, to + * assess when (roughly) the income was achieved for tax purposes. + * Note that the Exchange will only check that the timestamp is not "too + * far" into the future (i.e. several days). The fact that the + * timestamp falls within the validity period of the coin's + * denomination key is irrelevant for the validity of the deposit + * request, as obviously the customer and merchant could conspire to + * set any timestamp. Also, the Exchange must accept very old deposit + * requests, as the merchant might have been unable to transmit the + * deposit request in a timely fashion (so back-dating is not + * prevented). + */ + struct GNUNET_TIME_Timestamp timestamp; + + /** + * How much time does the merchant have to issue a refund request? + * Zero if refunds are not allowed. After this time, the coin + * cannot be refunded. + */ + struct GNUNET_TIME_Timestamp refund_deadline; + + /** + * How much time does the merchant have to execute the wire transfer? + * This time is advisory for aggregating transactions, not a hard + * constraint (as the merchant can theoretically pick any time, + * including one in the past). + */ + struct GNUNET_TIME_Timestamp wire_deadline; + + /** + * Detailed information about the receiver for executing the transaction. + * URL in payto://-format. + */ + struct TALER_FullPayto receiver_wire_account; + + /** + * true, if age commitment is not applicable + */ + bool no_age_commitment; + + /** + * true, if wallet data hash is not present + */ + bool no_wallet_data_hash; + + /** + * True if a policy was provided with the deposit request + */ + bool has_policy; + + /** + * Has the deposit been wired? + */ + bool done; + +}; + + +/** + * @brief Specification for a refund operation in a coin's transaction list. + */ +struct TALER_EXCHANGEDB_RefundListEntry +{ + + /** + * Public key of the merchant. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Signature from the merchant affirming the refund. + */ + struct TALER_MerchantSignatureP merchant_sig; + + /** + * Hash over the proposal data between merchant and customer + * (remains unknown to the Exchange). + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Merchant-generated REFUND transaction ID to detect duplicate + * refunds. + */ + uint64_t rtransaction_id; + + /** + * Fraction of the original deposit's value to be refunded, including + * refund fee (if any). The coin is identified by @e coin_pub. + */ + struct TALER_Amount refund_amount; + + /** + * Refund fee to be covered by the customer. + */ + struct TALER_Amount refund_fee; + +}; + + +/** + * @brief Specification for a refund operation. The combination of + * the coin's public key, the merchant's public key and the + * transaction ID must be unique. While a coin can (theoretically) be + * deposited at the same merchant twice (with partial spending), the + * merchant must either use a different public key or a different + * transaction ID for the two transactions. The same goes for + * refunds, hence we also have a "rtransaction" ID which is disjoint + * from the transaction ID. The same coin must not be used twice at + * the same merchant for the same transaction or rtransaction ID. + */ +struct TALER_EXCHANGEDB_Refund +{ + /** + * Information about the coin that is being refunded. + */ + struct TALER_CoinPublicInfo coin; + + /** + * Details about the refund. + */ + struct TALER_EXCHANGEDB_RefundListEntry details; + +}; + + +/** + * @brief Specification for coin in a melt operation. + */ +struct TALER_EXCHANGEDB_Refresh +{ + /** + * Information about the coin that is being melted. + */ + struct TALER_CoinPublicInfo coin; + + /** + * Signature over the melting operation. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** + * Refresh commitment this coin is melted into. + */ + struct TALER_RefreshCommitmentP rc; + + /** + * How much value is being melted? This amount includes the fees, + * so the final amount contributed to the melt is this value minus + * the fee for melting the coin. We include the fee in what is + * being signed so that we can verify a reserve's remaining total + * balance without needing to access the respective denomination key + * information each time. + */ + struct TALER_Amount amount_with_fee; + + /** + * Index (smaller #TALER_CNC_KAPPA) which the exchange has chosen to not + * have revealed during cut and choose. + */ + uint32_t noreveal_index; + +}; + + +/** + * Information about a /coins/$COIN_PUB/melt operation in a coin transaction history. + */ +struct TALER_EXCHANGEDB_MeltListEntry +{ + + /** + * Signature over the melting operation. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** + * Refresh commitment this coin is melted into. + */ + struct TALER_RefreshCommitmentP rc; + + /** + * Hash of the public denomination key used to sign the coin. + */ + struct TALER_DenominationHashP h_denom_pub; + + /** + * Hash of the age commitment used to sign the coin, if age restriction was + * applicable to the denomination. May be all zeroes if no age restriction + * applies. + */ + struct TALER_AgeCommitmentHashP h_age_commitment; + + /** + * true, if no @e h_age_commitment is applicable + */ + bool no_age_commitment; + + /** + * How much value is being melted? This amount includes the fees, + * so the final amount contributed to the melt is this value minus + * the fee for melting the coin. We include the fee in what is + * being signed so that we can verify a reserve's remaining total + * balance without needing to access the respective denomination key + * information each time. + */ + struct TALER_Amount amount_with_fee; + + /** + * Melt fee the exchange charged. + */ + struct TALER_Amount melt_fee; + + /** + * Index (smaller #TALER_CNC_KAPPA) which the exchange has chosen to not + * have revealed during cut and choose. + */ + uint32_t noreveal_index; + + /** + * The refresh seed that was used for the melt operation + */ + struct TALER_PublicRefreshMasterSeedP refresh_seed; + + /** + * If false, @e blinding_seed is present + */ + bool no_blinding_seed; + + /** + * If @e no_blinding_seed it false, the blinding seed that was used + * for the melt operation, in case of CS denominations. + */ + struct TALER_BlindingMasterSeedP blinding_seed; + +}; + + +/** + * Information about a /purses/$PID/deposit operation in a coin transaction history. + */ +struct TALER_EXCHANGEDB_PurseDepositListEntry +{ + + /** + * Exchange hosting the purse, NULL for this exchange. + */ + char *exchange_base_url; + + /** + * Public key of the purse. + */ + struct TALER_PurseContractPublicKeyP purse_pub; + + /** + * Contribution of the coin to the purse, including + * deposit fee. + */ + struct TALER_Amount amount; + + /** + * Depositing fee. + */ + struct TALER_Amount deposit_fee; + + /** + * Signature by the coin affirming the deposit. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** + * Hash of the age commitment used to sign the coin, if age restriction was + * applicable to the denomination. + */ + struct TALER_AgeCommitmentHashP h_age_commitment; + + /** + * Hash of the public denomination key used to sign the coin. + */ + struct TALER_DenominationHashP h_denom_pub; + + /** + * Set to true if the coin was refunded. + */ + bool refunded; + + /** + * Set to true if there was no age commitment. + */ + bool no_age_commitment; + +}; + + +/** + * @brief Specification for a purse refund operation in a coin's transaction list. + */ +struct TALER_EXCHANGEDB_PurseRefundListEntry +{ + + /** + * Public key of the purse. + */ + struct TALER_PurseContractPublicKeyP purse_pub; + + /** + * Fraction of the original deposit's value to be refunded, including + * refund fee (if any). The coin is identified by @e coin_pub. + */ + struct TALER_Amount refund_amount; + + /** + * Refund fee to be covered by the customer. + */ + struct TALER_Amount refund_fee; + +}; + + +/** + * Information about a /reserves/$RID/open operation in a coin transaction history. + */ +struct TALER_EXCHANGEDB_ReserveOpenListEntry +{ + + /** + * Signature of the reserve. + */ + struct TALER_ReserveSignatureP reserve_sig; + + /** + * Contribution of the coin to the open fee, including + * deposit fee. + */ + struct TALER_Amount coin_contribution; + + /** + * Signature by the coin affirming the open deposit. + */ + struct TALER_CoinSpendSignatureP coin_sig; + +}; + + +/** + * Information about a /purses/$PID/deposit operation. + */ +struct TALER_EXCHANGEDB_PurseDeposit +{ + + /** + * Exchange hosting the purse, NULL for this exchange. + */ + char *exchange_base_url; + + /** + * Public key of the purse. + */ + struct TALER_PurseContractPublicKeyP purse_pub; + + /** + * Contribution of the coin to the purse, including + * deposit fee. + */ + struct TALER_Amount amount; + + /** + * Depositing fee. + */ + struct TALER_Amount deposit_fee; + + /** + * Signature by the coin affirming the deposit. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** + * Public key of the coin. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Hash of the age commitment used to sign the coin, if age restriction was + * applicable to the denomination. May be all zeroes if no age restriction + * applies. + */ + struct TALER_AgeCommitmentHashP h_age_commitment; + + /** + * Set to true if @e h_age_commitment is not available. + */ + bool no_age_commitment; + +}; + +/** + * Information about a melt operation. + */ +struct TALER_EXCHANGEDB_Melt +{ + + /** + * Overall session data. + */ + struct TALER_EXCHANGEDB_Refresh session; + + /** + * Melt fee the exchange charged. + */ + struct TALER_Amount melt_fee; + +}; + + +/** + * Information about a melt operation since vDOLDPLUS of the protocol. + * This also includes the information for the reveal phase. + */ +struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS +{ + /** + * Information about the coin that is being melted. + */ + struct TALER_CoinPublicInfo coin; + + /** + * Signature over the melting operation. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** + * Refresh commitment this coin is melted into. + */ + struct TALER_RefreshCommitmentP rc; + + /** + * True if the client has successfully performed the reveal part + * of the refresh protocol, after the melt. + */ + bool is_revealed; + + /** + * @since vDOLDPLUS + * Mark if we have a v27 Refresh object. + * That is, the @a refresh_seed refers to the vDOLDPLUS master_refresh_seed + * from the original request, AND the client has provided transfer public keys, + * see below, @a transfer_public_keys + */ + bool is_v27_refresh; + + /** + * Public seed from which the refresh nonces (v27) or transfer secrets (vDOLDPLUS) + * per coin candidate were derived from. + */ + struct TALER_PublicRefreshMasterSeedP refresh_seed; + + /** + * How much value is being melted? This amount includes the fees, + * so the final amount contributed to the melt is this value minus + * the fee for melting the coin. We include the fee in what is + * being signed so that we can verify a reserve's remaining total + * balance without needing to access the respective denomination key + * information each time. + */ + struct TALER_Amount amount_with_fee; + + /** + * Number of coins to be refreshed into + */ + size_t num_coins; + + /** + * The running hash over all kappa * @a num_coins blinded coin envelopes, provided by + * the client. + */ + struct TALER_HashBlindedPlanchetsP planchets_h; + + /** + * The running hash over all chosen (noreveal_index) @a num_coins blinded coin envelopes. + */ + struct TALER_HashBlindedPlanchetsP selected_h; + + /** + * Array of @a num_coins denomination signatures of the blinded coins. + */ + struct TALER_BlindedDenominationSignature *denom_sigs; + + /** + * If @a is_v27_refresh is false, the client performed a vDOLDPLUS refresh, + * and has provided @a num_coins * kappa transfer public keys. + * This is the chosen (at index @a noreveal_index) array of @a num_coins transfer public keys. + */ + struct TALER_TransferPublicKeyP *transfer_pubs; + + /** + * Array of @a num_coins serial id's of the denominations. + * If @e coin.no_age_commitment is false, the denominations + * MUST support age restriction. + */ + uint64_t *denom_serials; + + /** + * Index (smaller #TALER_CNC_KAPPA) which the exchange chose to not + * to be revealed during cut and choose. + */ + uint32_t noreveal_index; + + /** + * True, if the client has successfully performed the reveal step + */ + bool revealed; + + /** + * If true, no @e blinding_seed is set and @e num_cs_r_values is 0. + */ + bool no_blinding_seed; + + /** + * If @e no_blinding_seed is false, the blinding seed for the nonces needed for + * blind CS signatures. + */ + struct TALER_BlindingMasterSeedP blinding_seed; + + /** + * Number of elements in @e cs_r_values. + */ + size_t num_cs_r_values; + + /** + * Array @e num_cs_r_values of public R-values for CS that were generated from the + * @e blinding_seed, a coin's index and the denomination's private key during the + * the /melt request, to ensure idempotency in case of expiration of a denomination. + * NULL if @e num_cs_r_values is 0. + */ + struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values; + + /** + * If @e num_cs_r_values is not 0, the bitvector of choices for the pairs + * in @e cs_r_values that was made by the exchange. The vector is in NBO + * and the lowest bit represents the choice for the pair at index 0 into @e cs_r_values; + */ + uint64_t cs_r_choices; + + /** + * [out]-Array of @a num_coins hashes of the public keys of the denominations + * identified by @e denom_serials. This field is set when calling + * get_refresh + */ + struct TALER_DenominationHashP *denom_pub_hashes; +}; + + +/** + * @brief Linked list of refresh information linked to a coin. + */ +struct TALER_EXCHANGEDB_LinkList +{ + /** + * Information is stored in a NULL-terminated linked list. + */ + struct TALER_EXCHANGEDB_LinkList *next; + + /** + * Denomination public key, determines the value of the coin. + */ + struct TALER_DenominationPublicKey denom_pub; + + /** + * Signature over the blinded envelope. + */ + struct TALER_BlindedDenominationSignature ev_sig; + + /** + * Exchange-provided values during the coin generation. + */ + struct TALER_ExchangeBlindingValues alg_values; + + /** + * Signature of the original coin being refreshed over the + * link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK + */ + struct TALER_CoinSpendSignatureP orig_coin_link_sig; + + /** + * Session nonce, if cipher has one. + */ + union GNUNET_CRYPTO_BlindSessionNonce nonce; + + /** + * Offset that generated this coin in the refresh + * operation. + */ + uint32_t coin_refresh_offset; + + /** + * Set to true if @e nonce was initialized. + */ + bool have_nonce; +}; + + +/** + * @brief Enumeration to classify the different types of transactions + * that can be done with a coin. + */ +enum TALER_EXCHANGEDB_TransactionType +{ + + /** + * Deposit operation. + */ + TALER_EXCHANGEDB_TT_DEPOSIT = 0, + + /** + * Melt operation. + */ + TALER_EXCHANGEDB_TT_MELT = 1, + + /** + * Refund operation. + */ + TALER_EXCHANGEDB_TT_REFUND = 2, + + /** + * Recoup-refresh operation (on the old coin, adding to the old coin's value) + */ + TALER_EXCHANGEDB_TT_RECOUP_REFRESH_RECEIVER = 3, + + /** + * Recoup operation. + */ + TALER_EXCHANGEDB_TT_RECOUP_WITHDRAW = 4, + + /** + * Recoup-refresh operation (on the new coin, eliminating its value) + */ + TALER_EXCHANGEDB_TT_RECOUP_REFRESH = 5, + + /** + * Purse deposit operation. + */ + TALER_EXCHANGEDB_TT_PURSE_DEPOSIT = 6, + + /** + * Purse deposit operation. + */ + TALER_EXCHANGEDB_TT_PURSE_REFUND = 7, + + /** + * Reserve open deposit operation. + */ + TALER_EXCHANGEDB_TT_RESERVE_OPEN = 8 + +}; + + +/** + * @brief List of transactions we performed for a particular coin. + */ +struct TALER_EXCHANGEDB_TransactionList +{ + + /** + * Next pointer in the NULL-terminated linked list. + */ + struct TALER_EXCHANGEDB_TransactionList *next; + + /** + * Type of the transaction, determines what is stored in @e details. + */ + enum TALER_EXCHANGEDB_TransactionType type; + + /** + * Serial ID of this entry in the @e type-specific table. + */ + uint64_t serial_id; + + /** + * Serial ID of this entry in the coin history table. + */ + uint64_t coin_history_id; + + /** + * Details about the transaction, depending on @e type. + */ + union + { + + /** + * Details if transaction was a deposit operation. + * (#TALER_EXCHANGEDB_TT_DEPOSIT) + */ + struct TALER_EXCHANGEDB_DepositListEntry *deposit; + + /** + * Details if transaction was a melt operation. + * (#TALER_EXCHANGEDB_TT_MELT) + */ + struct TALER_EXCHANGEDB_MeltListEntry *melt; + + /** + * Details if transaction was a refund operation. + * (#TALER_EXCHANGEDB_TT_REFUND) + */ + struct TALER_EXCHANGEDB_RefundListEntry *refund; + + /** + * Details if transaction was a recoup-refund operation where + * this coin was the OLD coin. + * (#TALER_EXCHANGEDB_TT_RECOUP_REFRESH_RECEIVER). + */ + struct TALER_EXCHANGEDB_RecoupRefreshListEntry *old_coin_recoup; + + /** + * Details if transaction was a recoup operation. + * (#TALER_EXCHANGEDB_TT_RECOUP_WITHDRAW) + */ + struct TALER_EXCHANGEDB_RecoupListEntry *recoup; + + /** + * Details if transaction was a recoup-refund operation where + * this coin was the REFRESHED coin. + * (#TALER_EXCHANGEDB_TT_RECOUP_REFRESH) + */ + struct TALER_EXCHANGEDB_RecoupRefreshListEntry *recoup_refresh; + + /** + * Coin was deposited into a purse. + * (#TALER_EXCHANGEDB_TT_PURSE_DEPOSIT) + */ + struct TALER_EXCHANGEDB_PurseDepositListEntry *purse_deposit; + + /** + * Coin was refunded upon purse expiration + * (#TALER_EXCHANGEDB_TT_PURSE_REFUND) + */ + struct TALER_EXCHANGEDB_PurseRefundListEntry *purse_refund; + + /** + * Coin was used to pay to open a reserve. + * (#TALER_EXCHANGEDB_TT_RESERVE_OPEN) + */ + struct TALER_EXCHANGEDB_ReserveOpenListEntry *reserve_open; + + } details; + +}; + + +/** + * Callback with data about a prepared wire transfer. + * + * @param cls closure + * @param rowid row identifier used to mark prepared transaction as done + * @param wire_method which wire method is this preparation data for + * @param buf transaction data that was persisted, NULL on error + * @param buf_size number of bytes in @a buf, 0 on error + */ +typedef void +(*TALER_EXCHANGEDB_WirePreparationIterator) (void *cls, + uint64_t rowid, + const char *wire_method, + const char *buf, + size_t buf_size); + +/** + * Function called to get an unfinished wire transfer + * preparation data. Fetches at most one item. + * + * @param cls closure + * @param start_row offset to query table at + * @param limit maximum number of results to return + * @param cb function to call for ONE unfinished item + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wire_prepare_data_get (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t start_row, + uint64_t limit, + TALER_EXCHANGEDB_WirePreparationIterator cb, + void *cb_cls); + +#endif diff --git a/src/include/taler/exchange-database/wire_prepare_data_insert.h b/src/include/taler/exchange-database/wire_prepare_data_insert.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/wire_prepare_data_insert.h + * @brief implementation of the wire_prepare_data_insert function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_WIRE_PREPARE_DATA_INSERT_H +#define EXCHANGE_DATABASE_WIRE_PREPARE_DATA_INSERT_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to insert wire transfer commit data into the DB. + * + * @param cls closure + * @param type type of the wire transfer (i.e. "iban") + * @param buf buffer with wire transfer preparation data + * @param buf_size number of bytes in @a buf + * @return query status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wire_prepare_data_insert (struct EXCHANGEDB_PostgresContext *ctx, + const char *type, + const char *buf, + size_t buf_size); + +#endif diff --git a/src/include/taler/exchange-database/wire_prepare_data_mark_failed.h b/src/include/taler/exchange-database/wire_prepare_data_mark_failed.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/wire_prepare_data_mark_failed.h + * @brief implementation of the wire_prepare_data_mark_failed function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_WIRE_PREPARE_DATA_MARK_FAILED_H +#define EXCHANGE_DATABASE_WIRE_PREPARE_DATA_MARK_FAILED_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * 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 + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wire_prepare_data_mark_failed (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t rowid); + +#endif diff --git a/src/include/taler/exchange-database/wire_prepare_data_mark_finished.h b/src/include/taler/exchange-database/wire_prepare_data_mark_finished.h @@ -0,0 +1,41 @@ +/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file src/include/taler/exchange-database/wire_prepare_data_mark_finished.h + * @brief implementation of the wire_prepare_data_mark_finished function for Postgres + * @author Christian Grothoff + */ +#ifndef EXCHANGE_DATABASE_WIRE_PREPARE_DATA_MARK_FINISHED_H +#define EXCHANGE_DATABASE_WIRE_PREPARE_DATA_MARK_FINISHED_H + +#include "taler/taler_util.h" +#include "taler/taler_json_lib.h" +#include "taler/taler_exchangedb_plugin.h" + + +struct EXCHANGEDB_PostgresContext; +/** + * Function called to mark wire transfer commit data as finished. + * + * @param cls closure + * @param rowid which entry to mark as finished + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +EXCHANGEDB_wire_prepare_data_mark_finished (struct EXCHANGEDB_PostgresContext *ctx, + uint64_t rowid); + +#endif